Hi,

I'm facing a problem: I've to make an undo/redo using Command's design pattern.

I've succed to make one, but when I want to use my undo/redo btn in an other view, it gives me an NullPointerException.

Does anyone can help me? Here's the code of the 2 view's

First one with btns:

package view;

import Commands.BoardTitleCommand;
import Commands.Command;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import main.Start;

import static Commands.Command.pivot;


public class TrelloView extends VBox {

    //création stack commandes




    public static final int SCREENWIDTH = 1280;
    public static final int SCREENHEIGHT = 720;
    public static final Font FONT = new Font("Helvetica", 18);

    private Stage gameStage;
    private Scene gameScene;

    private BoardView boardView;
    private ColumnView columnView;
    public EditableLabel editableLabel;
    private Button btnAddColumn;


    private MenuBar menuBar;
    private Menu menuFichier;
    private Menu menuEdition;

    private MenuItem menuItemAddColumn;
    private MenuItem menuItemQuit;
    private MenuItem menuItemUndo;
    private MenuItem menuItemRedo;


    public TrelloView() {
        initNodes();
        initWindow();
        addActions();
        editableLabel.getLabel().textProperty().bindBidirectional(boardView.getBoardViewModel().boardViewTitleProperty());
    }

    // Code qui génère l'écran principal
    private void initWindow(){
        gameStage = new Stage();
        gameScene = new Scene(this, SCREENWIDTH, SCREENHEIGHT);
        gameStage.setTitle("Trello");
        gameStage.setResizable(false);
        gameStage.setScene(gameScene);
        gameStage.show();
    }

    // Code qui génère les nodes
    private void initNodes(){
        boardView = new BoardView();

        editableLabel = new EditableLabel("My Board");
        btnAddColumn = new Button("Add Column");
        btnAddColumn.setFont(FONT);

        menuBar=new MenuBar(); // bar menu

        menuFichier=new Menu("Files");// élements bar menu
        menuEdition=new Menu("Edition");

        //éléments éléments abr menu
        menuItemAddColumn=new MenuItem("Add column");
        menuItemQuit = new MenuItem("Quit application");


        menuItemUndo=new MenuItem("Undo (CTR + Z)");
        menuItemRedo=new MenuItem("Redo (CTR + Y)");

        menuItemUndo.disableProperty().set(false);
        menuItemRedo.disableProperty().set(false);

        //ajoute élément dans élément menu
        menuFichier.getItems().addAll(menuItemAddColumn,menuItemQuit);

        menuEdition.getItems().addAll(menuItemUndo,menuItemRedo);

        //ajoute élements menus dans menus
        menuBar.getMenus().addAll(menuFichier,menuEdition);

        this.getChildren().addAll(menuBar,editableLabel, boardView, btnAddColumn);
    }

    private void addActions(){
        this.btnAddColumn.setOnAction(e -> this.boardView.getBoardViewModel().addColumn());
        this.menuItemAddColumn.setOnAction(e -> this.boardView.getBoardViewModel().addColumn());

        this.menuItemQuit.setOnAction(e -> gameStage.close());


        //UNDO REDO TITLE BOARD
        this.menuItemUndo.setOnAction((e) ->{
            Command.listCommand.get(pivot-1).undo();

        } );

        this.menuItemRedo.setOnAction((e) ->{
            Command.listCommand.get(pivot+1).redo();

        } );
        this.editableLabel.getLabel().setOnMouseClicked((e) -> {
            if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 2) {

                editableLabel.showTextFieldHideLabel();
            }
        });

        this.editableLabel.getTextField().setOnKeyPressed((e) -> {
            if (e.getCode().equals(KeyCode.ENTER)) {
                Start.trelloView.getMenuItemUndo().disableProperty().set(false); // à mettre dans chaque actions
                Start.trelloView.getMenuItemRedo().disableProperty().set(false);

                editableLabel.showLabelHideTextField();
                BoardTitleCommand command = new BoardTitleCommand(editableLabel.getLabel().getText());
                Command.listCommand.add(command);
                pivot++;
                System.out.println(Command.listCommand);
            }
        });

    }

    //GETTERS & SETTERS UNDO REDO


    public EditableLabel getEditableLabel() {
        return editableLabel;
    }

    public MenuItem getMenuItemUndo() {
        return menuItemUndo;
    }

    public void setMenuItemUndo(MenuItem menuItemUndo) {
        this.menuItemUndo = menuItemUndo;
    }

    public MenuItem getMenuItemRedo() {
        return menuItemRedo;
    }

    public void setMenuItemRedo(MenuItem menuItemRedo) {
        this.menuItemRedo = menuItemRedo;
    }

    public BoardView getBoardView() {
        return boardView;
    }
}

