JavaFX BorderPane Maximising Window Issues - javafx

My code creates a window and lays it out exactly how I want... initially. However, if I maximise the window, the top and bottom parts of the border pane do not remain in the centre. They drift off to the top left and bottom left corners.
I tried to disable the maximise window option, but again it messes up the look of the page, with the top and bottom parts moving.
Here is my code:
#Override
public void start(Stage startWindow) {
startWindow.setTitle("QuizApp");
BorderPane borderPane = new BorderPane();
borderPane.setTop(addHorizontalBoxWithMessage());
borderPane.setCenter(addImageView());
borderPane.setBottom(addHorizontalBoxWithButton());
Scene scene = new Scene(borderPane, 750, 663);
startWindow.setScene(scene);
scene.getStylesheets().add(StartWindow.class.getResource("application.css").toExternalForm());
// startWindow.resizableProperty().setValue(Boolean.FALSE);
startWindow.show();
}
public HBox addHorizontalBoxWithMessage() {
HBox hBox = new HBox();
hBox.setId("hBox");
hBox.setMinWidth(750);
hBox.setMinHeight(50);
hBox.setMaxWidth(750);
hBox.setMaxHeight(50);
hBox.setPadding(new Insets(0, 10, 0, 10));
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Text message = new Text("Welcome to the QuizApp!");
message.setId("message");
hBox.getChildren().add(message);
return hBox;
}
public ImageView addImageView() {
Image image = new Image(getClass().getResourceAsStream("quiz.jpg"));
ImageView imageView = new ImageView();
imageView.setImage(image);
imageView.setFitWidth(750);
imageView.setFitHeight(563);
return imageView;
}
public HBox addHorizontalBoxWithButton() {
HBox hBox = new HBox();
hBox.setId("hBox");
hBox.setMinWidth(750);
hBox.setMinHeight(50);
hBox.setMaxWidth(750);
hBox.setMaxHeight(50);
hBox.setPadding(new Insets(10, 10, 10, 10));
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button registerButton = new Button("Register");
registerButton.setPrefSize(100, 30);
Button loginButton = new Button("Login");
loginButton.setPrefSize(100, 30);
hBox.getChildren().add(registerButton);
hBox.getChildren().add(loginButton);
return hBox;
}
I only started teaching myself JavaFX last night but can't seem to figure out where I am going wrong, or find a solution to my problem.
Thanks in advance for any advice.

In your code replace : hBox.setMaxWidth(750);
with:
hBox.setMaxWidth(Region.USE_COMPUTED_SIZE);
The problem was that after resizing your hbox, the width was still 750 px long
Another easy option is to use JavaFX Scene Builder to figure out how GUI components works.

Related

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();
}

Moving Button or Any thing else in javafx?

Button btn=new Button("Click Me");
Button btn2=new Button("Click");
btn2.setOnAction(e->System.exit(0));
btn.setOnAction(new EventHandler<ActionEvent>(){
public void handle(ActionEvent action){
System.out.println(5);
}
});
btn2.relocate(0, 0);
StackPane root=new StackPane();
root.getChildren().add(btn);
root.getChildren().add(btn2);
Scene sene=new Scene(root,500,265);
primaryStage.setScene(sene);
primaryStage.show();
I want to move button and using above code but I am unable to move my button?
What is the problem in code and is their any other way to do it???
The answer is :
http://docs.oracle.com/javafx/2/animations/jfxpub-animations.htm
JavaFX has ready libraries for animations.
An example (the rectangle will be faded):
final Rectangle rect1 = new Rectangle(10, 10, 100, 100);
rect1.setArcHeight(20);
rect1.setArcWidth(20);
rect1.setFill(Color.RED);
...
FadeTransition ft = new FadeTransition(Duration.millis(3000), rect1);
ft.setFromValue(1.0); ft.setToValue(0.1);
ft.setCycleCount(Timeline.INDEFINITE);
ft.setAutoReverse(true);
ft.play();
In your code you maybe need TranslateTranstition or just use translateX and translateY methods

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