javafx/ fxml - Switching Screens/ add a new Tab in controller - javafx

Firstly, sorry for my English. I hope, you unterstand it.
Last Month I started developing a little programm with FXML/ JavaFX.
I have two screens, and I'm switching between them. This is not the problem.
The problem is: On one Screen i have a listview, where i can choose an item. When i have chosen an item, i want to open a new tab on the other screen with the content of the item. Therefore, i have to click on a button.
When i have chosen an item, i can print out the selected item, but how do I open a new tab on the other screen. Both Screens a two different FXML and are activited from the controller. How can I add a Tab, although loading fxml?
public class Controller{
#FXML
private ListView<String> lv;
#FXML
private Button check;
#FXML
public void projectview (Event e3) throws Exception{
Stage stage = null;
Parent root = null;
if(e3.getSource()==check){
//Check is the declaration for the Button on the screen with the listview
String projectview= lv.getSelectionModel().getSelectedItem();
stage = (Stage) check.getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("FXML1.fxml"));
//Here I want to add a tab in FXML1.fxml
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
}
If something is missing or not clear, please ask. I read other similar questions, but i don't know, what to do.
Thanks for help

Related

Javafx Popup can't get focus if other application gains focus

I use a JavaFX Popup in my application to change the Shipping Address of a customer. That often requires copy pasting the Address from the web browser. If I click on the Popup after the application lost focus it will not regain focus. I first need to click the parent window behind the popup and then click the Popup again to be able to interact with it.
Is there any way to solve that problem, besides using an undecorated stage instead of a Popup?
EDIT:
Here I made a minimal example:
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
Scene scene = new Scene(new VBox(), 600, 600);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
Popup popup = new Popup();
Button btn = new Button("This is a very nice button!");
btn.setOnAction(actionEvent -> System.out.println("button clicked"));
TextField textField = new TextField();
textField.setOnMouseClicked(mouseEvent -> System.out.println("textField clicked"));
VBox popupVBox = new VBox(btn, textField);
popupVBox.setStyle("-fx-background-color: white");
popupVBox.setPadding(new Insets(10));
popup.getContent().add(popupVBox);
popup.show(scene.getWindow());
}
public static void main(String[] args) {
launch();
}
}
If you click outside of the application (for example the web browser, to copy some value) then you can not enter Text into the TextField anymore. The button action listener and even the TextField mouse Listener still work and output "button clicked" and "textField clicked" but the blue halo around them does not apppear and you can not enter (or paste) text into the TextField. After you click somewhere on the main Stage of the application it works again.
I tried adding textField.requestFocus();
to the mouse Listener of the textfield but that does not do anything.
EDIT 2 after the comment from kleopatra:
I tried adding the following code:
popupVBox.setOnMouseEntered(mouseEvent -> {
popup.getOwnerWindow().requestFocus();
parentVBox.toFront(); //This is created above and passed to the new Scene instead of diectly passing new VBox() as in the code snippet posted above
});
With that code added, popup and its children seem to have focus if the mouse is hoverd over it after an other application had focus, i.e. if clicked with the mouse the blue border appears around the button and textField, and if there is any text in the textField I can move the cursor with the mouse and select the text with the mouse, buy any keyboard inputs are ignored. Actually they are executed in the other application which had focus before. If I ctrl+c in Intellij and try to ctrl+v into the textfield it will be pasted to the Intellij editor. Also the arrow keys move the cursor in the intellij window instead of the textField.
The only way to be able to type anything in the TextField is to click the parent window first.
Also
textField.setOnMouseClicked(mouseEvent -> {
textField.requestFocus();
});
does not do anything
not an answer, just to clarify the comment (will delete if seen by OP :)
public class PopupFocus extends Application {
#Override
public void start(Stage stage) throws IOException {
Scene scene = new Scene(new VBox(), 300, 300);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.setX(10);
stage.show();
Popup popup = new Popup();
Button btn = new Button("This is a very nice button!");
btn.setOnAction(actionEvent -> System.out.println("button clicked"));
TextField textField = new TextField();
textField.setOnMouseClicked(mouseEvent -> {
System.out.println("textField clicked");
stage.toFront();
});
VBox popupVBox = new VBox(btn, textField);
popupVBox.setStyle("-fx-background-color: white");
popupVBox.setPadding(new Insets(10));
popup.getContent().add(popupVBox);
// original
popup.show(scene.getWindow());
}
public static void main(String[] args) {
launch();
}
}

