Since I need to have multiple collapsible TitledPanes at once (which the default JavaFX Accordion does not support), I added some TitledPanes into a VBox. This works fine so far, but I realized that the width of the TitledPanes is 10px smaller than the width of the actual VBox.
Following FXML code:
<Pane prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.71" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox prefHeight="700.0" prefWidth="1000.0">
<children>
<TitledPane animated="false" text="Pane 1">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
<TitledPane animated="false" text="Pane 2">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
</children>
</VBox>
</children>
</Pane>
Which produces this (see the gap on the right):
After adding and adapting a css file, the layout looks like this:
The css code:
VBox {
-fx-padding: 0 -11 0 -1;
}
For me, this solution works fine, however it seems like a poor workaround. I guess there needs to be a smarter solution?!
Thanks a lot in advance :)
The pane is resized with the stage, but the width of the VBox does not exceed 1000px.
The width of the stage of your capture is approximately 1010px.
You should be able to dispense with the Pane:
<VBox xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TitledPane animated="false" text="Pane 1">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
<TitledPane animated="false" text="Pane 2">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
</children>
</VBox>
Or use AnchorPane to adjust the size of the vbox, if for some reason requires a panel above:
<AnchorPane xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<TitledPane animated="false" text="Pane 1">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
<TitledPane animated="false" text="Pane 2">
<content>
<AnchorPane prefHeight="300.0" />
</content>
</TitledPane>
</children>
</VBox>
</children>
</AnchorPane>
Thanks #geh:
Resizing the stage to the scene solved the problem without the need of a css adjustment:
#Override
public void start( Stage stage ) throws Exception {
Pane root = (Pane) FXMLLoader.load( getClass().getResource( "root.fxml" ) );
Scene scene = new Scene( root );
stage.setScene( scene );
stage.setResizable( false );
// the following solved it
stage.sizeToScene();
stage.setTitle( "JavaFx Test" );
stage.show();
}
Related
Ok, so I have an accordion which doesn't close properly when it's a child of a Tab Pane but works as expected outside it. I don't know where the problem stems from.
Also, I just found out that resizing the window causes the layout to display properly.
Is there a way to fix this?
Here is the FXML:
<AnchorPane maxWidth="350" minWidth="350.0" prefWidth="350.0">
<TabPane fx:id="tabPane" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0"
AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0">
<Tab text="Friends">
<AnchorPane>
<Accordion fx:id="accordion2" AnchorPane.bottomAnchor="45" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0"
AnchorPane.topAnchor="0" expandedPane="$friendsPane">
<panes>
<TitledPane fx:id="friendsPane" animated="false" styleClass="myClass" text="Friends">
<ScrollPane fitToWidth="true" hbarPolicy="NEVER" AnchorPane.bottomAnchor="0"
AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0"
AnchorPane.topAnchor="0">
<VBox fx:id="friends" fillWidth="true" styleClass="vbox">
<children>
</children>
</VBox>
</ScrollPane>
</TitledPane>
<TitledPane fx:id="groupsPane" animated="true" styleClass="myClass" text="Groups">
<ScrollPane fitToWidth="true" hbarPolicy="NEVER" AnchorPane.bottomAnchor="0"
AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0"
AnchorPane.topAnchor="0">
<VBox fx:id="groups" fillWidth="true" styleClass="vbox">
<children>
</children>
</VBox>
</ScrollPane>
</TitledPane>
</panes>
</Accordion>
<Button fx:id="activateCheck" mnemonicParsing="true" onAction="#activateCheck" text="New Group"
AnchorPane.bottomAnchor="10" AnchorPane.leftAnchor="10"/>
<Button fx:id="createGroup" mnemonicParsing="false" onAction="#createGroup" text="Create Group"
visible="false" AnchorPane.bottomAnchor="10" AnchorPane.leftAnchor="10"/>
</AnchorPane>
</Tab>
<Tab text="Received Requests">
<ScrollPane fitToWidth="true" hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0">
<VBox fx:id="requestsRecv" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0"
styleClass="vbox">
<children>
</children>
</VBox>
</ScrollPane>
</Tab>
<Tab text="Sent Requests">
<ScrollPane fitToWidth="true" hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0">
<VBox fx:id="requestsSent" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0"
styleClass="vbox">
<children>
</children>
</VBox>
</ScrollPane>
</Tab>
</TabPane>
</AnchorPane>
Here is what it looks like:
It was caused by a conflict between setting tab pane max and min width and having the controller set up a listener forcing the split pane that contained the tab pane divider to a set position.
I have a problem with my fxml interface.
When I try to reduce a specific part of my application, a grey area covers it.
An example in image will be more speaking:
I've tried quite a few things (by modifying parameters of the different components) but the white zone is still there.
Do you have any idea what my problem is?
The code (example):
MainApp.java
public class MainApp extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/test.fxml"));
AnchorPane root = (AnchorPane) loader.load();
Controller controller = loader.getController();
controller.setMainApp(this);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
Controller.java
public class Controller implements Initializable{
MainApp mainApp;
#FXML
Label label;
#Override
public void initialize(URL location, ResourceBundle resources) {
label.setText("Hello");
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
}
test.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane"
maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
minHeight="250.0" minWidth="400.0" prefHeight="519.0" prefWidth="921.0"
xmlns="http://javafx.com/javafx/8.0.111"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.view.Controller">
<children>
<SplitPane dividerPositions="0.49439102564102566"
maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
prefHeight="799.0" prefWidth="1250.0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="400.0" minWidth="400.0"
prefHeight="511.0" prefWidth="467.0" rotate="0.0" />
<AnchorPane minHeight="0.0" minWidth="0.0"
prefHeight="797.0" prefWidth="349.0">
<children>
<SplitPane layoutX="17.0" layoutY="7.0"
orientation="VERTICAL" prefHeight="797.0" prefWidth="346.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="108.0"
minWidth="447.0" prefHeight="108.0" prefWidth="447.0">
<children>
<SplitPane dividerPositions="0.5248796147672552"
maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="112.0" prefWidth="442.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="0.0"
minWidth="0.0" prefHeight="110.0" prefWidth="313.0" />
<AnchorPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="0.0"
minWidth="0.0" prefHeight="110.0" prefWidth="87.0">
<children>
<Label fx:id="label" layoutX="52.0" layoutY="223.0"
prefHeight="16.0" prefWidth="96.0" text="Test !">
<font>
<Font size="29.0" />
</font>
</Label>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
Note: I made this interface with the help of Gluon's SceneBuilder.
Thank you in advance.
In SceneBuilder if I click on the root SplitPane and slide it's divider to the right, I get this picture below. This means that at some point your min values on the highlighted AnchorPane is greater than it's parent's current width.
I basically set most of the later AnchorPanes' preferred width to USE_COMPUTER_SIZE and the highlighted AnchorPane's min width to USE_PRE_SIZE and it's preferred width to USE_COMPUTER_SIZE. Here is the code I used to fix the problem:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="250.0" minWidth="400.0" prefHeight="519.0" prefWidth="921.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.Controller">
<children>
<SplitPane dividerPositions="0.49836779107725787" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="799.0" prefWidth="1250.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="400.0" minWidth="400.0" prefHeight="511.0" prefWidth="467.0" rotate="0.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="797.0" prefWidth="349.0">
<children>
<SplitPane layoutX="17.0" layoutY="7.0" orientation="VERTICAL" prefHeight="797.0" prefWidth="346.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane>
<children>
<SplitPane dividerPositions="0.5248796147672552" minHeight="-Infinity" minWidth="-Infinity" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" />
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="110.0" prefWidth="87.0">
<children>
<Label fx:id="label" layoutX="52.0" layoutY="223.0" prefHeight="16.0" prefWidth="96.0" text="Test !">
<font>
<Font size="29.0" />
</font>
</Label>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
I'm trying to center a view on top of another view essentially in an anchor pane.
Here is my code:
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list" prefHeight="750.0" prefWidth="300.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<ProgressIndicator fx:id="bar" />
</children>
</AnchorPane>
This is what it looks like:
This is my goal:
EDIT:
Updated code to include a stackpane
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<StackPane prefHeight="150.0" prefWidth="200.0">
<children>
<ListView fx:id="list" />
<ProgressIndicator fx:id="bar" />
</children>
</StackPane>
</children>
</AnchorPane>
Try this:
The key to filling the StackPane is to set the ListView's maxHeight and maxWidth to Double.MAX_VALUE.
<children>
<StackPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ListView maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" />
<ProgressIndicator maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" progress="0.44">
<StackPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</StackPane.margin>
</ProgressIndicator>
</children>
</StackPane>
The prefHeight and prefWidth for the StackPane and ListView may not reflect what you have in your original post. You can change these values to suit your needs. I also set Constraints on the StackPane so that it fills its Parent AnchorPane.
SceneBuilder Images:
You may need to set the preferred side of ProgressIndicator
I have a VBox that is in a BorderPane (on the left side) so it is automatically sized to the full BorderPane height. I place a number of panels in this VBox, but they do not take up the full height, meaning that there is some empty space at the bottom. The BorderPane is in turn in a StackPane, so there are layers "underneath" it.
What I would like is for mouse-clicks in this empty space to be passed through to the pane underneath the BorderPane. Web searches have led me to believe that the correct way to do this is to make the VBox transparent, and set it to pickOnBounds="false".
I have tried to make the VBox transparent with both style="-fx-background-color: rgba(0,0,0,0);" and opacity="0", but neither produces the required effect — it seems that even when transparent with pickOnBounds="false", the VBox still consumes mouse events in its empty area and does not allow them to fall through to the next layer down in the StackPane.
The following FXML illustrates the problem. Two toggle buttons are on the bottom layer of a StackPane. On the left-hand side, the button is covered by a VBox, and it cannot be clicked. On the right-hand side, the button is covered by an AnchorPane, and it can be clicked.
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane fx:id="stackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane fx:id="anchorPane">
<children>
<ToggleButton mnemonicParsing="false" text="ToggleButton under VBox" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" />
<ToggleButton mnemonicParsing="false" text="ToggleButton under AnchorPane" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" />
</children>
</AnchorPane>
<BorderPane fx:id="borderPane" pickOnBounds="false" prefHeight="200.0" prefWidth="200.0">
<left>
<VBox fx:id="vBox" pickOnBounds="false" prefHeight="200.0" prefWidth="400.0" style="-fx-background-color: rgba(0,0,0,0);" BorderPane.alignment="CENTER">
<children>
<TitledPane animated="false" text="untitled">
<content>
<AnchorPane fx:id="pane1" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="400.0" />
</content>
</TitledPane>
<TitledPane animated="false" text="untitled">
<content>
<AnchorPane fx:id="pane2" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="400.0" />
</content>
</TitledPane>
</children>
</VBox>
</left>
<center>
<AnchorPane pickOnBounds="false" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
</children>
</StackPane>
Is there any workaround for this problem?
Write:
-fx-background-color: null;
Instead of:
-fx-background-color: rgba(0,0,0,0);
I do not know why setting the background to null and not transparent works in this case (as I expected that the transparent background would also work fine).
I apologize for perhaps lame question but I'm new to JavaFX and after reading 4 tutorials I can't find clear information how constraints work.
Can I set constraints to any control? Here is what I'm trying to achieve. I have VBox with ButtonBar of fixed height and I want second control to fill remaining area as I resize VBox.
<AnchorPane id="main-pane" style="-fx-border-color: #ADFF2F;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox prefHeight="300.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ButtonBar prefHeight="40.0" prefWidth="200.0">
<buttons>
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" text="Button" />
</buttons>
</ButtonBar>
<AnchorPane id="inner-pane" style="-fx-border-color: #FF0000;">
<children>
<ColorPicker prefHeight="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
</children>
</AnchorPane>
</children>
</VBox>
</children>
</AnchorPane>
Interestingly enough inner-pane widens as I resize the window but botton edge does not. How can I fix that ?
Considering you are using SceneBuilder, you can do the following :
Remove the anchorpane and make ColorPicker a child of VBox. Since anchorpane is not the perfect layout for what you are trying to achieve. It allows the edges of child nodes to be anchored to an offset from the anchor pane's edges, but has no property to enforce their growth when the same happens to it.
In the ColorPicker Layout properties set VBox.vgrow="ALWAYS" and Max Height and Max Width as MAX_VALUE.
FXML (Incase you don't use SB)
<AnchorPane id="main-pane" style="-fx-border-color: #ADFF2F;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox prefHeight="300.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ButtonBar prefHeight="40.0" prefWidth="200.0">
<buttons>
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" text="Button" />
</buttons>
</ButtonBar>
<ColorPicker prefHeight="200.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS" />
</children>
</VBox>
</children>
</AnchorPane>