As you can see I have two buttons right now (button and button2) The problem is that they are in the center of JavaFX window (in the same place). So I don't see one of them because 2nd is covering 1st. What is wrong? The main objective of this simple app is to have two buttons on main screen. And after clicking into one of buttons, I expect to open new window with some other content.
public class Run extends Application {
#Override
public void start(final Stage primaryStage) {
Button button = new Button();
button.setText("Navigation");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Label secondLabel = new Label("Select from list");
StackPane secondaryLayout = new StackPane();
secondaryLayout.getChildren().add(secondLabel);
Scene secondScene = new Scene(secondaryLayout, 500, 400);
// New window (Stage)
Stage newWindow = new Stage();
newWindow.setTitle("Adding products");
newWindow.setScene(secondScene);
// Specifies the modality for new window.
newWindow.initModality(Modality.WINDOW_MODAL);
// Specifies the owner Window (parent) for new window
newWindow.initOwner(primaryStage);
// Set position of second window, related to primary window.
newWindow.setX(primaryStage.getX() + 200);
newWindow.setY(primaryStage.getY() + 100);
newWindow.show();
}
});
Button button2 = new Button();
button2.setText("X");
button2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Label secondLabel = new Label("Select from list");
StackPane secondaryLayout = new StackPane();
secondaryLayout.getChildren().add(secondLabel);
Scene secondScene = new Scene(secondaryLayout, 500, 400);
// New window (Stage)
Stage newWindow = new Stage();
newWindow.setTitle("Adding products");
newWindow.setScene(secondScene);
// Specifies the modality for new window.
newWindow.initModality(Modality.WINDOW_MODAL);
// Specifies the owner Window (parent) for new window
newWindow.initOwner(primaryStage);
// Set position of second window, related to primary window.
newWindow.setX(primaryStage.getX() + 200);
newWindow.setY(primaryStage.getY() + 100);
newWindow.show();
}
});
StackPane root = new StackPane();
root.getChildren().add(button);
root.getChildren().add(button2);
Scene scene = new Scene(root, 650, 450);
primaryStage.setTitle("Shopping Buddy");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
I'm having a problem with creating a method and calling it when a button is clicked.
What I want to do is when a button is clicked the scene changes to a new one. I have already achieved this but I came across a problem when I need to create more of such actions.
Here is my code:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane borderPane = new BorderPane();
Button dugmeStart = new Button("Start");
dugmeStart.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
BorderPane borderPane2 = new BorderPane();
Label prvo_pritanje = new Label("Prvo pitanje: Kada je poceo Prvi svetski rat?");
prvo_pritanje.setStyle("-fx-font-weight: bold;");
Button dalje1 = new Button("Dalje");
//Navigacija
HBox navigacija_goranj = new HBox();
navigacija_goranj.getChildren().add(prvo_pritanje);
navigacija_goranj.setAlignment(Pos.CENTER);
navigacija_goranj.setPadding(new Insets(15,12, 15, 12));
HBox navigacija_donja = new HBox();
navigacija_donja.getChildren().add(dalje1);
navigacija_donja.setPadding(new Insets(15,12, 15, 12));
navigacija_donja.setAlignment(Pos.CENTER);
//Odgovori
HBox odgovori = new HBox();
ToggleGroup pitanja1 = new ToggleGroup();
RadioButton prvo_pitanje = new RadioButton("1914");
prvo_pitanje.setToggleGroup(pitanja1);
RadioButton drugo_pitanje = new RadioButton("1918");
drugo_pitanje.setToggleGroup(pitanja1);
RadioButton trece_pitanje = new RadioButton("1910");
trece_pitanje.setToggleGroup(pitanja1);
odgovori.getChildren().addAll(prvo_pitanje, drugo_pitanje, trece_pitanje);
odgovori.setSpacing(15);
odgovori.setAlignment(Pos.CENTER);
//Dodavanje u BorderPane
borderPane2.setBottom(navigacija_donja);
borderPane2.setTop(navigacija_goranj);
borderPane2.setCenter(odgovori);
Scene scena2 = new Scene(borderPane2, 300, 300);
primaryStage.setScene(scena2);
}
});
Label dobrodoslica = new Label("Pocetak kviza");
dobrodoslica.setStyle("-fx-font-weight: bold;");
//Definisanje Hbox-a sa dugmetom "Start"
HBox navigacija1 = new HBox();
navigacija1.setPadding(new Insets(15, 12, 15, 12));
navigacija1.getChildren().add(dugmeStart);
navigacija1.setAlignment(Pos.CENTER);
borderPane.setBottom(navigacija1);
borderPane.setCenter(dobrodoslica);
Scene scene = new Scene(borderPane,300,300);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("Domaci: Kviz");
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
You can see that when a button is clicked it creates a whole new scene and BorderPane, and populates it with content. I figured that it would be best to create a method with each scene and then call each method when a button is clicked. The problem is I cant figure out how to do this.
Any help is appreciated. Thanks in advance.
I'm attempting to have a node recognize when a drag gesture is performed from one node to another.
I've tried to set a MouseDragEvent through node#setOnMouseDragOver but it doesn't ever get invoked.
This is my implementation:
nfaNode.setOnMouseDragOver(event1 -> {
System.out.println("over " + nfaNode.getText().getText());
});
I want it to know that Q_1 is being dragged over so that I am able to tell that Q_0 is being dragged to Q_1.
During a dragging gesture events are only delivered to the node where the gesture started by default. To change this, you need to call startFullDrag in the onDragDetected handler. Also if you move the node around, setting mousetransparent to true may be necessary for the mouse events not to be delivered just to the dragged node.
Example
#Override
public void start(Stage primaryStage) {
Rectangle rect1 = new Rectangle(100, 100, Color.BLUE);
Rectangle rect2 = new Rectangle(200, 200, 100, 100);
rect2.setFill(Color.RED);
rect1.setOnDragDetected(evt -> {
rect1.startFullDrag();
});
rect2.setOnMouseDragOver(evt -> {
System.out.println("over");
});
Pane root = new Pane(rect1, rect2);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
Comment out rect1.startFullDrag(); and you'll not see any output in the console.
Update
You can retrieve the gestureSource from a MouseDragEvent to get the node where you started the drag gesture and use getSource to retrieve the node where the event handler was added. Example:
#Override
public void start(Stage primaryStage) {
TextField text1 = new TextField();
TextField text2 = new TextField();
EventHandler<MouseEvent> dragDetected = evt -> ((Node) evt.getSource()).startFullDrag();
EventHandler<MouseDragEvent> dragOver = evt -> {
System.out.println("over " + ((TextField) evt.getGestureSource()).getText());
};
EventHandler<MouseDragEvent> dragReleased = evt -> {
TextField target = (TextField) evt.getSource();
TextField source = (TextField) evt.getGestureSource();
if (source != target) {
target.setText(source.getText());
source.clear();
}
};
for (TextField tf : Arrays.asList(text1, text2)) {
tf.setOnDragDetected(dragDetected);
tf.setOnMouseDragOver(dragOver);
tf.setOnMouseDragReleased(dragReleased);
}
VBox root = new VBox(text1, text2);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
I want to make a new stage in JavaFX and when I will click a button the new stage will pop-up with a new scene.
When the new scene will pop-up previous stage will appear but wouldn't work. When I would close the pop-up then the previous window will work. Please help me to do that.
You could try using the code snippet below:
public void start(Stage primaryStage) {
try {
Pane root = new Pane();
Scene scene = new Scene(root, 400, 400);
Button btn = new Button(); // create a btn
root.getChildren().add(btn); // add this btn to the root
btn.setOnAction(new EventHandler<ActionEvent>() // when click
{
#Override
public void handle(ActionEvent e) {
Stage dialog = new Stage(); // new stage
dialog.initModality(Modality.APPLICATION_MODAL);
// Defines a modal window that blocks events from being
// delivered to any other application window.
dialog.initOwner(primaryStage);
VBox vb = new VBox(20);
Scene dialogScene = new Scene(vb, 300, 200);
dialog.setScene(dialogScene);
dialog.show();
}
});
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
I am making a GUI using JavaFx, I want a name field to appear if the check box is checked and disappear if it is not checked.
Here is the code I wrote
test1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Boolean b = test1.isSelected();
log(b);
Label label1 = new Label("Name:");
TextField textField = new TextField();
HBox hb = new HBox();
if (test1.isSelected()) {
hb.getChildren().addAll(label1, textField);
hb.setSpacing(10);
grid.add(hb, 3, 3);
} else {
**hb.getChildren().removeAll(label1 , textField);** <---look at this!
}
}
});
I am removing the node if it is unchecked but it doesn't execute it accordingly. What am I doing wrong?
Incase it is required, here is how I execute my scene.
Scene scene = new Scene(grid, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
I am having a resize issue when content is added and removed from a JavaFX BorderPane. The BorderPane content is not being resized until the window is manually resized. I have written a small test app to model this behavior. The application builds a BorderPane that contains a rectangle embedded within a StackPane at the center of the BorderPane. Along the bottom of the BorderPane there is a VBox and HBox that contain text and a separator. There is a menu item that removes the content from the bottom of the BorderPane (MoveText -> Right) and adds similar content to the right position of the BorderPane.
When the text is added to the right position of the BorderPane, the rectangle overlaps the text. In otherwords the content of the BorderPane center is overlapping the content in the BorderPane right.
I saw the following link -
https://stackoverflow.com/questions/5302197/javafx-bug-is-there-a-way-to-force-repaint-this-is-not-a-single-threading-pr
Calling requestLayout does not seem to help. I have also tried calling impl_updatePG and impl_transformsChanged on various nodes in the graph. I got this idea from this thread - https://forums.oracle.com/forums/thread.jspa?threadID=2242083
public class BorderPaneExample extends Application
{
private BorderPane root;
private StackPane centerPane;
#Override
public void start(Stage primaryStage) throws Exception
{
root = new BorderPane();
root.setTop(getMenu());
root.setBottom(getBottomVBox());
centerPane = getCenterPane();
root.setCenter(centerPane);
Scene scene = new Scene(root, 900, 500);
primaryStage.setTitle("BorderPane Example");
primaryStage.setScene(scene);
primaryStage.show();
}
private MenuBar getMenu()
{
MenuBar menuBar = new MenuBar();
MenuItem rightMenuItem = new MenuItem("Right");
rightMenuItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
root.setRight(getRightHBox());
root.setBottom(null);
root.requestLayout();
}
});
MenuItem bottomMenuItem = new MenuItem("Bottom");
bottomMenuItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
root.setRight(null);
root.setBottom(getBottomVBox());
}
});
Menu menu = new Menu("Move text");
menu.getItems().add(rightMenuItem);
menu.getItems().add(bottomMenuItem);
menuBar.getMenus().addAll(menu);
return menuBar;
}
private HBox getRightHBox()
{
HBox hbox = new HBox();
VBox vbox = new VBox(50);
vbox.setPadding(new Insets(0, 20, 0, 20));
vbox.setAlignment(Pos.CENTER);
vbox.getChildren().addAll(new Text("Additional Info 1"),
new Text("Additional Info 2"), new Text("Additional Info 3"));
hbox.getChildren().addAll(new Separator(Orientation.VERTICAL), vbox);
return hbox;
}
private VBox getBottomVBox()
{
VBox vbox = new VBox();
HBox hbox = new HBox(20);
hbox.setPadding(new Insets(5));
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().addAll(new Text("Footer Item 1")
, new Text("Footer Item 2"), new Text("Footer Item 3"));
vbox.getChildren().addAll(new Separator(), hbox);
return vbox;
}
private StackPane getCenterPane()
{
StackPane stackPane = new StackPane();
stackPane.setAlignment(Pos.CENTER);
final Rectangle rec = new Rectangle(200, 200);
rec.setFill(Color.DODGERBLUE);
rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
rec.heightProperty().bind(stackPane.heightProperty().subtract(50));
stackPane.getChildren().addAll(rec);
return stackPane;
}
public static void main(String[] args)
{
Application.launch(args);
}
}
Any suggestions would be appreciated.
Thanks
For the sake of having an answer:
The StackPane needs to have its minimum size set in order to do clipping. So if you explicitly add stackPane.setMinSize(0, 0); to the getCenterPane() method, it should fix your problem.
So your getCenterPane() method would now look like this:
private StackPane getCenterPane()
{
StackPane stackPane = new StackPane();
stackPane.setMinSize(0, 0);
stackPane.setAlignment(Pos.CENTER);
final Rectangle rec = new Rectangle(200, 200);
rec.setFill(Color.DODGERBLUE);
rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
rec.heightProperty().bind(stackPane.heightProperty().subtract(50));
stackPane.getChildren().addAll(rec);
return stackPane;
}