JavaFX primaryStage binding with TextField

In JavaFx I'm currently trying to change the height of
primaryStage via binding.
primaryStage.setScene(scene);
primaryStage.setHeight(400.0);
primaryStage.widthProperty().bindBidirectional(textField.textProperty());
It's just a homework problem, not meaningful.
Unfortunately primaryStage is readOnlyDoubleProperty. May I change this settings to gain write-permissions?
I know, there is the possibility to change the window size via EventHandler, but I would like to change the window size on the fly through the TextField with bindings.
So any newly entered number enlarges the window.
Any ideas?
It's definitely possible and I hope there is a better way and no one should ever use this code ever but this is what I managed to make work
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
//Allows for only numeric input
textField.setTextFormatter(new TextFormatter<>(change -> {
if (change.getText().matches("[0-9]*"))
return change;
else
return null;
}));
primaryStage.setScene(new Scene(textField));
primaryStage.setHeight(200.0);
//Allows Program to start without error
primaryStage.setMaxWidth(200);
//Binds min and max to ensure stage width change due to only 1 possible size
primaryStage.minWidthProperty().bind(primaryStage.maxWidthProperty());
//Bind textfield to width
textField.textProperty().bindBidirectional(primaryStage.maxWidthProperty(), new NumberStringConverter());
primaryStage.show();
}
}

Can JavaFX ComboBox fire events when selection not changed?

I'm new to JavaFX. Unlike Swing, JavaFX's combo box's action event seems to be fired when the selection actually changed. In Swing, you can add an ActionListener on a JComboBox and it will fire an event whenever you make a selction (by clicking on one of the choices in the combo box), regardless of if the selected value actually changed. Can we achieve the same behavior in JavaFX? Some code below. What I want is to select "Hello" and have it printed, and select "Hello" again and have it printed again.
public class ComboBoxSelection extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
VBox layout = new VBox();
ComboBox<String> comboBox = new ComboBox<>();
comboBox.getItems().addAll("Hello", "World");
comboBox.setOnAction(event -> System.out.println("Selected " + comboBox.getValue()));
layout.getChildren().addAll(comboBox);
Scene scene = new Scene(layout);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I noticed a thread here: ComboBox SAME item selected action listener. This almost gives me what I want, except this fires when the selection cancels (press Esc) as well. Is there any other solution? Thanks in advance.

How can i close my Scene by clicking on button in javafx

I want to close scene(which is currently opened),
i want to do like Cancel or close button operation
written the statement
x.show();
in another class
and want to close x means
x.close();
in another class
#FXML
private void closeScene(ActionEvent event){
final Node source = (Node) event.getSource();
final Stage stage = (Stage) source.getScene().getWindow();
stage.close();
}

JavaFX FXML menuItem action

I'm trying to set a variable value when a MenuItem i chosen in a MenuButton object.
I've tried to search for this but I've came up empty handed.
Here's the code to set the MenuItems:
private ObservableList<MenuItem> templateMenuItems = FXCollections.observableArrayList();
#FXML private MenuButton menu = new MenuButton();
#FXML
protected void getTemplates() throws IOException {
CaspReturn tls = this.socket.runCmd(new Tls(""));
String tlsList = tls.getResponse();
String[] tlsListSplitt = tlsList.split("\\n");
for (int i = 0; i < tlsListSplitt.length; i++) {
String[] tlsLine = tlsListSplitt[i].split("\"");
this.templateMenuItems.add(new MenuItem(tlsLine[1]));
}
this.menu.getItems().setAll(this.templateMenuItems);
}
I'm not sure how to write the code to get the text from a menuItem or which field in scenebuilder the method should be in.
It's not clear what your asking, but I'll assume that you want to know the text of a menu item when it is clicked. To do that, you need to add an event handler onto the menu item. The following is clipped from the JavaDoc for ContextMenu:
MenuItem item1 = new MenuItem("About");
item1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
System.out.println("About");
}
});
You can get the event source, cast in to MenuItem and then get the text from that.
There's a real problem with your code the way it's written, though. You have calls to an external database in getTemplates, and as it's implemented as an #FXML element that almost guarantees that it'll be run on the FXAT, which is really, really bad.
I'd refactor that so that the database access is in a Task, and then the MenuItem creation is a handler for the onSucceeded event of the Task. Then you need instantiate a ContextMenu and install the MenuItem's on it in that event handler.
The getTemplates() method should be called as the onAction event for the button.

Resources