I have a class called Restaurant, that has an FXML file, in that class, I have a button that when pressed opens another window called tables, that also has an FXML file, I have a minimize button in tables window.
What I want is when I press the minimize button in table, a new button will be added to the Restaurant window.
But I'm getting a null exception.
Can someone help me solve this.
This is the code for my minimize button:
#FXML
public void minimiza(ActionEvent event) {
Button Tables = new Button("Mesas");
try {
Stage mesa = (Stage) ((Button) event.getSource()).getScene().getWindow();
mesa.setIconified(true);
FXMLLoader loader = new FXMLLoader();
RestauranteController controle = loader.getController();
controle.adicionaBotao(Tables);
} catch (Exception e) {
System.out.println("Not working " + e.getMessage());
}
}
It's probably better to just listen to the iconified property of the Stage from the Restaurant class. If the minimized state does not match the iconified state, you could create this property in the controller for the tables window yourself.
private int windowCount;
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Show new Window");
VBox buttonContainer = new VBox(btn);
btn.setOnAction((ActionEvent event) -> {
// create new window
windowCount++;
Label label = new Label("Window No " + windowCount);
Stage stage = new Stage();
Scene scene = new Scene(label);
stage.setScene(scene);
// button for restoring from main scene
Button restoreButton = new Button("Restore Window " + windowCount);
// restore window on button click
restoreButton.setOnAction(evt -> {
stage.setIconified(false);
});
// we rely on the minimize button of the stage here
// listen to the iconified state to add/remove button form main window
stage.iconifiedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
buttonContainer.getChildren().add(restoreButton);
} else {
buttonContainer.getChildren().remove(restoreButton);
}
});
stage.show();
});
Scene scene = new Scene(buttonContainer, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
BTW: Note that without loading a fxml, FXMLLoader will never create a controller instance, let alone without the fxml being specified. Furthermore under no circumstances would it return the same controller instance as the one used with your Restaurant window.
Related
I am creating a simple JavaFX based game and when I add a Button to my Pane and try to perform some action on it by clicking the mouse button while hovering over the button nothing happens - as if it is disabled but still visible.
private class Game extends Parent {
public Game() {
private Button newGameButton;
private Scene secondScene;
private Stage secondStage;
private Pane pane;
VBox menu = new VBox(15);
VBox highScore = new VBox(15);
menu.setTranslateX(280);
menu.setTranslateY(250);
highScore.setTranslateX(100);
highScore.setTranslateY(200);
try {
onLoad();
} catch (IOException e) {
e.printStackTrace();
}
newGameButton = new MenuButtonView("New Game");
newGameButton.setOnMouseClicked(event -> {
pane = new Pane();
secondScene = new Scene(pane, 800, 600);
secondStage = new Stage();
secondStage.setScene(secondScene);
secondStage.show();
scoreAndCrackView();
mickeyView();
});
public void mickeyView(){
private Button leftDownRedButton;
leftDownRedButton = new Button();
rightDownRedButton.setTranslateX(640);
rightDownRedButton.setTranslateY(560);
pane.getChildren().add(rightDownRedButton);
leftDownRedButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
System.out.println("Clicked");
}
});
public void scoreAndCrackView()
{
vertBox = new VBox();
vertBox.setPrefSize(800, 100); // this one was causing issue, previously: vertBox.setPrefSize(800, 600)
vertBox.getChildren().addAll(scoreLabel,crackLabel);
pane.getChildren().add(vertBox);
}
}
UPDATE
Btw I found the cause of the error - as you guys suggested something was covering my buttons and more precisely the VBox in another method which was set to the whole screen. After changing the values and minimizing prefWidth and prefHeight I can click on the buttons. Lesson for the future to set the Box only for the required area.
I have designed a simple form with a TextField and a Button.
When the stage is created, with the scene containing the form, the TextField must be preloaded with a character. The problem is that, when the form shows up, the character is selected, as shown in the image.
I tried textfield.deselect() or textfield.positionCaret(1) (or both) but nothing has changed.
I don't want to remove the focus on the textfield, but deselect the text and move the caret at the end (so that if the user write something, the first character will not be overwritten).
This is the code I wrote:
try {
Stage primaryStage = new Stage();
FXMLLoader loader = new FXMLLoader();
Pane root = loader.load(getClass().getResource("/resources/view/quick-search.fxml").openStream());
QuickSearchCtrl quickSearchCtrl = (QuickSearchCtrl) loader.getController();
quickSearchCtrl.text_tf.setText(text);
quickSearchCtrl.text_tf.deselect();
primaryStage.setTitle("");
primaryStage.setScene(new Scene(root, 230, 54));
primaryStage.show();
primaryStage.setResizable(false);
} catch (IOException e) {
e.printStackTrace();
}
This is an evil crutch, but this work.
quickSearchCtrl.text_tf.setText(text);
deselect(quickSearchCtrl.text_tf);
private void deselect(TextField textField) {
Platform.runLater(() -> {
if (textField.getText().length() > 0 &&
textField.selectionProperty().get().getEnd() == 0) {
deselect(textField);
}else{
textField.selectEnd();
textField.deselect();
}
});
}
So, I have two .fxml files, the other one working as main and the other one as basically window that pops up.
#FXML private void handleSelection() throws Error {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StudentChoose.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
sBox.setItems(FXCollections.observableArrayList("New Document", "Open ", "Save", "Save as"));
}
This is what I have. I have stated the sBox above with
#FXML private ChoiceBox sBox;
Everything works PERFECTLY when the choicebox/combobox is on the main stage, but when it is on the other stage - it doesn't. I have a .fxml file for this another stage with the content, id is set as 'sBox' for the choicebox - but it doesn't work. Instead it returns me a java.lang.NullPointerException on the line where I call to add items to it. What could be the problem?
We are using more than one stage(window) in JavaFX for a desktop standalone application. So when we drag or move any of the stage(window) form one point to another and clicking a certain button to navigate to the other page means the new stage is coming to center again(default position). Is there any methods to set the future stage(future windows) also in the previous stage location or point(previous windows). Please help.
You can control stage location before showing it. Just remember last stage coordinates and create new one in the same point:
public class FXStages extends Application {
private int counter = 0;
#Override
public void start(final Stage stage) {
Button btn = new Button();
btn.setText("Reopen");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
stage.close();
Stage newStage = new Stage();
newStage.setX(stage.getX());
newStage.setY(stage.getY());
start(newStage);
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
stage.setTitle("Stage " + counter++);
stage.setScene(scene);
stage.show();
}
}
I am new to JavaFX. I have a window loaded with vertical split pane. Here left side of the split page I have couple of buttons. On Each button click I need to load separate fxml on the right side of the split pane. So here I paste screen shot to be clear.
Here as of now I am opening in separate stage, separate scene when search button is hit. Now I need to load Searcher in the right side of baselayout window. Here is some code which loads baseLayout.
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Base Layout");
BaseController.setMlTool(this);
FXMLLoader loader = new FXMLLoader(MLTool.class.getResource("view/Base.fxml"));
baseLayout = (AnchorPane) loader.load();
Scene scene = new Scene(baseLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
Here is some code which loads Searcher on button click.
#FXML
private void initialize(){
System.out.println("Testing");
}
#FXML
private void handleSearchButton(){
System.out.println("Handle Button Called");
Stage search = new Stage();
FXMLLoader loader = new FXMLLoader(MLTool.class.getResource("view/Searcher.fxml"));
search.setTitle("Searcher");
try {
AnchorPane searcherPage = (AnchorPane) loader.load();
Scene scene = new Scene(searcherPage);
search.setScene(scene);
search.show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Here how do I load Searcher in BaseLayout's Rightside of split pane.
Hope my question is clear. Thanks for your help in anticipation.
You can take pane on right side and then load fxml as child node of that pane. Stage is same for all time and you can load fxml in pane.
ex: MainWindow.fxml is perent window. You can load in stage.
Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
Now in MainWindow.fxml you have split pane. Put anchorPan on right side where you want to load fxml on button click. Then add fxml as child in anchorpane.
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(fxml));
Pane cmdPane = (Pane) fxmlLoader.load();
try {
anchCmdController.getChildren().clear();
anchCmdController.getChildren().add(cmdPane);
fadeIn.playFromStart();
} catch (Exception e) {
e.printStackTrace();
}
try to listen to the button click, once its clicked use 'FXMLLoader.load' to load based on the root elenment, typecast it say panel and assign tot he content of the right side.
In Your handler method try with this:
first declare anchorpane. In fxml right pane put anchorpane with anchCmdController name.
#FXML
private AnchorPane anchCmdController;
then update your handleSearchButton event.
#FXML
private void handleSearchButton() throws IOException {
System.out.println("Handle Button Called");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("view/Searcher.fxml"));
Pane cmdPane = (Pane) fxmlLoader.load();
try {
/* NEED TO DECLARE ANCHOR PANE" */
anchCmdController.getChildren().clear();
anchCmdController.getChildren().add(cmdPane);
} catch (Exception e) {
e.printStackTrace();
}
}