Cant get pane centered in Borderpane - javafx

Ok so I am in a basic programming class, and we have to make a borderpane that has all the different panes inside of it. When i try to put just a regular pane in the center with a "hello" button inside it the button gets put on the top the borderpane. All of the other panes I use a method that makes 5 buttons and randomly inserts a word and randomly rotates it. How do i get the pane to be in the center and not the top
StackPane root = new StackPane();
Button[] buttons = new Button[5];
buttons = createButtons();
root.getChildren().addAll(buttons);
FlowPane flow = new FlowPane();
Button[] buttons1 = new Button[5];
buttons1 = createButtons();
flow.getChildren().addAll(buttons1);
HBox hbox= new HBox();
Button[] buttons2 = new Button[5];
buttons2 = createButtons();
hbox.getChildren().addAll(buttons2);
VBox vbox = new VBox();
Button[] buttons3 = new Button[5];
buttons3 = createButtons();
vbox.getChildren().addAll(buttons3);
Pane pane = new Pane();
Button btn = new Button();
btn.setText("Hello");
pane.getChildren().add(btn);
BorderPane border = new BorderPane();
border.setBottom(hbox);
border.setLeft(root);
border.setRight(vbox);
border.setTop(flow);
border.setCenter(pane);
Scene scene = new Scene(border, 500, 500);
primaryStage.setTitle("Buttons");
primaryStage.setScene(scene);
primaryStage.show();
}

You should add a background color for identification, e. g. via setStyle("-fx-background-color:black). This way you see how each of your panes are laid out.
Example:
public class BindIt extends Application {
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.setStyle("-fx-background-color:red");
Button[] buttons = new Button[5];
buttons = createButtons();
root.getChildren().addAll(buttons);
FlowPane flow = new FlowPane();
flow.setStyle("-fx-background-color:blue");
Button[] buttons1 = new Button[5];
buttons1 = createButtons();
flow.getChildren().addAll(buttons1);
HBox hbox= new HBox();
hbox.setStyle("-fx-background-color:green");
Button[] buttons2 = new Button[5];
buttons2 = createButtons();
hbox.getChildren().addAll(buttons2);
VBox vbox = new VBox();
vbox.setStyle("-fx-background-color:yellow");
Button[] buttons3 = new Button[5];
buttons3 = createButtons();
vbox.getChildren().addAll(buttons3);
Pane pane = new Pane();
pane.setStyle("-fx-background-color:cyan");
Button btn = new Button();
btn.setText("Hello");
pane.getChildren().add(btn);
BorderPane border = new BorderPane();
border.setStyle("-fx-background-color:black");
border.setBottom(hbox);
border.setLeft(root);
border.setRight(vbox);
border.setTop(flow);
border.setCenter(pane);
Scene scene = new Scene(border, 500, 500);
primaryStage.setTitle("Buttons");
primaryStage.setScene(scene);
primaryStage.show();
}
private Button[] createButtons() {
return new Button[] { new Button( "Button") };
}
public static void main(String[] args) {
launch(args);
}
}
It gives you this:
Now you see that the center pane is in the center and fills the center. The problem is that the button isn't in the center. The easy solution is to just use a StackPane for the center pane:
StackPane pane = new StackPane();
Another solution would be to relocate the button to the center of the center pane. But then you'd have to consider resizing of the parent.

Related

Border Pane issues

