JavaFX动态调整大小

时间:2018-07-30 21:31:51

标签: javafx

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

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工具栏。有人可以帮我吗?我不希望得到完整的答案,可能只是我所需要的提示。

1 个答案:

答案 0 :(得分:0)

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

  

主要

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

<?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>