JavaFX动态调整大小 [英] JavaFX dynamic resizing

查看:120
本文介绍了JavaFX动态调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢您的帮助.我一直在尝试创建像Word中那样的功能区响应式布局,其中项目逐个调整大小,到目前为止,我并没有多大运气.

Thank you for your help. I've been trying to create a ribbon responsive layout like the one in Word, where the items resize one after another, and so far I haven't had much luck with it.

custom_control.fxml

<fx:root type="javafx.scene.layout.VBox" fx:id="dis" minHeight="-1.0" minWidth="-1.0" prefWidth="350.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
  <GridPane fx:id="grid">
    <children>
      <Button text="Button" GridPane.columnIndex="0" GridPane.rowIndex="0" />
      <RadioButton text="RadioButton" GridPane.columnIndex="1" GridPane.rowIndex="0" />
      <Button onAction="#doSomething" text="Click Me" GridPane.columnIndex="1" GridPane.rowIndex="1" />
      <ComboBox GridPane.columnIndex="0" GridPane.rowIndex="1" />
      <Slider GridPane.columnIndex="0" GridPane.rowIndex="2" />
      <CheckBox text="CheckBox" GridPane.columnIndex="1" GridPane.rowIndex="2" />
      <TextField fx:id="textField" prefWidth="200.0" GridPane.columnIndex="0" GridPane.rowIndex="3" />
      <MenuButton fx:id="mb" mnemonicParsing="false" text="" GridPane.columnIndex="1" GridPane.rowIndex="3">
        <items>
          <MenuItem mnemonicParsing="false" text="Action 1" />
          <MenuItem mnemonicParsing="false" text="Action 2" />
        </items>
      </MenuButton>
    </children>
    <columnConstraints>
      <ColumnConstraints hgrow="NEVER" maxWidth="+Infinity" minWidth="10.0" percentWidth="60.0" prefWidth="100.0" />
      <ColumnConstraints hgrow="NEVER" maxWidth="+Infinity" minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
    </columnConstraints>
    <rowConstraints>
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
    </rowConstraints>
  </GridPane>
</fx:root>

CustomController.java

public class CustomController extends VBox {

    /**
     * Initializes the controller class.
     */

    @FXML private TextField textField;
    @FXML private VBox dis;
    @FXML private GridPane grid;

    //dis.prefWidthProperty().bind(grid.widthProperty());

    public CustomController() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("custom_control.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public String getText() {
        return textProperty().get();
    }

    public void setText(String value) {
        textProperty().set(value);
    }

    public StringProperty textProperty() {
        return textField.textProperty();
    }

    public void adaptWidth(double width) {
        /*textField.textProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("textfield changed from " + oldValue + " to " + newValue);
        });*/
    }

    @FXML
    protected void doSomething() {
        System.out.println("The button was clicked!");
    }
 }


**RibbonJavaFX.java**

    public class RibbonJavaFX extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        HBox start = new HBox();
        CustomController rib1= new CustomController();
        rib1.setText("Ribbon 1");
        CustomController rib2 = new CustomController();
        rib2.setText("Ribbon 2");
        CustomController rib3 = new CustomController();
        rib3.setText("Ribbon 3");
        start.getChildren().add(rib1);
        start.getChildren().add(rib2);
        start.getChildren().add(rib3);

        rib3.prefWidthProperty().bind(rib2.widthProperty());
        rib2.prefWidthProperty().bind(rib1.widthProperty());


        Scene scene = new Scene(start,1800,400);

        stage.setScene(scene);
            //scene.getStylesheets().add(getClass().getResource("custom_control.css").toExternalForm());

        stage.setTitle("Custom Control");
        stage.setWidth(300);
        stage.setHeight(200);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }  
}

到目前为止,这就是我的作品.我一直在尝试将3个控制器绑定在一起,但是由于必须将其动态化并供将来使用,因为所有控制器都是相同的,所以它们必须彼此适应.我的目标是使它们一个接一个地调整大小,例如Word工具栏.有人可以帮我吗?我不希望得到完整的答案,可能只是我所需要的提示.

