Tomasz Mularczyk
Tomasz Mularczyk

Reputation: 36179

Error when getting ContextMenu and adding new item

So I have controller class with this object:

 @FXML
    private TextArea textArea;  

then Im trying to add new MenuItem to its standard Items(that is "copy" and "select all")

 @Override
public void initialize(URL location, ResourceBundle resources) {
        ContextMenu contextMenu = textArea.getContextMenu();
     X  contextMenu.getItems().add(new MenuItem("chuj"));
        textArea.setContextMenu(contextMenu);

and line marked with X gets me null pointer exception. Why? Interesting part is that I can get contextMenu from textArea and set it back to its place with no error. I just cant add something new.

Upvotes: 2

Views: 1155

Answers (1)

James_D
James_D

Reputation: 209418

Unfortunately, there's no current way to access the default context menu, which is private API in the TextInputControl. This is a known bug.

If you set a context menu, it will remove the default one. You can recreate most of the functionality in the default context menu as these simply map to public methods defined in TextArea. The exceptions are "undo" and "redo".

So you can do something like this:

private List<MenuItem> createDefaultMenuItems(TextInputControl t) {
    MenuItem cut = new MenuItem("Cut");
    cut.setOnAction(e -> t.cut());
    MenuItem copy = new MenuItem("Copy");
    copy.setOnAction(e -> t.copy());
    MenuItem paste = new MenuItem("Paste");
    paste.setOnAction(e -> t.paste());
    MenuItem delete = new MenuItem("Delete");
    delete.setOnAction(e -> t.deleteText(t.getSelection()));
    MenuItem selectAll = new MenuItem("Select All");
    selectAll.setOnAction(e -> t.selectAll());

    BooleanBinding emptySelection = Bindings.createBooleanBinding(() ->
        t.getSelection().getLength() == 0,
        t.selectionProperty());

    cut.disableProperty().bind(emptySelection);
    copy.disableProperty().bind(emptySelection);
    delete.disableProperty().bind(emptySelection);

    return Arrays.asList(cut, copy, paste, delete, new SeparatorMenuItem(), selectAll);
}

Now you can do

public void initialize() {
    ContextMenu contextMenu = new ContextMenu();
    contextMenu.getItems().addAll(createDefaultMenuItems(textArea));
    contextMenu.getItems().add(new MenuItem("chuj"));
    textArea.setContextMenu(contextMenu);
}

It's a bit of a hack (replicating functionality, etc) and you lose the undo/redo (which is a real issue); but it's the best I can suggest until they fix the bug. I suggest you vote for it...

Upvotes: 4

Related Questions