how to have a running program add tab panes javafx - javafx

Hello this is my question, In order to let a user add tabs with a new button would i need to create a whole new border panes and tab panes for this to work?

No you don't need if you have already created tabPane previously.
Button btn = new Button("add new tab");
btn.setOnAction( (e) -> {
tabPane.getTabs.add(new Tab("new tab"), new VBox(new Label(Content)) );
});

Related

How to change contextMenu default mouse button?

I have a contextMenu and I added it to a button. I want the contextMenu to be displayed when I left-click(PRIMARY) on the button. How can I do this? Because by default just right-clicking does this.
I tried this way but it did not work
Button sortBy = new Button();
ContextMenu sortByMenu = new ContextMenu();
sortByMenu.addEventFilter(MouseEvent.MOUSE_PRESSED, ev -> {
if (ev.getButton() == MouseButton.PRIMARY) {
//does not do anything
}
});
sortBy.setContextMenu(sortByMenu);
MenuButton
MenuButton is a button which, when clicked or pressed, will show a ContextMenu.
Example code from the javadoc:
MenuButton m = new MenuButton(
"Eats"
);
m.getItems().addAll(
new MenuItem("Burger"),
new MenuItem("Hot Dog")
);
ChoiceBox
You could also consider a ChoiceBox, depending on what you are trying to do.
The ChoiceBox is used for presenting the user with a relatively small set of predefined choices from which they may choose.
ChoiceBox<String> cb = new ChoiceBox<>();
cb.getItems().addAll(
"item1",
"item2",
"item3"
);
To select a sortBy sorting field from a list of choices, a ChoiceBox would probably be a good fit.

JavaFx add context menu from controller

I am trying my way through JavaFX and still have many - probably silly - beginner questions.
My problem of the day is the following:
I am creating, in Scene builder and Controller, a FlowPane to which I want to add a right-click option, that opens a Context Menu.
Through the scene builder I have added the function OnContextMenuRequested and defined it in the Controller.
To check, I have added a print commend and a Dialog Box to the function, which work well.
Yet, the Context Menu does not work..
Anybody could help and tell me what am I missing???
Thanks in advance...
public void contextMenu(ContextMenuEvent contextMenuEvent) {
// working fine ..
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText("Look");
alert.setContentText("Message");
alert.showAndWait();
// working fine
System.out.println("Hello");
// Context Menu ......... not working
ContextMenu contextMenu = new ContextMenu();
MenuItem quit = new MenuItem("quit");
MenuItem hello = new MenuItem("hello");
contextMenu.getItems().addAll(quit, hello);
contextMenu.setX(10.0);
contextMenu.setY(10.0);
contextMenu.show();
????.setContextMenu(????)
}
Unless you have a control, you need to show the ContextMenu "manually" using one of the methods defined in ContextMenu:
// contextMenu.setX(10.0);
// contextMenu.setY(10.0);
contextMenu.show((Node) contextMenuEvent.getSource(), contextMenuEvent.getScreenX(), contextMenuEvent.getScreenY());

javafx TitledPane click event only for Title

Is there any way I can have an event that only triggers if I click the Title of a TitledPane?
I have several Nodes in a Graph Editor and currently they are draggable.
But I want them only to drag when i drag the Title not if I click anywhere on the pane.
the mouseClick event seems not to work for me.
Does anyone have suggestions?
Don't set the text on the titled pane, but instead create a label and set it as the graphic for the titled pane. Then you can register a mouse handler with the label:
private TitledPane createClickableTitledPane(String text) {
Label label = new Label(text);
label.setOnMouseClicked(e -> System.out.println("Click on "+text));
TitledPane titledPane = new TitledPane();
titledPane.setGraphic(label);
return titledPane ;
}
StackPane titleRegion = (StackPane) titledPane.lookup(".title");
titleRegion.setOnMouseClicked(System.out::println);
EDIT:
Sometimes titledPane.lookup(".title") returns null which means CSS is not applied to the node. To resolve this issue, you need to use applyCss() and layout() on the pane that contains the TitledPane.
See:
JavaFX TitledPane lookup(.title) returns null

JavaFx TabPane Automatic Closing

I have a MenuItem "load" that opens four tabs in the GUI. However, when I click "load" again. Instead of closing the previous tabs opened. It simply appends after it. How can I close them automatically?
load.setOnAction(e -> {
cb.loadBinary();
pb.loadPersonBinary();
tb.loadTextbookBinary();
Tab tabS = new Tab();
tabS.setText("Student");
studentScene = new SceneStudent(this, pb);
tabS.setContent(studentScene.getPane());
root.setCenter(tabPane);
Tab tabF = new Tab();
tabF.setText("Faculty");
facultyScene = new SceneFaculty(this, pb);
tabF.setContent(facultyScene.getPane());
root.setCenter(tabPane);
Tab tab = new Tab();
tab.setText("Text Book");
textScene = new SceneTextBook(this, tb);
tab.setContent(textScene.getPane());
root.setCenter(tabPane);
Tab tabC = new Tab();
tabC.setText("Course");
courseScene = new SceneCourse(this, cb);
tabC.setContent(courseScene.getPane());
tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS);
MenuItem buttonClicked = (MenuItem) e.getTarget();
if(buttonClicked == load){
tabPane.getTabs().removeAll();
}
tabPane.getTabs().addAll(tabS, tabF, tab, tabC);
root.setCenter(tabPane);
});
Instead of checking if the MenuItem that was clicked was your "load" item, removing, then adding, just do: tabPane.getTabs().setAll(tabS, tabF, tab, tabC);
See documentation here.

ContextMenu and programmatically selecting an item

There does not seem to be API for programmatically "selecting" ContextMenu items? By selecting I mean the equivalent of tapping up and down keys (or hovering the mouse over an item). I really only need to select the first item, when a ContextMenu is shown. I attempted to fire a down keyevent upon showing the menu, but nothing happened.. perhaps I constructed the event wrongly.
To get this working, we could use some private API. ContextMenu skin (ContextMenuSkin) uses a ContextMenuContent object, as a container with all the items.
We just need to request the focus for the first of these items.
But for this we could just use some lookups to find the first menu-item CSS selector. This has to be done after the stage has been shown.
This example will show a context menu with focus on the first item:
#Override
public void start(Stage primaryStage) {
MenuItem cmItem1 = new MenuItem("Item 1");
cmItem1.setOnAction(e->System.out.println("Item 1"));
MenuItem cmItem2 = new MenuItem("Item 2");
cmItem2.setOnAction(e->System.out.println("Item 2"));
final ContextMenu cm = new ContextMenu(cmItem1,cmItem2);
Scene scene = new Scene(new StackPane(), 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
scene.setOnMouseClicked(t -> {
if(t.getButton()==MouseButton.SECONDARY){
cm.show(scene.getWindow(),t.getScreenX(),t.getScreenY());
// Request focus on first item
cm.getSkin().getNode().lookup(".menu-item").requestFocus();
}
});
}
For me solution provided in accepted answer didn't work correctly as item was only highlighted but not really selected (<Enter> was not accepting a value).
Instead of that constructing a proper KeyEvent did the work except a bug that only after first letter popup was working correctly.
Finally I combined both and got what I'd wanted:
// 'this' is related to parent component of ContextMenu
popup.show(this, x, y);
// Request focus on first item (sort of hack)
popup.getSkin().getNode().lookup(".menu-item").requestFocus();
this.fireEvent(new KeyEvent(
KeyEvent.KEY_PRESSED, "", "",
KeyCode.DOWN, false, false, false, false));

Resources