JavaFX 8:如何重新调整窗口(阶段)的大小,但保持内部元素的位置?

时间:2015-07-18 20:56:02

标签: java javafx-8

我有一个项目有2个文本区域和几个按钮。根窗格是AnchorPane。当将窗口大小调整为较小的窗口时,所有元素都开始重叠。有什么方法可以解决这个问(不知道我的主播的名字,我懒惰了)

    AnchorPane borderpane = new AnchorPane ();

    TextArea user_list = new TextArea();
    user_list.setPrefSize(150, 400);
    TextArea messages = new TextArea();
    messages.setPrefSize(350, 400);
    TextField typebox = new TextField();
    typebox.setPrefSize(425, 100);

    // put a shape over a text, over a shape
    StackPane send_container = new StackPane();

    Rectangle send_box = new Rectangle(75, 25);
    Label send_text = new Label("Send");

    send_container.getChildren().add(send_box);
    send_container.getChildren().add(send_text);

    AnchorPane.setLeftAnchor(messages, 25.0);
    AnchorPane.setTopAnchor(messages, 10.0);
    AnchorPane.setRightAnchor(user_list, 25.0);
    AnchorPane.setTopAnchor(user_list, 10.0);

    AnchorPane.setBottomAnchor(typebox, 25.0); 
    AnchorPane.setLeftAnchor(typebox, 25.0); 
    AnchorPane.setBottomAnchor(send_container, 25.0); 
    AnchorPane.setRightAnchor(send_container, 25.0); 
    borderpane.getChildren().addAll(messages, user_list, typebox,send_container );


    Scene scene = new Scene(borderpane, 600, 600);
    primaryStage.setMaxHeight(600);
    primaryStage.setMaxWidth(600);

    primaryStage.setScene(scene); 
    primaryStage.setTitle("Welcome");
    scene.getStylesheets().add(LoginWindow.class.getResource("Login.css").toExternalForm());
    primaryStage.show();

2 个答案:

答案 0 :(得分:1)

您正在对控件的位置和大小进行硬编码。这意味着控件无法响应父节点大小的变化。

通常,您不应指定任何高度或宽度。控件都具有默认的首选尺寸,所有布局都遵循这些尺寸。布局还决定如何调整子节点的大小以响应用户调整窗口的大小。

通常,窗口的布局需要细分为子布局。在您的情况下,您希望一个部分始终调整大小以填充窗口(用户列表和消息部分),底部的另一个部分(类型框和发送按钮)。 BorderPane是理想的选择,因为它的中心节点总是填充它。因此,这个主BorderPane的中心将包含用户列表和消息区域,而此BorderPane的底部将包含类型框和发送按钮。

您可能希望用户能够横向调整用户列表和消息的大小,因此我将它们放在SplitPane中,并使SpiltPane成为主BorderPane的中心。

您可能希望typebox和Send按钮位于单独的子BorderPane中,并将typebox作为中心节点,因为您希望在用户调整窗口大小时水平扩展和缩小类型框。

所以,总结一下:

  • SplitPane中的用户列表和消息区域
  • BorderPane中的“打开”按钮和
  • 中的“发送”按钮
  • 父级BorderPane,中间是用户列表/消息部分,底部是打印/发送部分

这个代码实际上很短:

ListView user_list = new ListView();

TextArea messages = new TextArea();
messages.setPrefRowCount(12);
messages.setPrefColumnCount(30);

TextField typebox = new TextField();
typebox.setPrefColumnCount(30);

Button send_text = new Button("Send");
send_text.disableProperty().bind(
    typebox.lengthProperty().lessThan(1));

SplitPane top = new SplitPane(user_list, messages);
top.setDividerPosition(0, 1/3.0);

BorderPane bottom = new BorderPane();
bottom.setCenter(typebox);
bottom.setRight(send_text);
BorderPane.setMargin(typebox, new Insets(0, 12, 0, 0));

BorderPane main = new BorderPane();
main.setCenter(top);
main.setBottom(bottom);
BorderPane.setMargin(bottom, new Insets(12));

Scene scene = new Scene(main);

primaryStage.setScene(scene); 
primaryStage.setTitle("Welcome");
scene.getStylesheets().add(LoginWindow.class.getResource("Login.css").toExternalForm());
primaryStage.show();

请注意,没有硬编码尺寸或坐标(Insets对象定义的边距除外)。每个控件都有一个基于其属性的首选大小,例如TextField的首选列数。

各种布局的工作情况都有详细记录。我建议在javafx.scene.layout package中阅读它们。

(我猜测用户列表应该是ListView,而不是TextArea,因为典型的聊天程序允许选择一个或多个用户。我怀疑你的黑色Rectangle和send_text标签是为了代表一个禁用的按钮。)

答案 1 :(得分:0)

使用锚点窗格以外的窗格。这是绝对定位。尝试堆栈窗格或简单的VBox。