So this is how my work looks so far. I've been trying to bind the 3 controllers together, but since it has to be made dynamic and for future use, because all controllers are the same, so they have to adapt to each other. My goal is to make them resize one after another, like the Word toolbar. Can somebody please help me with this? I don't expect a full answer, a hint is maybe all I need.

推荐答案

更新后的答案! 此答案使用SplitPaneHBox来完成任务.它会根据SplitPane's分隔线的位置和分隔线的移动方向来增大近似值StackPane.您应该能够使用这些想法进行自定义控件.

Updated answer! This answer uses a SplitPane and an HBox to accomplish the task. It grows the approapitate StackPane depending the position of the SplitPane's divider and the direction the divider is moving. You should be able to make a custom control using these ideas.

主要

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication232 extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}

控制器

import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;

/**
 *
 * @author blj0011
 */
public class FXMLDocumentController implements Initializable
{

    @FXML
    HBox hBox;
    @FXML
    SplitPane splitPane;
    @FXML
    AnchorPane anchorPane2;

    @FXML
    StackPane sp1, sp2, sp3, sp4;

    double orgX, orgY;

    double PANE_MIN_WIDTH = 0;
    double PANE_STARTING_WIDTH = 200;
    double PANES_TOTAL_WIDTH = 800;

    AtomicBoolean initialMove = new AtomicBoolean(true);

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        SplitPane.Divider divider = splitPane.getDividers().get(0);

        divider.positionProperty().addListener((obs, oldValue, newValue) -> {
            //System.out.println("oldValue: " + oldValue.doubleValue() + " newValue: " + newValue);
            //System.out.println(anchorPane2.getWidth() + " :: " + (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH));

            if (newValue.doubleValue() > oldValue.doubleValue() && !initialMove.get()) {
                if (anchorPane2.getWidth() <= PANES_TOTAL_WIDTH && anchorPane2.getWidth() > PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) {
                    sp1.setMinWidth(PANE_MIN_WIDTH);
                    sp1.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH));
                }
                else if (anchorPane2.getWidth() <= (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) && anchorPane2.getWidth() > (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH)) {
                    sp2.setMinWidth(PANE_MIN_WIDTH);
                    sp2.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH));
                }
                else if (anchorPane2.getWidth() <= (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH) && anchorPane2.getWidth() > (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
                    sp3.setMinWidth(PANE_MIN_WIDTH);
                    sp3.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH));
                }
            }
            else if (newValue.doubleValue() < oldValue.doubleValue()) {
                if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
                    sp4.setMaxWidth(PANE_STARTING_WIDTH);
                    sp4.setMinWidth(anchorPane2.getWidth());
                }
                else if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH) && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
                    sp3.setMaxWidth(PANE_STARTING_WIDTH);
                    sp3.setMinWidth(anchorPane2.getWidth() - PANE_STARTING_WIDTH);
                }
                else if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH)) {
                    sp2.setMaxWidth(PANE_STARTING_WIDTH);
                    sp2.setMinWidth(anchorPane2.getWidth() - 2 * PANE_STARTING_WIDTH);
                }
                else if (anchorPane2.getWidth() <= PANES_TOTAL_WIDTH && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH)) {
                    sp1.setMaxWidth(PANE_STARTING_WIDTH);
                    sp1.setMinWidth(anchorPane2.getWidth() - 3 * PANE_STARTING_WIDTH);
                }
            }

            initialMove.set(false);//Used becase of the first pass, the AnchorPane's width = 0
        });
    }
}

FXML

FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>

<SplitPane fx:id="splitPane" dividerPositions="0.0" prefHeight="160.0" prefWidth="808.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication232.FXMLDocumentController">
   <items>
      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
      <AnchorPane fx:id="anchorPane2" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="800.0">
         <children>
            <HBox fx:id="hBox" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="203.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
               <children>
                  <StackPane fx:id="sp1" maxWidth="200.0" minWidth="0.0" prefWidth="200.0" style="-fx-background-color: green;" />
                  <StackPane fx:id="sp2" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: blue;" />
                  <StackPane fx:id="sp3" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: yellow;" />
                  <StackPane fx:id="sp4" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: brown;" />
               </children>
            </HBox>
         </children>
      </AnchorPane>
   </items>
</SplitPane>

这篇关于JavaFX动态调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