I'm learning Javafx layouts and I would like to obtain the following result:
HBox in the bottom center fo a Pane I have tried with the following code but I'm not able to do that
Can you please explain what I'm doing wrong? and How to achieve that?
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TestLayout extends Application {
#Override
public void start(Stage stage) {
initUI(stage);
}
private void initUI(Stage stage) {
Scene scene =null;
HBox hbox = new HBox();
hbox.setStyle("-fx-background-color: #FFFAAA;");
StackPane pane = new StackPane();
hbox.setStyle("-fx-background-color: #AAFAAA;");
hbox.prefWidthProperty().bind(pane.widthProperty().divide(4));
hbox.prefHeightProperty().bind(pane.heightProperty().divide(10));
pane.getChildren().add(hbox);
scene = new Scene(pane, 600, 600);
pane.prefWidthProperty().bind(scene.widthProperty());
pane.prefHeightProperty().bind(scene.heightProperty());
stage.setTitle("Test");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class AppLauncherTest {
public static void main(String[] args) {
TestLayout.main(args);
}
}
I would Use a VBox or BorderPane as the root node. In this example, I use a VBox. I am assuming more nodes will go into this so I used a StackPane as the top node. This may need to be changed out or some other Pane may need to be added to this. That depends on what you are trying to do with the end product. For the bottom, I used an HBox and I set it's Margins.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Priority;
import javafx.geometry.Insets;
/**
* JavaFX App
*/
public class App extends Application {
#Override
public void start(Stage stage) {
StackPane subRootTop = new StackPane();
VBox.setVgrow(subRootTop, Priority.ALWAYS);
//subRootTop.setStyle("-fx-background-color: yellow;");
HBox subRootBotton = new HBox();
VBox.setVgrow(subRootBotton, Priority.ALWAYS);
subRootBotton.setStyle("-fx-background-color: green;");
subRootBotton.setMaxHeight(150);
VBox.setMargin(subRootBotton, new Insets(40, 40, 40, 40));
VBox root = new VBox(subRootTop, subRootBotton);
root.setStyle("-fx-background-color: red;");
Scene scene = new Scene(root, 600, 600);;
stage.setTitle("Test");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
The binding of the StackPane is not size shouldn't be done. The scene automatically resizes its root to fill the whole area available. Assuming you want relative sizes, using StackPane is not really a good choice.
If you want the child to have a fixed distance to left right and bottom of the StackPane, you can do so specifying margins and alignment. Make sure the child does not grow to fit the parent though by setting the maxHeight to use the preferred height:
private void initUI(Stage stage) {
HBox hbox = new HBox();
hbox.setStyle("-fx-background-color: #FFFAAA;");
hbox.setMaxHeight(Region.USE_PREF_SIZE);
// could be calculated based on children instead of assigning
// an absolute value
hbox.setPrefHeight(30);
StackPane.setAlignment(hbox, Pos.BOTTOM_CENTER);
StackPane.setMargin(hbox, new Insets(20));
StackPane pane = new StackPane(hbox);
pane.setStyle("-fx-background-color: #AAFAAA;");
Scene scene = new Scene(pane, 600, 600);
stage.setTitle("Test");
stage.setScene(scene);
stage.show();
}
Maybe you can use an AnchorPane as a base layout instead of the StacKPane. I made a small exmaple how it would look like. Of cause you could keep the StackPane as the base layout and just put the AnchorPane with the HBox onto it, but you should definitly use an AnchorPane for your plan.
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
private void initUI(Stage stage) {
// Create an anchor pane as base layout and set a color:
AnchorPane root = new AnchorPane();
root.setStyle("-fx-background-color: #FFFAAA;");
// Create a second container and set a minimum height and a color;
HBox hbox = new HBox();
hbox.setMinHeight(100d);
hbox.setStyle("-fx-background-color: #AAFAAA;");
// Give the child container a fixed location:
AnchorPane.setBottomAnchor(hbox, 50d);
AnchorPane.setLeftAnchor(hbox, 75d);
AnchorPane.setRightAnchor(hbox, 75d);
// Add the horizontal box to the base anchor pane:
root.getChildren().add(hbox);
stage.setScene(new Scene(root, 600, 600));
stage.show();
}
#Override
public void start(Stage stage) throws Exception {
initUI(stage);
}
public static void main(String[] args) {
launch(args);
}
}
Preview:
Related
I'm having some problems with this view. What I need to do it in JavaFX to add this 'border' and divide the circle into 2 parts.
public void start(Stage primaryStage){
Circle mycircle = new Circle(200,200,200);
mycircle.setFill(Color.GREEN);
BorderPane root = new BorderPane();
root.setCenter(mycircle);
}
I don't have errors but it's not the view what I am looking for. So can anyone help me with this, please
And btw sorry for bad image quality
Would this satisfy your needs?
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class HalfCircleDemo extends Application {
#Override
public void start(final Stage stage) {
BorderPane root = new BorderPane();
Group circleGroup = new Group();
Circle greenCircle = new Circle(200,200,200);
greenCircle.setFill(Color.GREEN);
Circle blueCircle = new Circle(200,200,200);
blueCircle.setFill(Color.BLUE);
Rectangle clip = new Rectangle(400, 200);
greenCircle.setClip(clip);
circleGroup.getChildren().setAll(blueCircle, greenCircle);
root.setCenter(circleGroup);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You could use Paths with ArcTo elements:
private static Group createHalfCircles(double radius) {
Path upperHalf = new Path(
new MoveTo(0, radius),
new ArcTo(radius, radius, 0, 2*radius, radius, true, false),
new ClosePath());
upperHalf.setFill(Color.PURPLE);
upperHalf.setStroke(null);
Path lowerHalf = new Path(
new MoveTo(2 * radius, radius),
new ArcTo(radius, radius, 0, 0, radius, true, false),
new ClosePath());
lowerHalf.setFill(Color.GREEN);
lowerHalf.setStroke(null);
return new Group(upperHalf, lowerHalf);
}
#Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(createHalfCircles(50));
primaryStage.setScene(scene);
primaryStage.show();
}
In Javafx the DisclosureNode of Treeview is on left by default. How can I I place the Disclosure Node to Right (float right)..??
Any Help would be appreciated.
You only need to set the Node Orientation to get a right to left behaviour. But be aware of, that all childrens of this TreeView will inherit the orientation as a default.
import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TreeViewRightLeft extends Application {
#Override
public void start(Stage primaryStage) {
TreeItem<String> item = new TreeItem<>("Root Node");
item.setExpanded(true);
item.getChildren().addAll(
new TreeItem<>("Item 1"),
new TreeItem<>("Item 2"),
new TreeItem<>("Item 3")
);
TreeView<String> treeView = new TreeView<>(item);
// Here you can select the orientation.
treeView.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
BorderPane root = new BorderPane(treeView);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("TreeView");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Right to Left
Left to Right (default)
I have a SplitPane and I need to divide the layout 25% and 75%. Also, I need to disallow dragging towards right side beyond the 25% split. However I can drag to any extent within the 25% space. Please help.
SplitPane will respect the min and max dimensions of the components (items) it contains. So to get the behavior you want, bind the maxWidth of the left component to splitPane.maxWidthProperty().multiply(0.25):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ConstrainedSplitPane extends Application {
#Override
public void start(Stage primaryStage) {
StackPane leftPane = new StackPane(new Label("Left"));
StackPane rightPane = new StackPane(new Label("Right"));
SplitPane splitPane = new SplitPane();
splitPane.getItems().addAll(leftPane, rightPane);
splitPane.setDividerPositions(0.25);
//Constrain max size of left component:
leftPane.maxWidthProperty().bind(splitPane.widthProperty().multiply(0.25));
primaryStage.setScene(new Scene(new BorderPane(splitPane), 800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This worked for me
private final double dividerMaxWidth = .15;
splitPane.getDividers().get(0).positionProperty().addListener((observable,oldValue,newValue) -> {
if(splitPane.getDividers().get(0).getPosition() > dividerMaxWidth)
splitPane.setDividerPosition(0, dividerMaxWidth);
});
And if you want to lock a divider into a hard position that cannot be moved
private final double absolutePosition = .15;
splitPane.getDividers().get(0).positionProperty().addListener((observable,oldValue,newValue) -> {
splitPane.setDividerPosition(0, absolutePosition);
});
I have TitledPane, which i want to hide back (after expanding - un-expand it) after pressing a button. Is there any way to do it? I didn't find any way :( Thanks!
Just do
titledPane.setExpanded(false);
Complete example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TitledPaneExample extends Application {
#Override
public void start(Stage primaryStage) {
Label label = new Label("Some content");
Button button = new Button("OK");
VBox content = new VBox(10, label, button);
TitledPane titledPane = new TitledPane("Titled Pane", content);
button.setOnAction(e -> titledPane.setExpanded(false));
VBox root = new VBox(titledPane);
Scene scene = new Scene(root, 250, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I want to resize ScrollPane to fit the parent component. I tested this code:
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MainApp extends Application {
#Override
public void start(Stage stage) throws Exception {
BorderPane bp = new BorderPane();
bp.setPrefSize(600, 600);
bp.setMaxSize(600, 600);
bp.setStyle("-fx-background-color: #2f4f4f;");
VBox vb = new VBox(bp);
ScrollPane scrollPane = new ScrollPane(vb);
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);
scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
Scene scene = new Scene(scrollPane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
But as you can see I don't see tree scroll bars. Is there anything wrong into my code?
The scrollbars won't show up because
You have the policy set to ScrollBarPolicy.AS_NEEDED
The width and height of the scroll bars are automatically resized to that of its' container, which, in this case, is your resizable Vbox.
To fix this, you could remove setFitToHeight and setFitToWidth and leave them as false.
Note that ScrollBarPolicy could also be set to ALWAYS as opposed to AS_NEEDED, which will keep the scroll bars even when the window is expanded.
Refer here for more information using ScrollPane
ScrollPane API: setFitToHeight
public class MainApp extends Application {
#Override
public void start(Stage stage) throws Exception {
BorderPane bp = new BorderPane();
bp.setPrefSize(600, 600);
bp.setMaxSize(600, 600);
bp.setStyle("-fx-background-color: #2f4f4f;");
VBox vb = new VBox(bp);
ScrollPane scrollPane = new ScrollPane(vb);
//scrollPane.setFitToHeight(true);
//scrollPane.setFitToWidth(true);
scrollPane.setHbarPolicy(ScrollBarPolicy.ALWAYS);
scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS);
Scene scene = new Scene(scrollPane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}