2

I'm using TreeTableView , and I want to change the menu items that are associated to the context menu according to the data inside the selected row.

Suppose that I'm having a table with a structure like:


visitors


visitor 1

visitor 2

visitor 3

Chatters


chatter1

chatter2


Here in this table we can metaphorically say that we have two root nodes which are "Visitors" and "Chatters". Now, I want to have two context menus with different options. A context menu for visitors that we can say have one item which is "Invite to Chat" and another context menu that handles chatters and have different options like : "kick" , "ban" and so on. My problem is how can I achieve this scenario? Where should I use these context menus? Should I use them with cells, rows or the table?

Khafaga
  • 1,537
  • 4
  • 15
  • 24
  • what's wrong with a custom cell factory? – kleopatra Dec 15 '14 at 10:26
  • @kleopatra: and how can I use cell factory to achieve that? – Khafaga Dec 15 '14 at 12:21
  • ahh .. on re-reading I see you want the content to depend on the _selected_ data. but then, I don't understand the problem: update the contextMenu whenever selection changes, f.i. So, what _exactly is_ your problem? Best show a SSCCE that demonstrates what you want to achieve and how it doesn't work as expected – kleopatra Dec 15 '14 at 12:38
  • @kleopatra: I updated my question. Is it clear now? – Khafaga Dec 15 '14 at 14:38
  • Your description is unclear: want separate context menu per data type? Then see my first comment. Want separate context menu for selected rows? See my second comment. Anyway, SSCCE still missing ... – kleopatra Dec 15 '14 at 14:49

1 Answers1

6

Use a custom row factory and configure the context menu in the updateItem(...) method.

Assuming you have a

TreeTableView<MyDataType> treeTable = ... ;

you would do something like

treeTable.setRowFactory(ttv -> {
    ContextMenu contextMenu = new ContextMenu();
    MenuItem inviteMenuItem = new MenuItem("Invite to Chat");
    // ...
    MenuItem banMenuItem = new MenuItem("Ban");
    // ...
    TreeTableRow<MyDataType> row = new TreeTableRow<MyDataType>() {
        @Override
        public void updateItem(MyDataType item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setContextMenu(null);
            } else {
                // configure context menu with appropriate menu items, 
                // depending on value of item
                setContextMenu(contextMenu);
            }
        }
    };
    inviteMenuItem.setOnAction(evt -> {
        MyDataType item = row.getItem();
        // do something with item...
    });
    // event handlers for other menu items...
    return row ;
});

Caveat: this is not tested as you didn't provide an MCVE for me to test against, but it should give you the general idea. This will show the appropriate context menu for the row on which the user clicks (with the appropriate trigger for a context menu, e.g. right-click); this is independent of which item is selected.

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322