I want to make a border pane with two HBoxes on top and bottom and a GridPane in the center... I wrote what I needed, attached the labels but I can't run the code
Exception in Application start method
java.lang.reflect.InvocationTargetException is what I get as an error... the code is below, any help is welcome :) thanks
public class labelBorder extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane bp = new BorderPane();
bp.setPrefSize(400, 400);
HBox hb1 = new HBox();
Label lb1 = new Label("");
lb1.setPrefWidth(200);
lb1.setBorder(new Border(new BorderStroke(Color.AQUAMARINE,BorderStrokeStyle.SOLID,null,new BorderWidths(5))));
Label lb2 = new Label("");
lb2.setPrefWidth(200);
lb2.setBorder(new Border(new BorderStroke(Color.BLUEVIOLET,BorderStrokeStyle.SOLID,null,new BorderWidths(5))));
HBox hb2 = new HBox();
URI foto = Paths.get("D:\\Barca.jpg").toUri();
Label lb3 = new Label();
lb3.setGraphic(new ImageView(foto.toString()));
lb3.autosize();
GridPane gp = new GridPane();
Label lb4 = new Label("");
Label lb5 = new Label("");
Label lb6 = new Label("");
Label lb7 = new Label("");
gp.add(lb4, 0, 0);
gp.add(lb5, 0, 1);
gp.add(lb6, 1, 0);
gp.add(lb7, 1, 1);
gp.getChildren().addAll(lb4,lb5,lb6,lb7);
hb1.getChildren().addAll(lb1,lb2);
hb2.getChildren().addAll(lb3);
bp.setTop(hb1);
bp.setCenter(gp);
bp.setBottom(hb2);
bp.getChildren().addAll(hb1,hb2,gp);
Scene scene = new Scene(bp);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You should NOT add the duplicate children controls to your parent layout(pane). Your code must be throwing,
java.lang.IllegalArgumentException: Children: duplicate children added
To overcome your issue remove these lines,
gp.getChildren().addAll(lb4,lb5,lb6,lb7);
And,
bp.getChildren().addAll(hb1,hb2,gp);
As those controls have already been added to your corresponding layout.
Note: Adding children with pane.getChildren().addAll(...) on BorderPane is irrelevant and will be ignored while rendering the added controls.

javafx - Navigation Sidebar with Toggle

So in windows 10 you have the windows menu with the icons on the left side:
When clicking on the hamburger icon the menu expands and text is show.
The expanded part is overlaying the content. The text is showing. and it was animated in (sliding transition).
In my application I want to make a similar menu on the right side (see blue part):
I have absolutely no idea how to get this effect. Currently I made a button with a graphic. I only display the graphic and when I click on the hamburger I show all the text by changing the setContentDisplay(ContentDisplay.GRAPHIC_ONLY) to setContentDisplay(ContentDisplay.RIGHT) 2 things that are wrong with this approach.
it pushes the content.
You cannot add a transition.
Any help would be appreciated, especially examples.
Demo
I made a demo that shows what I currently have:
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
JFXButton[] jfxButtons = {
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
};
JFXHamburger hamburger = new JFXHamburger();
HamburgerNextArrowBasicTransition transition = new HamburgerNextArrowBasicTransition(hamburger);
transition.setRate(-1);
hamburger.setAlignment(Pos.CENTER_RIGHT);
hamburger.setPadding(new Insets(5));
hamburger.setStyle("-fx-background-color: #fff;");
hamburger.setOnMouseClicked(event -> {
transition.setRate(transition.getRate() * -1);
transition.play();
if (transition.getRate() == -1) {
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
} else {
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setContentDisplay(ContentDisplay.RIGHT);
}
}
});
ScrollPane scrollPane = new ScrollPane();
VBox vBox = new VBox();
scrollPane.setContent(vBox);
vBox.getStyleClass().add("content_scene_right");
vBox.getChildren().add(hamburger);
vBox.getChildren().addAll(jfxButtons);
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setMaxWidth(Double.MAX_VALUE);
jfxButton.setRipplerFill(Color.valueOf("#40E0D0"));
VBox.setVgrow(jfxButton, Priority.ALWAYS);
jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
vBox.setFillWidth(true);
Label labelHoverOverTest = new Label("Testing label");
VBox vbox2 = new VBox();
vbox2.getChildren().addAll(labelHoverOverTest);
vbox2.setAlignment(Pos.CENTER_RIGHT);
root.setRight(scrollPane);
root.setCenter(vbox2);
Scene scene = new Scene(root);
primaryStage.setMinWidth(400);
primaryStage.setMinHeight(400);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I used JFoenix and fontawesomefx for this demo, but it can also be javafx scene buttons with any graphic.
Here are some images of what the demo looks like:
As you can see it pushes it the content in the center and I can't add any transition.
(here is a sample from bootstrap to give you an idea on What I'm trying to make it look like 1: https://bootsnipp.com/snippets/Pa9xl, 2: https://bootsnipp.com/snippets/featured/navigation-sidebar-with-toggle (with this one the content still moves, but it should give you a clear idea on what my vision is))
Problem is that you are using BorderPane and placing everything on same layer, so when content on right changes width it will affect one in the center and such.
In other to avoid this you should make it layered, so for root of view use StackPane, this pane should have 2 children, 1 for main content and 1 for sidebar, make sure that sidebar is above main content, now this 2 can be any Pane that you want. This way sidebar will be placed over main content and it won't push content.
Using code you provided and just adding StackPane you get something like this:
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
BorderPane mainContent = new BorderPane();
BorderPane sidebar = new BorderPane();
JFXButton[] jfxButtons = {
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),};
JFXHamburger hamburger = new JFXHamburger();
HamburgerNextArrowBasicTransition transition = new HamburgerNextArrowBasicTransition(hamburger);
transition.setRate(-1);
hamburger.setAlignment(Pos.CENTER_RIGHT);
hamburger.setPadding(new Insets(5));
hamburger.setStyle("-fx-background-color: #fff;");
hamburger.setOnMouseClicked(event -> {
transition.setRate(transition.getRate() * -1);
transition.play();
if (transition.getRate() == -1) {
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
} else {
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setContentDisplay(ContentDisplay.RIGHT);
}
}
});
ScrollPane scrollPane = new ScrollPane();
VBox vBox = new VBox();
scrollPane.setContent(vBox);
vBox.getStyleClass().add("content_scene_right");
vBox.getChildren().add(hamburger);
vBox.getChildren().addAll(jfxButtons);
for (JFXButton jfxButton : jfxButtons) {
jfxButton.setMaxWidth(Double.MAX_VALUE);
jfxButton.setRipplerFill(Color.valueOf("#40E0D0"));
VBox.setVgrow(jfxButton, Priority.ALWAYS);
jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
vBox.setFillWidth(true);
Label labelHoverOverTest = new Label("Testing label");
VBox vbox2 = new VBox();
vbox2.getChildren().addAll(labelHoverOverTest);
vbox2.setAlignment(Pos.CENTER_RIGHT);
mainContent.setCenter(vbox2);
sidebar.setRight(scrollPane);
root.getChildren().addAll(mainContent, sidebar);
Scene scene = new Scene(root);
primaryStage.setMinWidth(400);
primaryStage.setMinHeight(400);
primaryStage.setScene(scene);
primaryStage.show();
}
As for transition I'm not sure what is problem there, for me it works fine.

