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);
}
});
}
}