JavaFX中的动态/即时调整大小

时间:2010-08-02 20:12:30

标签: binding resize javafx

如何创建(立即)动态调整大小的JavaFX应用程序?现在我编写了一个动态调整大小的简单应用程序,但布局更改直到拖动时释放鼠标按钮后才会显示。我希望在此按钮发布之前立即看到结果/布局更改。

我假设这是通过用反向绑定正确的值/控件来完成的...任何帮助都会很棒!

<小时/> 编辑:

以下是我的工作方式(感谢Praeus)。正如他所说,我必须将我的顶级容器/布局宽度和高度绑定到scene.width和scene.height。 -

var scene:Scene;

阶段{
标题:“申请标题”
    场景:场景=场景{
        内容:[
            XMigLayout {
                 width:bind scene.width;
                高度:绑定scene.height;
...}]}}

4 个答案:

答案 0 :(得分:4)

绑定在JavaFX 2.0版本中有所不同。 Angela Caicedo's video演示了如何很好地绑定属性。必须将变量设置为ObservableNumberValue,并使用其get和set方法。在设置完成后,您可以将其绑定到组件的属性。

DoubleProperty x = new SimpleDoubleProperty(0);
x.set(1);
x.getValue();
imageView.xProperty().bind(x);
anchorPane.heightProperty().add(x);

Eric Bruno's帖子是另一种方式。

scene.widthProperty().addListener( 
    new ChangeListener() {
        public void changed(ObservableValue observable, 
                            Object oldValue, Object newValue) {
            Double width = (Double)newValue;
            tbl.setPrefWidth(width);
        }
    });

scene.heightProperty().addListener(
    new ChangeListener() {
        public void changed(ObservableValue observable, 
                            Object oldValue, Object newValue) {
            Double height = (Double)newValue;
            tbl.setPrefHeight(height);
        }
    });

编辑:添加了另一个更合适的答案以及我找到它的位置。

答案 1 :(得分:3)

实际上,如果您已经将所有内容组织到布局中,那么您可以将顶级布局容器的宽度和高度绑定到scene.width和scene.height。我不认为顶级布局控件是由任何东西管理的,因此您可以安全地直接设置布局控件的宽度和高度。如果这不起作用,那么您可能成功绑定layoutInfo的宽度和高度。

理想情况下,您希望在使用绑定之前使用布局管理。过度绑定可能是性能问题,并且在调整大小时可能导致重绘速度变慢。在这种情况下,您可以只使用顶级容器的绑定,然后顶级容器的所有子级都应相应地调整大小。至少我认为这应该有效。

答案 2 :(得分:1)

是的我认为你的选择正确 - 绑定将是你做你想做的事情的明显方式。你也可以看看触发器。

如果您还没有

,请阅读1.3 guide to layouts作为起点

布局容器自动管理其内容节点的动态布局行为。但是,通常还希望使用JavaFX Script的绑定机制来建立布局的某些动态方面。例如,您可以将HBox容器的宽度和高度绑定到场景高度和宽度,以便每当场景调整大小时,HBox容器也会调整大小。

JavaFX布局大师Amy Fowler

也可能值得阅读文章和博客文章

答案 3 :(得分:0)

这就是我最终要调整大小的原因。必须有一种更简单的方法,但我当然不知道。

我的主要方法会加载我的控制器和场景,然后调用我的控制器的init()方法

\n

我使用的网格窗格会随着用户调整整个阶段的大小而动态调整大小,因此始终适合。这是因为其百分比大小。与使用绑定IMO相比,以fxml的方式更容易做到这一点。

        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
    Parent root = (Parent) loader.load();
    primaryStage.setTitle("Robot Interface");
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
    Controller controller = (Controller)loader.getController();
    controller.init();

记住我的控制器类如何调用其init()方法。那么init()会调用setupUI,在其中我获取高度和宽度,并在以后创建高度和宽度更改的回调。这些改变了我班级的变量mHeight和mWidth;

<GridPane fx:id="gridPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">

  <columnConstraints>
    <ColumnConstraints percentWidth="50" />
    <ColumnConstraints percentWidth="50" />
  </columnConstraints>
  <rowConstraints>
    <RowConstraints percentHeight="35" />
    <RowConstraints percentHeight="35" />
    <RowConstraints percentHeight="35" />
  </rowConstraints>
   <children>

      <TextArea fx:id="textArea_Console" prefHeight="200.0" prefWidth="200.0" promptText="console/reponse" GridPane.columnIndex="1" GridPane.rowIndex="2" />

      <!-- <MediaView fx:id="mediaView_Images" fitHeight="225.0" fitWidth="225.0" GridPane.halignment="LEFT" GridPane.valignment="BOTTOM" /> -->


      <TextArea fx:id="textArea_RoboAvail" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="121.0" prefWidth="123.0" promptText="robots available" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.valignment="TOP" />

      <TextArea fx:id="textArea_SensorData" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="249.0" prefWidth="106.0" promptText="sensor data" GridPane.halignment="RIGHT" GridPane.valignment="TOP" />

      <TextArea fx:id="textArea_Scripting" prefHeight="200.0" prefWidth="200.0" promptText="Scripting" GridPane.columnIndex="1" GridPane.rowIndex="1" />

      <Label text="Currently Viewing" GridPane.halignment="LEFT" GridPane.valignment="TOP" />

      <TextArea maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="250.0" prefWidth="100.0" promptText="to do list" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.valignment="TOP" />

      <ImageView fx:id="imageView_Images"  fitHeight="233.0" fitWidth="225.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="LEFT" GridPane.valignment="TOP" />

      <Label fx:id="label_CheatSheet" text="Label" GridPane.halignment="LEFT" GridPane.rowIndex="2" GridPane.valignment="BOTTOM" />




   </children>

最后,我可以调用dynamicResize(),它将网格窗格中的每个对象调整为该行宽度或高度的百分比

  private void setupUI()
{
    imageView_Images.setImage( new Image("file:///C:\\Users\\administration\\IdeaProjects\\Robot User Interface\\Media\\filler.jpeg"));



   mHeight = gridPane.getHeight();
   mWidth = gridPane.getWidth();

   //for initial startup sizing
    dynamicRsize();


    //callbacks to detect changes for sizing
    gridPane.widthProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            mWidth = newValue.doubleValue();
            dynamicRsize();
        }
    });

    gridPane.heightProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            mHeight = newValue.doubleValue();
            dynamicRsize();
        }
    });


    setup_TextArea_Scriptng();
    setup_Label_CheatSheet();

}