Java FX out of the window screen

I wanna it will be okay when the number variables is changed, but when the are increased the button goes out from the window. How to fix it? Also how to put the bar down to the level of "10$", so they will be in the same row?
Before :
After :
Here is my code :
VBox vboxBottom = new VBox();
HBox hboxBottomElements = new HBox(15);
HBox hboxBottomMain = new HBox(0);
Region region = new Region();
region.setPrefWidth(500);
hboxBottomElements.getChildren().addAll(visaLabel, separator2, adLabel, separator3, governRelationStatus, separator4, region, next);
hboxBottomElements.setPadding(new Insets(5));
vboxBottom.getChildren().addAll(separator1, new Group(hboxBottomElements));
vboxBottom.setPadding(new Insets(3));
hboxBottomMain.getChildren().addAll(new Group(moneyBox), vboxBottom);
hboxBottomMain.setPadding(new Insets(3));
layout.setBottom(hboxBottomMain);
By using a Group here
vboxBottom.getChildren().addAll(separator1, new Group(hboxBottomElements));
you're creating a layout structure that resizes hboxBottomElements to it's prefered size independent of the space available.
HBox simply moves elements out the right side of it's bounds, if the space available does not suffice. This means if the Group containing moneyBox grows, the Button is moved out of the HBox...
The following simpler example demonstrates the behavior:
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Do something");
HBox.setHgrow(btn, Priority.NEVER);
btn.setMinWidth(Region.USE_PREF_SIZE);
Region filler = new Region();
filler.setPrefWidth(100);
HBox.setHgrow(filler, Priority.ALWAYS);
Rectangle rect = new Rectangle(200, 50);
HBox hBox = new HBox(rect, filler, btn);
Scene scene = new Scene(hBox);
primaryStage.setScene(scene);
primaryStage.show();
}
This will resize filler to make the HBox fit the window.
Now replace
Scene scene = new Scene(hBox);
with
Scene scene = new Scene(new Group(hBox));
and the Button will be moved out of the window...

JAVAFX: How can I put this into one window instead of two?

