I have a JavaFX application with a SplitPane. I want to disable the Divider on SplitPane, so it would not be possible to change its position when application is running. How can I do this?
There's no API for that, so once the scene is shown we have to use a lookup function to find the node by its id. In this case, the Divider has this id: split-pane-divider.
Once we find the node, we set it transparent to mouse events:
#Override
public void start(Stage primaryStage) {
final SplitPane splitPane = new SplitPane();
splitPane.setOrientation(Orientation.HORIZONTAL);
splitPane.setDividerPositions(new double[]{0.5});
splitPane.getItems().add(new StackPane(new Label("Left")));
splitPane.getItems().add(new StackPane(new Label("Right")));
Scene scene = new Scene(splitPane, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
splitPane.lookupAll(".split-pane-divider").stream()
.forEach(div -> div.setMouseTransparent(true) );
}
None of the above posts worked for me. I have found this solution which worked for me:
This code works for the case when your splitPane is divided in the middle and has only one divider, therefore the divider's position is set to 0.5. If you don't know the position of the divider, you can get it by divider.getPosition();.
Divider divider = splitPane.getDividers().get(0);
divider.positionProperty().addListener(new ChangeListener<Number>()
{
#Override
public void changed( ObservableValue<? extends Number> observable, Number oldvalue, Number newvalue )
{
divider.setPosition(0.5);
}
});
This code is in the initialize() method of the GUI Controller class.
Set mouseTransparent="true" of SplitPane in Fxml file.
<SplitPane dividerPositions="0.5" mouseTransparent="true" prefHeight="652.0" prefWidth="858.0">
You can also modify the Skin class for SplitPane. Just copy the code from GrepCode for SplitPaneSkin (available here) and remove the MouseListeners in method initializeDivderEventHandlers() and also the setCursor calls in method setGrabberStyle() and then you can't resize the pane by dragging the divider ;-) At the end you only have to set the skin to the SplitPane by calling setSkin.
Related
I have code in the form:
<BorderPane>
...
<right>
<GridPane>
...
</GridPane>
</right>
...
</BorderPane>
Obviously, now the GridPane takes a big space right of my BorderPane. What I'd like to do is add a button (or another element) that minimizes and maximizes the GridPane, so it's only fully in the view of the user when it is really needed. How can I easily achieve this?
You can do what you want by setting the Visible and Managed properties of your GridPane off and on. The centre of the BorderPane will automatically expand to take over the entire width of the BorderPane. "Managed" controls whether or not the layout manager will leave space for the node, so if you just turn Visible off, then you'll have an unused area the size of your GridPane on the right. The following code demonstrates it, I put the buttons in a VBox with a border around it so that you can see how it expands:
public class ResizeRight extends BorderPane {
public ResizeRight() {
Button openButton = new Button("Open");
Button closeButton = new Button("Close");
GridPane gridPane = new GridPane();
gridPane.addRow(0, new Text("This is just some text"));
gridPane.addRow(1, new Text("This is just some more text"));
VBox vbox = new VBox(10, openButton, closeButton);
vbox.setBorder(new Border(new BorderStroke(Color.BLACK,
BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
setCenter(vbox);
setRight(gridPane);
setPadding(new Insets(10));
openButton.setOnAction(evt -> {
gridPane.setVisible(true);
gridPane.setManaged(true);
});
closeButton.setOnAction(evt -> {
gridPane.setVisible(false);
gridPane.setManaged(false);
});
}
}
Run it from something like this:
public class Sample1 extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new ResizeRight(), 300, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
}
In JavaFx I'm currently trying to change the height of
primaryStage via binding.
primaryStage.setScene(scene);
primaryStage.setHeight(400.0);
primaryStage.widthProperty().bindBidirectional(textField.textProperty());
It's just a homework problem, not meaningful.
Unfortunately primaryStage is readOnlyDoubleProperty. May I change this settings to gain write-permissions?
I know, there is the possibility to change the window size via EventHandler, but I would like to change the window size on the fly through the TextField with bindings.
So any newly entered number enlarges the window.
Any ideas?
It's definitely possible and I hope there is a better way and no one should ever use this code ever but this is what I managed to make work
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
//Allows for only numeric input
textField.setTextFormatter(new TextFormatter<>(change -> {
if (change.getText().matches("[0-9]*"))
return change;
else
return null;
}));
primaryStage.setScene(new Scene(textField));
primaryStage.setHeight(200.0);
//Allows Program to start without error
primaryStage.setMaxWidth(200);
//Binds min and max to ensure stage width change due to only 1 possible size
primaryStage.minWidthProperty().bind(primaryStage.maxWidthProperty());
//Bind textfield to width
textField.textProperty().bindBidirectional(primaryStage.maxWidthProperty(), new NumberStringConverter());
primaryStage.show();
}
}
Can you please tell me how can I realize that the whole content of a pane will be resized while the stage is resized with mousedragg. Here is my code:
public class fab extends Application {
private Stage stage;
private Pane pane;
private Scene scene;
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
Button button = new Button("Button");
pane = new Pane();
pane.getChildren().add(button);
stage.setTitle("Test");
scene = new Scene(pane, 640, 640);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
I think there is the idea of binding. But I don't know how to use that, in order to make all nodes of a pane resizable, when the stage size is changing.
I'm searching a solution without Fxml or sceneBuilder.
Thank you in advance.
If you insists to use the Pane container then after the line scene = new Scene(pane, 640, 640); add this:
scene.widthProperty().addListener((c,o,n)->button.setPrefWidth((Double)n));
scene.heightProperty().addListener((c,o,n)->button.setPrefHeight((Double)n));
and after the line stage.setScene(scene); add this:
button.setPrefSize(scene.getWidth(), scene.getHeight());
This works fine with Pane and do your required thing.
But I prefer using an AnchorPane container and set the Top, Right,Bottom and Left anchors to 0 .
Here is the solution if you wish to bind the width of the button to you scene width
button.minWidthProperty().bind(scene.widthProperty());
You can also modify this +/- whatever you want for ex
button.minWidthProperty().bind(scene.widthProperty().subtract(20));
and you can do the same for the height
button.minHeightProperty().bind(scene.heightProperty().subtract(200));
I'm totally new to standalone applications. Please any one help me on this.
I have TableView with 6 columns which is half showing in the window as shown below.
I want to fix its current window size, even when the window is expanded, the tableview should auto resize. Is there any way to do this?
This Is The Code Snippet
GridPane tableGrid= new GridPane();
tableGrid.setVgap(10);
tableGrid.setHgap(10);
Label schoolnameL= new Label(SCHOOL+school_id);
schoolnameL.setId("schoolLabel");
Button exportDataSheetBtn= new Button("Export In File");
tableView.setMaxWidth(Region.USE_PREF_SIZE);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tableGrid.getChildren().addAll(schoolnameL,exportDataSheetBtn,tableView);
This can be done by binding the preferred height and width to the height and width of the primary stage. Here's an MCVE:
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class MCVE extends Application {
#Override
public void start(Stage stage) {
TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();
// We bind the prefHeight- and prefWidthProperty to the height and width of the stage.
table.prefHeightProperty().bind(stage.heightProperty());
table.prefWidthProperty().bind(stage.widthProperty());
stage.setScene(new Scene(table, 400, 400));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Create Tabel inside GridPane and Use GridePane inside AnchorPane.Click on GridPane(capture1).
Click on Ancho Pane Constraint inside the GridPane Layout (captur2).
In table view Layout select Hgrow and Vgrow as 'Always'(capture3)
VBox.setVgrow(tableView, Priority.ALWAYS);
OR for your parent layouts:
VBox.setVgrow({{PARENT}}, Priority.ALWAYS);
It fixed for me:
You could use a ScrollPane as the root of the scene and put everything else inside it. Then set the property setFitToWidth and setFitToHeight to true and all the content inside the ScrollPane will be stretched to fit the ScrollPane size and the ScrollPane will fit the Scene since its a Layout Pane. It will also show ScrollBars if the user resizes the window to be smaller than the contents minWidth, so the content doesnt get cut off!
#Override
public void start(Stage stage) {
TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();
table.setMinWidth(400);
ScrollPane sp = new ScrollPane(table);
sp.setFitToHeight(true);
sp.setFitToWidth(true);
stage.setScene(new Scene(table, 800, 600));
stage.show();
}
public static void main(String[] args) {
launch();
}
I copied parts of the MCVE From Jonathan's answer, hope you dont mind Jonathan :)
For more general tips for making resizable GUIs check this post!
I'm writing an application with JavaFX 2.2.7-b01.
Here is an example of the code I currently have. How can I allow the application window to be resized but maintain the aspect ratio it is initially configured with? In other words, if the user resizes the window, the window width should always stay double the window height.
...
public void showScene(Stage stage, String fxmlPath) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(fxmlPath);
Parent page;
try (InputStream in = Main.class.getResourceAsStream(fxmlPath)) {
page = (Parent) loader.load(in);
}
Scene scene = new Scene(page, 400, 200);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
} catch (Exception ex) {
...
}
}
...
It seems JavaFX allows a user to specify the width and height of a scene in the constructor but does not allow programmatic access to update the width or height. There are no setWidth or setHeight methods. I know I can add property listeners to get the read only width/height of the scene while it is being resized, but I haven't been able to figure out how to change the scene dimensions dynamically so I can force the aspect ratio to be maintained.
I imagine this would be possible if I were to subclass the Scene object (if I have to I will) but is there any other simple way to do this?
> How to make javafx.scene.Scene resize while maintaining an aspect ratio?
By manipulating the stage size instead of scene:
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Play by resizing the window");
VBox root = new VBox();
root.getChildren().add(btn);
root.setStyle("-fx-background-color: gray");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.minWidthProperty().bind(scene.heightProperty().multiply(2));
primaryStage.minHeightProperty().bind(scene.widthProperty().divide(2));
primaryStage.show();
}
Use removeListener and addListener when changing value to prevent listeners from chaining.
private ChangeListener<? super Number> widthChangeListener;
private ChangeListener<? super Number> heightChangeListener;
#Override
public void start(Stage stage) throws Exception {
widthChangeListener = (observable, oldValue, newValue) -> {
stage.heightProperty().removeListener(heightChangeListener);
stage.setHeight(newValue.doubleValue() / 2.0);
stage.heightProperty().addListener(heightChangeListener);
};
heightChangeListener = (observable, oldValue, newValue) -> {
stage.widthProperty().removeListener(widthChangeListener);
stage.setWidth(newValue.doubleValue() * 2.0);
stage.widthProperty().addListener(widthChangeListener);
};
stage.widthProperty().addListener(widthChangeListener);
stage.heightProperty().addListener(heightChangeListener);
}
In netbeans using Java Fx Scene Builder provide you can use AnchorPane Constraints to set
Resizing of stage.