Second one where I should use them also:

package view;

import Commands.BoardTitleCommand;
import Commands.ColumnTitleCommand;
import Commands.Command;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import main.Start;
import model.CardModel;
import model.ColumnModel;
import mvvm.ColumnViewModel;
import view.TrelloView;

import static Commands.Command.pivot;

public class ColumnView extends VBox {

    private TrelloView trelloView;
    private ColumnViewModel columnViewModel;
    private ListView<CardModel> listViewCard;
    private HBox hBox;
    public static EditableLabel editableLabel;
    private ContextMenu contextMenu;
    private MenuItem menuItemRemove;
    private Button btnLeft, btnRight, btnAddCard;


    public ColumnView(ColumnViewModel columnViewModel){
        this.columnViewModel = columnViewModel;
        this.initNodes();
        this.designListViewCardModel();
        this.addBindings();
        this.addActions();
        this.initCommand();

    }

    ColumnView(ColumnModel columnModel) {
        this(new ColumnViewModel(columnModel));
    }

    private void initCommand(){
        ColumnTitleCommand columnTitleCommand=new ColumnTitleCommand(columnViewModel.columnViewTitleProperty().getValue());
        Command.listCommand.add(columnTitleCommand);
    }
    private void initNodes(){
        listViewCard = new ListView();
        listViewCard.setPrefWidth(200.0D);
        contextMenu = new ContextMenu();
        menuItemRemove = new MenuItem("Remove Column");
        contextMenu.getItems().add(menuItemRemove);
        editableLabel = new EditableLabel("Column");
        editableLabel.getLabel().setContextMenu(contextMenu);
        btnLeft = new Button("-");
        btnLeft.setFont(TrelloView.FONT);
        btnRight = new Button("-");
        btnRight.setFont(TrelloView.FONT);
        hBox = new HBox();
        hBox.getChildren().addAll(btnLeft, editableLabel, btnRight);
        btnAddCard = new Button("Add card");
        btnAddCard.setFont(TrelloView.FONT);
        getChildren().addAll(hBox, listViewCard, btnAddCard);
        setAlignment(Pos.CENTER);
    }

    private void designListViewCardModel() {
        this.listViewCard.setCellFactory((view) -> {
            return new ListCell<CardModel>() {
                protected void updateItem(CardModel cardModel, boolean b) {
                    super.updateItem(cardModel, b);
                    CardView cardView = null;
                    if (cardModel != null) {
                        cardView = new CardView(cardModel);
                    }
                    this.setGraphic(cardView);
                }
            };
        });
    }

    private void addBindings() {
        editableLabel.getLabel().textProperty().bindBidirectional(columnViewModel.columnViewTitleProperty());
        listViewCard.itemsProperty().bind(columnViewModel.listPropertyCardModelProperty());
        btnLeft.visibleProperty().bind(columnViewModel.buttonLeftEnabledProperty());
        btnRight.visibleProperty().bind(columnViewModel.buttonRightEnabledProperty());
    }

    private void addActions() {
        btnLeft.setOnAction(e -> columnViewModel.moveLeft());
        btnRight.setOnAction(e -> columnViewModel.moveRight());
        btnAddCard.setOnAction(e -> columnViewModel.addCard());
        menuItemRemove.setOnAction(e -> columnViewModel.removeColumn());

        //Command
        //UNDO REDO TITLE COLUMN
        Start.trelloView.getMenuItemUndo().setOnAction((e) ->{
            Command.listCommand.get(pivot-1).undo();

        } );

        Start.trelloView.getMenuItemRedo().setOnAction((e) ->{
            Command.listCommand.get(pivot+1).redo();

        } );
        this.editableLabel.getLabel().setOnMouseClicked((e) -> {
            if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 2) {

                editableLabel.showTextFieldHideLabel();
            }
        });

        this.editableLabel.getTextField().setOnKeyPressed((e) -> {
            if (e.getCode().equals(KeyCode.ENTER)) {
                Start.trelloView.getMenuItemUndo().disableProperty().set(false); // à mettre dans chaque actions
                Start.trelloView.getMenuItemRedo().disableProperty().set(false);

                editableLabel.showLabelHideTextField();
                ColumnTitleCommand command = new ColumnTitleCommand(editableLabel.getLabel().getText());
                Command.listCommand.add(command);
                pivot++;
                System.out.println(Command.listCommand);
            }
        });
    }
}

Which line and variable does the NPE refer to?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.