I need some help. How do you center a text in HBox. I am using SceneBuilder. I try and I can't figure it out how to do it.
Here is the code for FXML.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.geometry.Point3D?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Text?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
<top>
<HBox prefHeight="50.0" prefWidth="800.0" BorderPane.alignment="CENTER">
<children>
<Text boundsType="LOGICAL_VERTICAL_CENTER" layoutX="600.0" layoutY="600.0" scaleZ="0.0" strokeType="OUTSIDE" strokeWidth="0.0" text="GIANTS DATABASE" textAlignment="CENTER" textOrigin="CENTER" wrappingWidth="231.7841796875" x="600.0" y="600.0">
<rotationAxis>
<Point3D x="1.0" y="1.0" z="1.0" />
</rotationAxis>
</Text>
</children></HBox>
</top>
<right>
<TableView prefHeight="550.0" prefWidth="577.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn minWidth="0.0" prefWidth="72.0" text="Rank" />
<TableColumn editable="false" minWidth="0.0" prefWidth="206.0" text="Name" />
<TableColumn editable="false" minWidth="0.0" prefWidth="88.0" text="Position" />
<TableColumn minWidth="0.0" prefWidth="77.0" text="School" />
<TableColumn minWidth="0.0" prefWidth="66.0" text="Age" />
<TableColumn minWidth="0.0" prefWidth="66.0" text="War" />
</columns>
</TableView>
</right>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets bottom="3.0" right="3.0" />
</padding>
The text I want to center is GIANTS DATABASE, under HBox children
Here is the code for javaFX
public class Login extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/giants/LoginF.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Giants Database Login");
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e) {
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Here is the image of the text *GIANTS DATABASE. And I want to center the text where the arrow is pointing**
Remove the bounds, layoutX/Y and rotation settings on the Text node - they are not needed for this. What you are looking for is the HBox alignment property - setting it to Pos.CENTER will layout the children of the HBox in the center both vertically and horizontally. If you want to keep it to the left use Pos.CENTER_LEFT.
It is also not clear from your question whether you wish for the HBox to be this tall - it may be helpful to change the prefHeight of the HBox to Region.USE_COMPUTED_SIZE to have it match the size of the Text note (plus any padding/margins set on either of them).
Related
I want my Chat Window to be reziable and scrollable, so far everything works except the ChatLog itself.
I need a scroll bar, that's why I put the VBox inside of a ScrollPane (which is child of an AnchorPane), but this way only the ScrollPane is responsive (thanks to Anchor Values). If I unwrap VBox I can set Anchor Values, then it works but I'm loosing my scroll bar.
How can I mantain the scroll bar for ChatLog AND make it responsive (attached on the right side)?
FXML:
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-background-color: #5b2529;" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.lmu.jungejunkervp.ClientWindowController">
<children>
<ScrollPane fx:id="scrollPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="265.0" prefWidth="592.0" AnchorPane.bottomAnchor="57.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<content>
<VBox fx:id="chatLog" prefHeight="265.0" prefWidth="575.0" />
</content></ScrollPane>
<TextArea fx:id="messageBox" layoutX="5.0" layoutY="349.0" onKeyPressed="#onEnterSend" prefHeight="47.0" prefWidth="536.0" promptText="enter message..." AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="61.0" />
<Button fx:id="sendButton" mnemonicParsing="false" onAction="#setSendButtonAction" onMouseClicked="#setSendButtonAction" prefHeight="47.0" prefWidth="52.0" text="Send" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" />
</children>
</AnchorPane>
public void addLabel(String message, Pos position) {
HBox hBox = new HBox();
hBox.setAlignment(position);
hBox.setPadding(new Insets(5, 5, 5, 10));
Text text = new Text(message);
TextFlow textFlow = new TextFlow(text);
textFlow.setStyle("-fx-background-color: rgb(233,233,235);" +
"-fx-background-radius: 20px");
textFlow.setPadding(new Insets(5, 10, 5, 10));
hBox.getChildren().add(textFlow);
Platform.runLater(new Runnable() {
#Override
public void run() {
chatLog.getChildren().add(hBox);
}
});
}
public void setSendButtonAction() {
String message = messageBox.getText().replaceAll("[\n\r]", "");
try {
if (!message.isEmpty()) {
// show message on the sending client window
addLabel(message, Pos.CENTER_RIGHT);
}
}
To answer your actual question, below is what you need add to the ScrollPane (in fxml with your current layout).
fitToHeight="true" fitToWidth="true"
The above code will make your VBox responsive with the ScrollPane.
I also suggest to change your layout to get rid of AnchorPane (will all those hardcoded positions). You can use VBox/HBox in conjuction with vgrow/hgrow policies. The optimized fxml will be as below:
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.geometry.Insets?>
<VBox style="-fx-background-color: #5b2529;" spacing="5" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.lmu.jungejunkervp.ClientWindowController">
<children>
<ScrollPane fx:id="scrollPane" prefHeight="265.0" prefWidth="592.0" fitToHeight="true" fitToWidth="true" VBox.vgrow="ALWAYS">
<content>
<VBox fx:id="chatLog"/>
</content>
</ScrollPane>
<HBox spacing="5">
<TextArea fx:id="messageBox" onKeyPressed="#onEnterSend" prefHeight="47.0" promptText="enter message..." HBox.hgrow="ALWAYS" />
<Button fx:id="sendButton" mnemonicParsing="false" onAction="#setSendButtonAction" prefHeight="47.0" minWidth="52.0" text="Send"/>
</HBox>
</children>
<padding>
<Insets topRightBottomLeft="5"/>
</padding>
</VBox>
Having said that, I think you need to consider changing your layout to what #jewelsea mentioned in the provided example (using ListView).
This question already has an answer here:
javaFX program not working after changing the scene builder and jdk
(1 answer)
Closed 4 months ago.
I am new to javafx.Currently I am developing a miniproject.I am designing it's UI in scene builder-18.0.0.
I have added fontawesomefx jar file to reference library.
When I use fontawesomefx icons to my project, it's shows the following Exception.If I remove the icons, the program runs fine.
Result
Exception in Application start method
java.lang.reflect.InvocationTargetExceptionf
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
at javafx.graphics#18.0.2/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
at javafx.graphics#18.0.2/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1081)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics#18.0.2/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901)
at javafx.graphics#18.0.2/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoClassDefFoundError: com/sun/javafx/css/parser/CSSParser
at de.jensd.fx.glyphs.GlyphIcon.<clinit>(GlyphIcon.java:49)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:236)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:546)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:496)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1020)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml#18.0.2/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2516)
at App.start(App.java:19)
at javafx.graphics#18.0.2/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at javafx.graphics#18.0.2/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics#18.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics#18.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at javafx.graphics#18.0.2/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics#18.0.2/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics#18.0.2/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.javafx.css.parser.CSSParser
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 25 more
Exception running application App
My Fxml code
<?xml version="1.0" encoding="UTF-8"?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="609.0" prefWidth="932.0" styleClass="holder" stylesheets="#TableStyle.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Pane layoutY="7.0" prefHeight="28.0" prefWidth="932.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Label layoutX="17.75" layoutY="3.0" styleClass="app-title" text="Hello Tables" textFill="WHITE">
<font>
<Font size="15.0" />
</font>
</Label>
</children>
</Pane>
<AnchorPane layoutX="14.0" layoutY="28.0" prefHeight="200.0" prefWidth="256.0" styleClass="sideview" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="7.0" AnchorPane.topAnchor="28.0">
<children>
<StackPane alignment="CENTER_RIGHT" layoutX="17.0" layoutY="48.0" AnchorPane.leftAnchor="35.6" AnchorPane.topAnchor="45.0">
<children>
<TextField promptText="Search here" styleClass="txt-field" />
</children>
</StackPane>
<ListView layoutX="28.0" layoutY="131.0" prefHeight="200.0" prefWidth="200.0" styleClass="listview" AnchorPane.bottomAnchor="110.0" AnchorPane.topAnchor="125.0" />
<StackPane layoutX="17.0" layoutY="514.0" prefHeight="30.0" prefWidth="222.0" AnchorPane.bottomAnchor="29.600000000000023">
<children>
<Button maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="145.0" styleClass="btn-new-table" />
<Label styleClass="txt-new-table" text="NEW TABLE" />
</children>
</StackPane>
<FontAwesomeIconView layoutX="111.0" layoutY="293.0" />
</children>
</AnchorPane>
<AnchorPane layoutX="316.0" layoutY="38.0" prefHeight="200.0" prefWidth="200.0" styleClass="sideview" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="267.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="28.0">
<children>
<Label layoutX="27.0" layoutY="69.0" text="NOTES" AnchorPane.leftAnchor="27.0" AnchorPane.topAnchor="69.0">
<font>
<Font name="System Bold" size="21.0" />
</font>
</Label>
<StackPane layoutX="27.0" layoutY="126.0" prefHeight="353.0" prefWidth="611.0" AnchorPane.bottomAnchor="96.0" AnchorPane.leftAnchor="27.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="125.0">
<children>
<Label alignment="TOP_LEFT" prefHeight="75.0" prefWidth="214.0" styleClass="txt-no-table" text="NO TABLE SELECTED" textAlignment="CENTER" StackPane.alignment="CENTER">
<font>
<Font name="Roboto" size="16.799999237060547" />
</font>
</Label>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Pane layoutY="41.0" prefHeight="200.0" prefWidth="200.0" styleClass="table-holder" AnchorPane.bottomAnchor="25.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="106.5" AnchorPane.topAnchor="2.0" />
<TableView prefHeight="353.0" prefWidth="503.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="95.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="75.0" text="NAME" />
<TableColumn prefWidth="75.0" text="AGE" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<VBox alignment="CENTER" layoutX="556.0" layoutY="27.0" prefHeight="327.0" prefWidth="48.0" AnchorPane.bottomAnchor="27.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0">
<children>
<FlowPane alignment="CENTER" orientation="VERTICAL" prefHeight="315.0" prefWidth="55.0" styleClass="toolbar" />
</children>
</VBox>
</children>
</AnchorPane>
</children></StackPane>
<FlowPane alignment="CENTER_LEFT" hgap="10.0" layoutX="27.0" layoutY="432.0" prefHeight="102.0" prefWidth="490.0" vgap="10.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="27.0" AnchorPane.rightAnchor="141.0">
<children>
<TextField promptText="Search here" styleClass="txt-field" />
</children>
</FlowPane>
<StackPane layoutX="422.0" layoutY="499.0" maxHeight="-Infinity" prefHeight="30.0" prefWidth="153.0" AnchorPane.bottomAnchor="30.0" AnchorPane.rightAnchor="120.0">
<children>
<Button maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="131.0" styleClass="btn-new-table" />
<Label styleClass="txt-new-table" text="ADD ROW" />
</children>
</StackPane>
</children>
</AnchorPane>
</children>
</AnchorPane>
Java(Main class)
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class App extends Application{
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("TableAppInterface.fxml"));
System.out.println("hi");
Parent root = null;
try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(root);
stage.setScene(scene);
//stage.initStyle(StageStyle.TRANSPARENT);
stage.setTitle("Tables");
stage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Launch Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "Launch App",
"request": "launch",
"mainClass": "App",
"projectName": "TableApp_e71931e0",
"vmArgs": "--module-path \"C:/Program Files/Java/javafx-sdk-18.0.2/lib\" --add-modules javafx.controls,javafx.fxml"
}
]
}
I also tried with the following vmArgs
"vmArgs": "--module-path \"C:/Program Files/Java/javafx-sdk-18.0.2/lib\" --add-modules javafx.controls,javafx.fxml \ --add-opens javafx.graphics/javafx.css=ALL-UNNAMED"
I also visited this post and used fontawesomfx 8.4.but it didn't work.It shows the same exception.
Currently I am using java 18(jdk-18.0.2) and javafx-sdk-18.0.2 and SceneBuilder-18.0.0 and fontawesomefx 8.9 jar.I use visual studio code.I am not using any built tools for my project.
NOTE:If I run the code without any fontawesomefx icons, my code works fine.
I have been searching the solution for this problem for an entire day.Please explain me what is the problem and how to solve it.I want to use fontawesomeicons in my project.How to do it?
Thank you
You need to upgrade the version of fontawesomefx you are using to be compatible with your java version.
See the answer to this question, I believe your problem is the same as this person was seeing.
I'm finding the way that how to bind the size of a pane with the outer pane.
I could bind the size ofRectangle with Pane,
But couldn't bind an inner pane (Red dotted rectangle) with outer pane (Blue dotted rectangle)
Why I couldn't do it
It seems to be that Pane does not provide bind method for widthProperty
Objects
At least, bind width with TextArea of inner Pane with outer Pane
I'll make many new tabs, therefore, I prefer to bind inner Pane with outer Pane rather than bind TextArea directly to outer Pane.
Situation
Blue and Orange rectangles are bound well with pane dropPane
But Blue border pane's width should be the same size as a red border pane!
My Sources
main.kt:
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.*
import javafx.scene.control.*
import javafx.scene.paint.Paint
import javafx.scene.shape.Rectangle
import javafx.stage.Stage
import javafx.scene.layout.*
import javafx.scene.paint.*
fun main(args : Array<String>) {
println("EntryPoint")
Application.launch(PaneBindingTest().javaClass, *args)
}
class PaneBindingTest : Application() {
private var tabCount = 0
private fun generateNewTab (): Tab {
val tab = Tab()
tabCount += 1
tab.text = "Tab$tabCount"
val fxml = javaClass.getResource("fxml/Tab.fxml")
val aTabPane: Pane = FXMLLoader.load(fxml)
aTabPane.border = Border(BorderStroke(Paint.valueOf("Red"),BorderStrokeStyle.DASHED, CornerRadii.EMPTY, BorderWidths.DEFAULT))
tab.content = aTabPane
return tab
}
override fun start(primaryStage: Stage) {
primaryStage.title = "EntryPoint"
primaryStage.isAlwaysOnTop = true
val fxml = javaClass.getResource("fxml/EntryPoint.fxml")
val root: Parent = FXMLLoader.load(fxml)
val scene = Scene(root)
val epPane= root.lookup("#EPPane") as AnchorPane // Entry Point Pane
val dropPane= root.lookup("#DropPane") as AnchorPane // Drop Pane
val tabPane= root.lookup("#TabPane") as TabPane // Tab Pane
val singleDropPoint= root.lookup("#ForSingle") as Rectangle // Single-ArchiveSet drop point
val multiDropPoint = root.lookup("#ForMulti") as Rectangle // Multi-ArchiveSet drop point
//epPane.background = Background(BackgroundFill(Paint.valueOf("Yellow"), CornerRadii(0.0), Insets(0.0,0.0,0.0,0.0)))
//dropPane.background = Background(BackgroundFill(Paint.valueOf("Green"), CornerRadii(0.0), Insets(0.0,0.0,0.0,0.0)))
tabPane.tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS // or SELECTED_TAB, UNAVAILABLE
tabPane.border = Border(BorderStroke(Paint.valueOf("Blue"),BorderStrokeStyle.DASHED, CornerRadii.EMPTY, BorderWidths.DEFAULT))
singleDropPoint.heightProperty().bind(epPane.heightProperty().divide(32).multiply(23))
multiDropPoint.yProperty().bind(singleDropPoint.yProperty().add(dropPane.heightProperty().divide(4).multiply(3)))
multiDropPoint.heightProperty().bind(epPane.heightProperty().divide(4))
primaryStage.scene = scene
primaryStage.show()
val newTab = generateNewTab()
tabPane.tabs.add(newTab)
tabPane.selectionModel.select(newTab)
}
}
fxml/EntryPoint.fxml
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Rectangle?>
<AnchorPane fx:id="EPPane" prefHeight="640.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TabPane fx:id="TabPane" prefHeight="640.0" prefWidth="1152.0" tabClosingPolicy="ALL_TABS" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="128.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
</TabPane>
<AnchorPane fx:id="DropPane" layoutY="128.0" maxWidth="128.0" minWidth="128.0" prefWidth="128.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Rectangle fx:id="ForSingle" arcHeight="16.0" arcWidth="16.0" fill="DODGERBLUE" height="360.0" width="120.0" stroke="#1100ff" strokeType="INSIDE" strokeWidth="8.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.topAnchor="4.0"/>
<Rectangle fx:id="ForMulti" arcHeight="16.0" arcWidth="16.0" fill="#ff9d1f" height="240.0" width="120.0" stroke="#ff8800" strokeType="INSIDE" strokeWidth="8.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.bottomAnchor="4.0"/>
</children>
</AnchorPane>
</children>
</AnchorPane>
fxml/Tab.fxml:
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextArea fx:id="FilePaths" layoutX="4.0" layoutY="80.0" prefHeight="128.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.topAnchor="72.0" />
<RadioButton layoutX="14.0" layoutY="206.0" mnemonicParsing="false" selected="true" text="Hash/Size only">
<toggleGroup>
<ToggleGroup fx:id="AnalyzeMethod" />
</toggleGroup>
</RadioButton>
<RadioButton layoutX="120.0" layoutY="206.0" mnemonicParsing="false" text="FileName" toggleGroup="$AnalyzeMethod" />
<RadioButton layoutX="200.0" layoutY="206.0" mnemonicParsing="false" text="Directory Structure" toggleGroup="$AnalyzeMethod" />
<CheckBox fx:id="CheckDiff" layoutX="336.0" layoutY="206.0" mnemonicParsing="false" text="Show Diff" />
<CheckBox fx:id="CheckSame" layoutX="420.0" layoutY="206.0" mnemonicParsing="false" text="Show Same" />
<ComboBox fx:id="ComboBox" layoutX="840.0" layoutY="202.0" prefWidth="150.0" />
<HBox fx:id="LabelBox" layoutX="12.0" layoutY="14.0" prefHeight="64.0" prefWidth="978.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.topAnchor="4.0" />
</children>
</AnchorPane>
I've found that almost the same question, but no answer was there.
You do not need a binding to achieve this. The problem is the fact that you set the constraints for maxHeight/maxWidth to USE_PREF_SIZE, i.e. to a fixed value that can very well be reached when resizing the window. Remove those constraints to allow the AnchorPane to grow as necessary:
Tab.fxml
<AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
...
</AnchorPane>
Furthermore I recommend avoiding the use of AnchorPanes, if you can avoid it. It's hard to achieve responsive layouts with this kind of layout. VBox and HBox would do much better jobs in this case.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.Region?>
<VBox prefHeight="480.0"
prefWidth="1000.0" xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<padding>
<Insets topRightBottomLeft="4" />
</padding>
<children>
<HBox fx:id="LabelBox" prefHeight="64.0" prefWidth="978.0" />
<TextArea VBox.vgrow="ALWAYS" fx:id="FilePaths"
prefHeight="128.0">
</TextArea>
<HBox spacing="10" minWidth="-Infinity">
<VBox.margin>
<Insets top="5" left="0" right="0" bottom="0" />
</VBox.margin>
<children>
<RadioButton mnemonicParsing="false" selected="true"
text="Hash/Size only">
<toggleGroup>
<ToggleGroup fx:id="AnalyzeMethod" />
</toggleGroup>
</RadioButton>
<RadioButton mnemonicParsing="false" text="FileName"
toggleGroup="$AnalyzeMethod" />
<RadioButton mnemonicParsing="false"
text="Directory Structure" toggleGroup="$AnalyzeMethod" />
<CheckBox fx:id="CheckDiff" mnemonicParsing="false"
text="Show Diff" />
<CheckBox fx:id="CheckSame" mnemonicParsing="false"
text="Show Same" />
<Region HBox.hgrow="ALWAYS" /> <!-- placeholder to grow/shrink -->
<ComboBox fx:id="ComboBox" prefWidth="150.0" />
</children>
</HBox>
</children>
</VBox>
I am trying to make a login page which is full screen,I followed another question in stackoverflow and made my login window it looks perfect with all controls, buttons etc aligned to center ,But as soon as I change the screen resolution every thing becomes unaligned . how can I solve this?.I am using scene builder
fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1360.0" spacing="20.0" styleClass="background" stylesheets="#../UICoreComponents/JMetroDarkTheme.css" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.MyCompany.attendanceMaster.LoginController">
<children>
<Pane prefHeight="200.0" prefWidth="278.0">
<children>
<TextField fx:id="userNameTF" layoutX="6.0" layoutY="55.0" prefHeight="25.0" prefWidth="248.0" promptText="Username" />
<Button layoutX="14.0" layoutY="141.0" mnemonicParsing="false" onAction="#loginBtnClicked" prefHeight="25.0" prefWidth="101.0" text="Login" />
<Button layoutX="145.0" layoutY="141.0" mnemonicParsing="false" onAction="#clearBtnClicked" prefHeight="25.0" prefWidth="101.0" text="Clear" />
<Label layoutX="99.0" layoutY="14.0" prefHeight="17.0" prefWidth="62.0" text="Login" textFill="WHITE">
<font>
<Font size="22.0" />
</font></Label>
<PasswordField fx:id="passwordTF" layoutX="6.0" layoutY="100.0" prefHeight="25.0" prefWidth="248.0" promptText="Password" />
</children>
</Pane>
</children>
<padding>
<Insets left="550.0" right="550.0" />
</padding>
</VBox>
Main.java
import com.MyCompany.Network.ClientMaster;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Screen;
import javafx.stage.Stage;
/**
*
* #author shersha
*/
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
new StaticController();
new ClientMaster();
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
stage.setFullScreen(true);
stage.setResizable(false);
Parent root = StaticController.LOGIN_LOADER.getRoot();
Scene scene = new Scene(root);
scene.getStylesheets().add("com/MyCompany/UICoreComponents/JMetroDarkTheme.css");
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
My screen resolution is 1360X768 perfectly alligned
**Screen resolution at 1024X768 **
My final question is how can I make a javafx application that will run screen resolution Independent?(My window size is maximized and not resizable)
Thank you.
Your layout is based on a VBox and then you are using padding to align it. As these values will be the same for all window sizes, it will only work in one case.
Instead you should use a StackPane or which centers the content. Into that StackPane you add your Pane, without any padding. Eventually you need to bind the scene width and heigh to the values of the StackPane.
I am just trying out JavaFX and am forcing my way into it because it is suppose to be the future. I am trying to create a table with 4 columns. The columns AND THE TABLE should resize to fill the parent pane. I cannot for the life of me get this to work. I have been trying for over 4 hours now and the tableview does not resize.
Here is my FXML file.
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.collections.*?>
<?import t.cubed.fxml.*?>
<BorderPane styleClass="root" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="t.cubed.fxml.FXMLDocumentController">
<top>
<MenuBar fx:id="menuBar" styleClass="menu-bar">
<menus>
<Menu text="File">
<items>
<MenuItem onAction="#handleOpenAction" text="Open" />
<MenuItem onAction="#handleExitAction" text="Exit" />
</items>
</Menu>
<Menu text="Edit">
<items>
<MenuItem onAction="#handleWeightAction" text="Edit Weights" />
<MenuItem onAction="#handleFilterAction" text="Edit Filters" />
<MenuItem onAction="#handleOptionsAction" text="Options" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<GridPane>
<!--
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
-->
<TableView fx:id="testTable" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="1">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
<columns>
<TableColumn text="TEST NUMBER">
<cellValueFactory>
<PropertyValueFactory property="testNumber" />
</cellValueFactory>
</TableColumn>
<TableColumn text="TEST NAME">
<cellValueFactory>
<PropertyValueFactory property="testName" />
</cellValueFactory>
</TableColumn>
<TableColumn text="TEST TIME(ms)">
<cellValueFactory>
<PropertyValueFactory property="testTime" />
</cellValueFactory>
</TableColumn>
<TableColumn text="BEST MATCH">
<cellValueFactory>
<PropertyValueFactory property="bestMatch" />
</cellValueFactory>
</TableColumn>
</columns>
<items>
<!--
<FXCollections fx:factory="observableArrayList">
<TestTableModel testNumber="100" testName="Test1234" testTime="0.34" bestMatch="99"/>
</FXCollections>
-->
</items>
</TableView>
</GridPane>
</center>
<stylesheets>
<URL value="#t-cubed.css" />
</stylesheets>
</BorderPane>
How Resizable Layout Works
The size of resizable items in JavaFX is managed by the layout managers in which the items are placed.
What you need to do
For your particular issue, you need to set the GridPane sizing constraints to manage the TableView that you placed in the grid.
See the GridPane.hgrow and GridPane.vgrow constraints I added on the TableView:
<TableView fx:id="testTable"
GridPane.columnIndex="0"
GridPane.columnSpan="1"
GridPane.hgrow="ALWAYS"
GridPane.vgrow="ALWAYS"
GridPane.rowIndex="0">
FXML just reflects the Java API, so you could also do the same in Java source as well; i.e. GridPane.setHGrow(node, priority). Though, if you are using FXML for your layout, defining the layout constraints in FXML is recommended.
Refactored Sample
I loaded your FXML up in Scene Builder 2 and set the appropriate constraints and it appears to resize automatically fine when I use the preview functionality of Scene Builder.
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.collections.*?>
<?import t.cubed.fxml.*?>
<BorderPane styleClass="root" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="t.cubed.fxml.FXMLDocumentController">
<top>
<MenuBar fx:id="menuBar" styleClass="menu-bar">
<menus>
<Menu text="File">
<items>
<MenuItem onAction="#handleOpenAction" text="Open" />
<MenuItem onAction="#handleExitAction" text="Exit" />
</items>
</Menu>
<Menu text="Edit">
<items>
<MenuItem onAction="#handleWeightAction" text="Edit Weights" />
<MenuItem onAction="#handleFilterAction" text="Edit Filters" />
<MenuItem onAction="#handleOptionsAction" text="Options" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<GridPane>
<children>
<!--
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
-->
<TableView fx:id="testTable" GridPane.columnIndex="0" GridPane.columnSpan="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.vgrow="ALWAYS">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
<columns>
<TableColumn text="TEST NUMBER">
<cellValueFactory>
<PropertyValueFactory property="testNumber" />
</cellValueFactory>
</TableColumn>
<TableColumn text="TEST NAME">
<cellValueFactory>
<PropertyValueFactory property="testName" />
</cellValueFactory>
</TableColumn>
<TableColumn text="TEST TIME(ms)">
<cellValueFactory>
<PropertyValueFactory property="testTime" />
</cellValueFactory>
</TableColumn>
<TableColumn text="BEST MATCH">
<cellValueFactory>
<PropertyValueFactory property="bestMatch" />
</cellValueFactory>
</TableColumn>
</columns>
<items>
<!--
<FXCollections fx:factory="observableArrayList">
<TestTableModel testNumber="100" testName="Test1234" testTime="0.34" bestMatch="99"/>
</FXCollections>
-->
</items>
</TableView>
</children>
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
</GridPane>
</center>
<stylesheets>
<URL value="#t-cubed.css" />
</stylesheets>
</BorderPane>
Some Advice
You are placing the TableView inside a GridPane. Using a GridPane in your case is a little strange as the GridPane you only place one node in the GridPane. Just placing the TableView directly in the center of your BorderPane or using a simpler layout parent such as a StackPane would have worked just fine. But perhaps this is just some cut down version of a more complex UI, so perhaps that is why you have used a GridPane.
Further Reading
If you have time, read up on layout in JavaFX in the Node, Pane, Group and GridPane javadoc and try this little layout bounds demo too.
Additional Questions for Comments
mention a StackPane would work, but StackPanes don't seem to have Hgrow and Vgrow?
StackPanes don't need a Hgrow or Vgrow constraints. Those constraints set Priorities, which are defined as:
Enumeration used to determine the grow (or shrink) priority of a given
node's layout area when its region has more (or less) space available
and multiple nodes are competing for that space.
With a StackPane, all children are layered on top of each other, they don't compete for space, so such growth priority settings for child nodes are not applicable.
After some homework, we came up with some qualifying information on FXML containers. Pretty much for the same reason given above by #user3403469. In the Scene Builder, there's a long list of 'containers'. Imho, only these 9 elements and Pane qualify as layout container, as they inherit from
<Pane> ... parent for all Pane classes. While both, Pane and Control inherit from Region only the Pane child-classes have layout properties.
* <AnchorPane>
* <BorderPane>
* <FlowPane>
* <GridPane>
* <StackPane>
* <TextFlow>
* <TilePane>
* <HBox>
* <VBox>
You can consider that Control child-classes more or less inherit Events and actions. Layout like things need to come from the encapsulating region, and the only thing with layout elements available to wrap a 'Control' is-a 'Pane'.
javafx.scene.layout.Pane
These FXML elements would be the bespoke 'layout managers' described in the #jewelsea's answer and elsewhere.
I guess 'Control' containers are still containers in FXML. It seems that they need to be 'inside' a panel to do good ;-)
Corrections and comment welcome.
related:
Percent width for TableColumn in JavaFX 2.x TableView
There seems to be a lot of code. My idea of dynamic resizing is a Zero-tolerance for code to do scaling and resize. Gee we left that behind in Windows 1.3 didn't we?
where is the: FXML Specification?
Reference and Guidelines for Dynamic Layout using JavaFX