I've been trying to make a toolbar inside a window with a checkers game, what happens now is, Checkers game opening in a separate window and so is the toolbar, what am I doing wrong? How can I make this code open in one window with both functions?
#Override
public void start(Stage primaryStage) throws Exception {
Stage toolStage = new Stage();
Button btnNewGame = new Button("New Game");
Button btnConcede = new Button("Concede");
Button btnNetwork = new Button("Network");
ToolBar toolBar = new ToolBar();
toolBar.getItems().addAll( new Separator(), btnNewGame, btnConcede, btnNetwork);
BorderPane pane = new BorderPane();
pane.setTop(toolBar);
Scene toolScene = new Scene(pane, 600, 400);
toolStage.setScene(toolScene);
toolStage.show();
Scene scene = new Scene(createContent());
primaryStage.setTitle("Dam spill - OBJ2000 Eksamen 2016");
primaryStage.setScene(scene);
primaryStage.show();
}
You're creating a new Scene+Stage fot the toolbar, show it and then show the content in the primaryStage instead of adding both toolbar and content as parts of the same scene, e.g. by adding the content as center node of the BorderPane:
#Override
public void start(Stage primaryStage) throws Exception {
Button btnNewGame = new Button("New Game");
Button btnConcede = new Button("Concede");
Button btnNetwork = new Button("Network");
ToolBar toolBar = new ToolBar();
toolBar.getItems().addAll( new Separator(), btnNewGame, btnConcede, btnNetwork);
BorderPane pane = new BorderPane();
pane.setTop(toolBar);
pane.setCenter(createContent());
Scene scene = new Scene(pane, 600, 400);
primaryStage.setTitle("Dam spill - OBJ2000 Eksamen 2016");
primaryStage.setScene(scene);
primaryStage.show();
}

Javafx - How to set drag range for components added in a pane

i have tried a below sample, in which left area of border Pane will have list of components and center of the border pane will act as a canvas area and here i have added a rectangle on run time as children to a Pane which is set to Center portion of BorderPane. But when drag the rectangle it moving outof the area allocated for the center, so how could i make this drag around only inside the Center Pane.
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("BPM");
BorderPane border = new BorderPane();
Pane canvas = new Pane();
canvas.setStyle("-fx-background-color: #F0F0F0;");
border.setLeft(compList());
border.setCenter(canvas);
//
Anchor start = new Anchor(null, "Start", Color.PALEGREEN, new SimpleDoubleProperty(170), new SimpleDoubleProperty(170));
final Rect rect=new Rect(100, 70,new SimpleDoubleProperty(10), new SimpleDoubleProperty(100));
rect.setX(100);
rect.setY(100);
canvas.getChildren().add(rect);
canvas.getChildren().add(start);
Scene scene = new Scene(border, 800, 600);
stage.setScene(scene);
stage.show();
}
Actually, by default, the Pane class does not ensure that all its children are clipping hence there are possibility that the children might go out of the boundary of the Pane. To ensure that all children (in your case, the rectangle) are dragged within specify boundary, you have to manually check the boundary as you dragging the children. Below are example of my implementation:
#Override
public void start(Stage stage){
stage.setTitle("BPM");
BorderPane mainPanel = new BorderPane();
VBox nameList = new VBox();
nameList.getChildren().add(new Label("Data"));
nameList.setPrefWidth(150);
Pane canvas = new Pane();
canvas.setStyle("-fx-background-color: #ffe3c3;");
canvas.setPrefSize(400,300);
Circle anchor = new Circle(10);
double rectWidth = 50, rectHeight = 50;
Rectangle rect = new Rectangle(50,50);
rect.setX(100);
rect.setY(100);
canvas.getChildren().addAll(rect, anchor);
// set the clip boundary
Rectangle bound = new Rectangle(400,300);
canvas.setClip(bound);
rect.setOnMouseDragged(event -> {
Point2D currentPointer = new Point2D(event.getX(), event.getY());
if(bound.getBoundsInLocal().contains(currentPointer)){
if(currentPointer.getX() > 0 &&
(currentPointer.getX() + rectWidth) < bound.getWidth()){
rect.setX(currentPointer.getX());
}
if(currentPointer.getY() > 0 &&
(currentPointer.getY() + rectHeight) < bound.getHeight()){
rect.setY(currentPointer.getY());
}
}
});
mainPanel.setLeft(nameList);
mainPanel.setCenter(canvas);
Scene scene = new Scene(mainPanel, 800, 600);
stage.setScene(scene);
stage.show();
}

Resources