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).