Is there a way to make labels contained in an HBox ignore the graphic when aligned to baseline?
I'm trying to align the labels using their text. What I get instead is that the label with graphics is aligned with a vertical offset with regard to the other labels in a row:
<HBox alignment="BASELINE_LEFT" fillHeight="false">
<children>
<Button text="Button" />
<Label text="Label" />
<Button text="Button">
<font><Font size="12.0" /></font>
<graphic>
<Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="15.0" stroke="BLACK" strokeType="INSIDE" width="15.0" />
</graphic>
</Button>
</children>
</HBox>
Related
I have a program that will have a 2D section on the right, and a 3D section on the left. I use a GridPane to have all of the buttons and other stuff laid out, and then the 3D SubScene takes up the entire first column of the GridPane.
However, I am only able to set the size of the SubScene using hard-coded values, but I would like the SubScene to take up the entire width and height of the GridPane cells that it is inside of. Is there a way to do this?
Note: The GridPane's first column (where the subscene is) changes size when the window is resized, hence why I cannot just hard code the values.
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.SubScene?>
<?import javafx.scene.Group?>
<?import javafx.scene.shape.Box?>
<?import javafx.scene.PerspectiveCamera?>
<BorderPane fx:controller="Controller"
xmlns:fx="http://javafx.com/fxml" styleClass="root">
<top>
<MenuBar>
<menus>
<Menu text="File">
<items>
<MenuItem text="New"
onAction="#handleNewSimulationAction" />
<MenuItem text="Save"
onAction="#handleSaveSimulationAction" />
<MenuItem text="Load"
onAction="#handleLoadSimulationAction" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<GridPane hgap="10" vgap="10">
<rowConstraints>
<RowConstraints vgrow="NEVER" />
<RowConstraints vgrow="ALWAYS" />
</rowConstraints>
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<gridLinesVisible>true</gridLinesVisible>
<SubScene fx:id="subscene" width="50" height="50"
GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.rowSpan="6">
<root>
<Region />
</root>
</SubScene>
<Button text="Add" GridPane.columnIndex="1"
GridPane.rowIndex="0" onAction="#handleAddAction" />
<Button text="Edit" GridPane.columnIndex="2"
GridPane.rowIndex="0" onAction="#handleEditAction" />
<Button text="Delete" GridPane.columnIndex="3"
GridPane.rowIndex="0" onAction="#handleDeleteAction" />
<ScrollPane GridPane.columnIndex="1" GridPane.rowIndex="1"
GridPane.columnSpan="3" />
<Label text="Speed" GridPane.columnIndex="1"
GridPane.rowIndex="2" />
<Slider GridPane.columnIndex="2" GridPane.rowIndex="2"
GridPane.columnSpan="2" />
<Label text="Gravity" GridPane.columnIndex="1"
GridPane.rowIndex="3" />
<TextField GridPane.columnIndex="2" GridPane.rowIndex="3"
GridPane.columnSpan="2" />
<HBox GridPane.columnIndex="1" GridPane.rowIndex="4">
<Button text="<<" onAction="#handleQuickRewindAction" />
<Button text="<" onAction="#handleRewindAction" />
</HBox>
<Text text="0.00" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<HBox GridPane.columnIndex="3" GridPane.rowIndex="4">
<Button text=">" onAction="#handleFastForwardAction" />
<Button text=">>"
onAction="#handleQuickFastForwardAction" />
</HBox>
<Button text="Start" GridPane.columnIndex="2"
GridPane.rowIndex="5" onAction="#handlePauseAction" />
</GridPane>
</center>
<stylesheets>
<URL value="#style.css" />
</stylesheets>
</BorderPane>
The grey square in the image is the SubScene, with hard coded values so that it is visible. If values for the width and height are not hardcoded, it will simply not appear on the screen.
Firstly, there may be other ways as well, but this is my take on this issue :).
I would like to recommend you to rethink about the layout implementation. I think it would be better to keep the right side part in its own gridPane and you primarily deal with only 2 sections (center- subScene and right- form layout). That way you don't unneccesarily mess with layout by keeping too many eggs in one basket.
And regarding the SubScene, it does not fit in any of the standard layouts behavior (like no min/pref/max sizes). It pretty much has the same features as Shape, where you need to explicity set the width/height when required.
So for that, you need to do some explicit calculations to determine the width/height of the SubScene whenever the main scene size is changed.
Below is the quick demo for changes to your code: (If your window is a TRANSPARENT stage, then in the calculations, you may need to consider the window header size as well)
FXML Code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.SubScene?>
<?import javafx.scene.text.Text?>
<?import javafx.geometry.Insets?>
<BorderPane fx:id="mainLayout" fx:controller="Controller" xmlns:fx="http://javafx.com/fxml"
styleClass="root">
<top>
<MenuBar fx:id="menuBar">
<menus>
<Menu text="File">
<items>
<MenuItem text="New"
onAction="#handleNewSimulationAction"/>
<MenuItem text="Save"
onAction="#handleSaveSimulationAction"/>
<MenuItem text="Load"
onAction="#handleLoadSimulationAction"/>
</items>
</Menu>
</menus>
</MenuBar>
</top>
<right>
<GridPane fx:id="sideLayout" hgap="10" vgap="10">
<rowConstraints>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="ALWAYS"/>
</rowConstraints>
<gridLinesVisible>true</gridLinesVisible>
<padding>
<Insets left="10"/>
</padding>
<Button text="Add" GridPane.columnIndex="0" GridPane.rowIndex="0" onAction="#handleAddAction"
prefWidth="-1" minWidth="-Infinity"/>
<Button text="Edit" GridPane.columnIndex="1" GridPane.rowIndex="0"
onAction="#handleEditAction" prefWidth="-1" minWidth="-Infinity"/>
<Button text="Delete" GridPane.columnIndex="2" GridPane.rowIndex="0"
onAction="#handleDeleteAction" prefWidth="-1" minWidth="-Infinity"/>
<ScrollPane GridPane.columnIndex="0" GridPane.rowIndex="1" GridPane.columnSpan="3"/>
<Label text="Speed" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
<StackPane GridPane.columnIndex="1" GridPane.rowIndex="2" GridPane.columnSpan="2"/>
<Label text="Gravity" GridPane.columnIndex="0" GridPane.rowIndex="3"/>
<StackPane GridPane.columnIndex="1" GridPane.rowIndex="3" GridPane.columnSpan="2"/>
<HBox GridPane.columnIndex="0" GridPane.rowIndex="4">
<Button text="<<" onAction="#handleQuickRewindAction" prefWidth="-1"
minWidth="-Infinity"/>
<Button text="<" onAction="#handleRewindAction" prefWidth="-1" minWidth="-Infinity"/>
</HBox>
<Text text="0.00" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<HBox GridPane.columnIndex="2" GridPane.rowIndex="4">
<Button text=">" onAction="#handleFastForwardAction" prefWidth="-1"
minWidth="-Infinity"/>
<Button text=">>"
onAction="#handleQuickFastForwardAction" prefWidth="-1" minWidth="-Infinity"/>
</HBox>
<Button text="Start" GridPane.columnIndex="1" GridPane.rowIndex="5"
onAction="#handlePauseAction" prefWidth="-1" minWidth="-Infinity"/>
</GridPane>
</right>
<center>
<SubScene fx:id="subscene">
<root>
<StackPane style="-fx-background-color:yellow;-fx-border-width:1px;-fx-border-color:red;">
<Label text="Sub Scene" style="-fx-font-size:16px;"/>
</StackPane>
</root>
</SubScene>
</center>
</BorderPane>
Controller code:
#FXML
private MenuBar menuBar;
#FXML
private SubScene subscene;
#FXML
private GridPane sideLayout;
#FXML
public void initialize() {
subscene.sceneProperty().addListener((ob, ol, scene) -> {
scene.heightProperty().addListener((obs, old, height) -> updateHeight());
scene.widthProperty().addListener((obs, old, width) -> updateWidth());
});
sideLayout.heightProperty().addListener((obs, old, height) -> updateHeight());
sideLayout.widthProperty().addListener((obs, old, width) -> updateWidth());
}
private void updateHeight() {
double sceneHeight = subscene.getScene().getHeight();
subscene.setHeight(sceneHeight - menuBar.getHeight());
}
private void updateWidth() {
double sceneWidth = subscene.getScene().getWidth();
subscene.setWidth(sceneWidth - sideLayout.getWidth());
}
I'm designing a dashboard in JavaFX FXML. Here is a screenshot of the dashboard:
Here is FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.farhad.controllers.DashboardMenuController"
spacing="50.0"
id="dashboard-menu"
stylesheets="#../style/dashboard.css">
<HBox alignment="CENTER" spacing="5.0">
<ImageView>
<Image url="#../icons/user.png" />
</ImageView>
<VBox spacing="5.0" alignment="CENTER_LEFT">
<Label id="user-full-name" text="User full name"/>
<Label id="user-login-name" text="User login name"/>
</VBox>
</HBox>
<Separator />
<!-- About User -->
<VBox spacing="20.0">
<HBox>
<ImageView>
<Image url="#../icons/overview.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Overview"/>
<Separator orientation="VERTICAL"/>
</HBox>
<HBox>
<ImageView>
<Image url="#../icons/accounts.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Accounts" />
<Separator orientation="VERTICAL"/>
</HBox>
<HBox>
<ImageView>
<Image url="#../icons/transaction.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Transactions"/>
<Separator orientation="VERTICAL"/>
</HBox>
<HBox>
<ImageView>
<Image url="#../icons/products.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Your Products"/>
<Separator orientation="VERTICAL"/>
</HBox>
</VBox>
<Separator />
<!-- Settings -->
<VBox spacing="20.0">
<HBox>
<ImageView>
<Image url="#../icons/add-account.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Add New Account" />
<Separator orientation="VERTICAL"/>
</HBox>
<HBox>
<ImageView>
<Image url="#../icons/merchant.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Be Merchant"/>
<Separator orientation="VERTICAL"/>
</HBox>
<HBox>
<ImageView>
<Image url="#../icons/settings.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="User Settings" />
<Separator orientation="VERTICAL" />
</HBox>
</VBox>
<!-- Logout -->
<VBox alignment="BOTTOM_CENTER">
<HBox >
<ImageView>
<Image url="#../icons/logout.png" />
</ImageView>
<Label styleClass="dashboard-menu-item-label" text="Logout" />
<Separator orientation="VERTICAL" />
</HBox>
</VBox>
</VBox>
My problem is in the Logout label and a little white vertical separator in each menu item. I want to place the Logout label at the bottom of Parent VBOX and a little white vertical separator to the left of HBOX as other apps.
How can I modify the code so my dashboard looks like this:
Suppose that this dashboard has a Logout label at the bottom of the VBox
i use scene builder to build a gui for my app and i have this problem:
When stage screen is set to Maximized , AnchorPane is set top left corner and all it's contents inside(VBox etc). i want to cover the full screen or at least be at the center. Im not too familiar with anchorPane alignment and positioning but wit borderpane i didn't have that problem. So here is how my screen looks :
So the anchorpane just is being placed always top left like this.
Here is my fxml code:
<AnchorPane prefHeight="394.0" prefWidth="586.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gr.hua.dit.oop2.gui.Controller2">
<children>
<VBox layoutY="29.0" prefHeight="116.0" prefWidth="344.0" spacing="30.0">
<children>
<TextField fx:id="name" alignment="TOP_CENTER" promptText="Enter your full name" />
<TextField fx:id="age" alignment="BASELINE_CENTER" promptText="Enter your age" />
</children>
</VBox>
<VBox layoutX="425.0" layoutY="54.0" prefHeight="300.0" prefWidth="161.0" spacing="10.0">
<children>
<Label alignment="CENTER_RIGHT" text="Tell us your interests" />
<CheckBox fx:id="museum" layoutX="10.0" layoutY="36.0" mnemonicParsing="false" text="Museums" />
<CheckBox fx:id="sights" layoutX="10.0" layoutY="62.0" mnemonicParsing="false" text="Historical Sights" />
<CheckBox fx:id="night" layoutX="10.0" layoutY="88.0" mnemonicParsing="false" text="Night Life" />
<CheckBox fx:id="forest" layoutX="10.0" layoutY="114.0" mnemonicParsing="false" text="Forests" />
<CheckBox fx:id="lake" mnemonicParsing="false" text="Lakes" />
<CheckBox fx:id="zoo" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" text="Zoo" />
<CheckBox fx:id="sea" layoutX="10.0" layoutY="218.0" mnemonicParsing="false" text="Sea - Beach" />
<CheckBox fx:id="mountain" layoutX="10.0" layoutY="254.0" mnemonicParsing="false" text="Mountains" />
</children>
</VBox>
<Button fx:id="submit" alignment="BOTTOM_CENTER" layoutX="269.0" layoutY="360.0" mnemonicParsing="false" text="Proposal">
<font>
<Font size="15.0" />
</font>
</Button>
<VBox layoutX="10.0" layoutY="174.0" prefHeight="161.0" prefWidth="375.0">
<children>
<TextField fx:id="cities" alignment="CENTER" prefHeight="36.0" prefWidth="334.0" promptText="Enter up to 5 Desired Cities you want to Visit">
<font>
<Font size="10.0" />
</font>
</TextField>
<Label alignment="CENTER" contentDisplay="TOP" prefHeight="18.0" prefWidth="377.0" text="e.g. "Athens gr,Berlin de,New York us" />
</children>
</VBox>
</children>
</AnchorPane>
So I have a stylesheet with just one style within at the moment for testing purposes.
CSS code:
.minimizeBtn{
-fx-background-color: rgba(0,0,0,1);
}
Setting the ID of the button. This is in the controller for the stage.
public void initialize(URL url, ResourceBundle rb) {
handler = new DbHandlers();
minimizeBtn1.setId("minimizeBtn");
My buttons in fxml:
<Button fx:id="minimizeBtn1" layoutX="520.0" mnemonicParsing="false"
prefHeight="25.0" prefWidth="12.0" styleClass="minimizeBtn" text="Button" />
<Button layoutX="548.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0" styleClass="maximizeBtn" text="Button" />
<Button layoutX="574.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0" styleClass="closeBtn" text="Button" />
The rest of my fxml file:
<AnchorPane prefHeight="450.0" prefWidth="600.0" style="-fx-background-color: #2A7FFF;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="bownhrmain1.pages.LoginScreenController">
<children>
<AnchorPane prefHeight="450.0" prefWidth="600.0" style="-fx-background-color: #2A7FFF;">
<children>
<Label layoutX="335.0" layoutY="144.0" text="Inventory Systems" textFill="WHITE">
<font>
<Font size="8.0" />
</font>
</Label>
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="200.0" layoutY="65.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../images/benx_logo.png" />
</image>
</ImageView>
<Hyperlink layoutX="250.0" layoutY="368.0" text="Forgot Password?" textFill="WHITE" underline="true" />
<JFXButton fx:id="loginBtn" buttonType="RAISED" layoutX="190.0" layoutY="302.0" prefHeight="51.0" prefWidth="221.0" ripplerFill="#2980b9" style="-fx-background-color: #1E5D87;" text="Login" textFill="WHITE" />
<JFXPasswordField fx:id="passwordField" focusColor="#1e5d87" labelFloat="true" layoutX="190.0" layoutY="237.0" prefHeight="34.0" prefWidth="221.0" promptText="Password..." unFocusColor="WHITE" />
<JFXTextField id="text-field" fx:id="usernameField" focusColor="#1e5d87" labelFloat="true" layoutX="190.0" layoutY="176.0" prefHeight="32.0" prefWidth="221.0" promptText="Username/Email..." unFocusColor="WHITE" />
<ImageView fitHeight="20.0" fitWidth="19.0" layoutX="522.0" layoutY="5.0" pickOnBounds="true">
<image>
<Image url="#../images/minimize.png" />
</image>
</ImageView>
<ImageView fitHeight="11.0" fitWidth="12.0" layoutX="554.0" layoutY="9.0" pickOnBounds="true">
<image>
<Image url="#../images/expand-button.png" />
</image>
</ImageView>
<ImageView fitHeight="11.0" fitWidth="11.0" layoutX="581.0" layoutY="9.0" pickOnBounds="true">
<image>
<Image url="#../images/closeWindow.png" />
</image>
</ImageView>
<Button fx:id="minimizeBtn1" layoutX="520.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0" styleClass="minimizeBtn" text="Button" />
<Button layoutX="548.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0" styleClass="maximizeBtn" text="Button" />
<Button layoutX="574.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0" styleClass="closeBtn" text="Button" />
</children>
</AnchorPane>
</children>
</AnchorPane>
The reason i have the styleclass on the buttons is because I have tried both setting the css through class name and ID.
Here's an image of the css working in JavaFx scene builder:
CSS Applying in scene builder.
Here's an imagee of it failing to apply when you run the program:
Not applying
So the answer to this question is to add the following to your start function:
scene.getStylesheets().add(getClass().getResource("pathtostylesheet").toExternalForm());
For some reason both my panes: gas-pumps-header and coffee-house-header won't stretch on window re-size. I'm using JavaFX Scene Builder, and I'm new to JavaFX (in case the answer is pretty basic...)
I want the panes to stretch to the sides (left and right), and fill the entire width of the window.
Here's my FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<AnchorPane prefHeight="768.0" prefWidth="1024.0" xmlns:fx="http://javafx.com/fxml">
<children>
<HBox id="action-buttons-section" alignment="CENTER_LEFT" layoutY="14.0" spacing="5.0"
AnchorPane.leftAnchor="14.0">
<children>
<Button mnemonicParsing="false" text="Add Customer" />
<Button mnemonicParsing="false" text="Move Customer" />
</children>
</HBox>
<HBox id="fuel-pool-section" alignment="CENTER_LEFT" layoutY="14.0" spacing="5.0" AnchorPane.rightAnchor="16.0">
<children>
<Label text="Main Fuel Pool" />
<ProgressBar prefHeight="20.0" prefWidth="200.0" progress="0.0" />
<Button mnemonicParsing="false" text="Fill" />
</children>
</HBox>
<VBox alignment="CENTER" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="44.0">
<children>
<VBox alignment="CENTER" spacing="5.0">
<children>
<Pane id="gas-pumps-header" prefHeight="100.0" prefWidth="996.0"> <!-- first one -->
<children>
<Label layoutX="14.0" layoutY="15.0" text="Gas Pumps">
<font>
<Font name="System Bold" size="16.0" fx:id="x2" />
</font>
</Label>
<HBox id="gas-pumps-income-section" alignment="CENTER_RIGHT" layoutX="893.0" layoutY="15.0" spacing="5.0">
<children>
<Label text="Income">
<font>
<Font size="14.0" fx:id="x1" />
</font>
</Label>
<Label fx:id="gasPumpsIncomeValue" font="$x1" text="Value" />
</children>
</HBox>
</children>
</Pane>
<HBox id="gas-pumps-section" prefHeight="378.0" prefWidth="996.0" styleClass="layout" VBox.vgrow="ALWAYS">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" fx:id="x3" />
</padding>
</HBox>
</children>
</VBox>
<VBox alignment="CENTER" spacing="5.0">
<children>
<Pane id="coffee-house-header" prefHeight="100.0" prefWidth="996.0"> <!-- second one -->
<children>
<Label font="$x2" layoutX="14.0" layoutY="15.0" text="Coffee House" />
<HBox id="coffee-house-income-section" alignment="CENTER_RIGHT" layoutX="893.0" layoutY="15.0" spacing="5.0">
<children>
<Label font="$x1" text="Income" />
<Label fx:id="coffeeHouseIncomeValue" font="$x1" text="Value" />
</children>
</HBox>
</children>
</Pane>
<HBox id="coffee-house-section" padding="$x3" prefHeight="378.0" prefWidth="996.0" styleClass="layout" VBox.vgrow="ALWAYS" />
</children>
</VBox>
</children>
</VBox>
</children>
<stylesheets>
<URL value="#style.css" />
</stylesheets>
</AnchorPane>
After playing with different kinds of Panes I managed to get it to work.
I used a BorderPane and added the child nodes to the left and right of the BorderPane. Now when I re-size the window every element gets re-positioned to its relative position in the starting layout.
Here is the BorderPane part
<BorderPane id="gas-pumps-header" VBox.vgrow="SOMETIMES">
<left>
<Label text="Gas Pumps" BorderPane.alignment="CENTER_LEFT">
<font>
<Font name="System Bold" size="16.0" fx:id="x2" />
</font>
</Label>
</left>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" fx:id="x3" />
</padding>
<right>
<HBox id="gas-pumps-income-section" alignment="CENTER_RIGHT" spacing="5.0" BorderPane.alignment="CENTER_RIGHT">
<children>
<Label text="Income">
<font>
<Font size="14.0" fx:id="x1" />
</font>
</Label>
<Label fx:id="gasPumpsIncomeValue" font="$x1" text="Value" />
</children>
</HBox>
</right>
</BorderPane>
gas-pumps-header already resizes automatically as the application window size changes.
Open your fxml file in SceneBuilder (I used 1.1-b28 on win7), click on the gas-pumps-header pane in the SceneBuilder Hierarchy pane, set the style to -fx-border-color: red; choose SceneBuilder menu item Preview | Show Preview and Window and resize the preview window, you will see the red border of the gas-pumps-header change size as you resize the preview window.
I'm pretty sure the above doesn't help you that much as you probably have some issue with the layout which I can't understand from your question.
In general, I'd recommend using an appropriate subclass of Pane rather than Pane for most layouts as Pane subclasses will do more work for layout work you. Perhaps in your case a HBox would be more appropriate.