JavaFX - Как приспособить GridPane для заполнения всего HBox, используя ширину масштабирования и статическую ширину ColumnConstraints? - PullRequest
0 голосов
/ 06 мая 2018

У меня проблемы с заполнением всего моего пользовательского HBox с помощью GridPane, который создается динамически. HBox существует внутри ListView и уже динамически масштабируется с ListView без каких-либо проблем. Проблема в том, что я хочу, чтобы некоторые элементы в моем GridPane масштабировались при увеличении размера окна с помощью мыши, но некоторые части должны оставаться одинакового размера.

Есть две кнопки и метка-заполнитель, которые должны оставаться одинакового размера, что не является проблемой. Мой фиктивный класс, который подводит итог тому, что я делаю:

Контроллер:

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import static javafx.scene.layout.Region.USE_PREF_SIZE;


public class FXMLDocumentController implements Initializable {

private Label label;
@FXML
private ListView<ConversionJob> listJobs;
@FXML
private Button btnAction;

@FXML
private void handleButtonAction(ActionEvent event) {
    // Generates a new ConversionJob in the ListView.
listJobs.getItems().add(new ConversionJob());

}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // EMPTY
}

public class ConversionJob extends HBox {

    public ConversionJob() {
        super();

        // Creates all elements
        Label lblConversionName = new Label();
        ProgressBar progress = new ProgressBar();
        Button btnPause = new Button();
        Button btnCancel = new Button();
        GridPane grid = new GridPane();

        setGridInfo(grid, lblConversionName, progress, btnPause, btnCancel);

        this.getChildren().addAll(grid);
    }

    private void setGridInfo(GridPane grid, Label lblConversionName, ProgressBar progress, Button btnPause, Button btnCancel) {
        this.setHgrow(grid, Priority.ALWAYS);

    Label filler = new Label();
    filler.setText("  ");

    grid.addColumn(0, filler);
    grid.add(lblConversionName, 1, 0);
    grid.add(progress, 2, 0);
    grid.add(btnPause, 3, 0);
    grid.add(btnCancel, 4, 0);
    grid.setGridLinesVisible(true);


    grid.setMaxWidth(this.getMaxWidth());

    ColumnConstraints col1 = new ColumnConstraints();
    col1.setMinWidth(USE_PREF_SIZE);

    ColumnConstraints col2 = new ColumnConstraints();
    col2.setPercentWidth(40);

    ColumnConstraints col3 = new ColumnConstraints();
    col3.setPercentWidth(40);

    ColumnConstraints col4 = new ColumnConstraints();
    col4.setMinWidth(USE_PREF_SIZE);
    col4.setMaxWidth(USE_PREF_SIZE);

    ColumnConstraints col5 = new ColumnConstraints();
    col5.setMinWidth(USE_PREF_SIZE);
    col5.setMaxWidth(USE_PREF_SIZE);

    grid.getColumnConstraints().addAll(col1, col2, col3, col4, col5);
    }
}
}

документ FXML:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="500.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testieclass.FXMLDocumentController">
   <children>
      <ListView fx:id="listJobs" layoutX="54.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
      <Button fx:id="btnAction" layoutX="53.0" layoutY="160.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Button" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="460.0" />
   </children>
</AnchorPane>

Я понял, что должен как-то использовать для этого класс ColumnConstraits, но я хочу, чтобы первая метка не становилась больше, чем ее максимальная / предпочтительная ширина, и то же самое касается последних двух кнопок. Однако объекты lblConversionName и progress должны расширять GridPane, чтобы он заполнял ширину HBox, в котором существует GridPane.

Итак, в основном я хочу:

  • Метка заполнителя в первом столбце, которая не масштабируется при увеличении размера окна и имеет текст "".
  • Метка во втором столбце, размер которой увеличивается в зависимости от размера окна.
  • Индикатор выполнения в третьем столбце, который также масштабируется в зависимости от размера окна.
  • Две кнопки в последних 2 столбцах, которые вообще не масштабируются, как первая метка-заполнитель. Последняя кнопка должна быть закреплена справа, чтобы GridPane заполнил весь HBox.

Изменение чисел в col.setPercentageWidth(RandomNumber) кажется совершенно случайным, поскольку иногда оно полностью выходит за рамки моего HBox, а иногда вообще не масштабирует проценты. Кто-нибудь знает, как решить мою проблему?

1 Ответ

0 голосов
/ 06 мая 2018

Поскольку 2 столбца с изменяемым размером должны вырасти до одинакового размера, вы можете просто работать со свойствами hgrow и назначить Priority.NEVER и Priority.ALWAYS столбцам, размер которых не должен быть изменен, и столбцам, размер которых должен быть соответственно изменен:

GridPane grid = new GridPane();

ColumnConstraints neverGrow = new ColumnConstraints();
neverGrow.setHgrow(Priority.NEVER);

ColumnConstraints alwaysGrow = new ColumnConstraints();
alwaysGrow.setHgrow(Priority.ALWAYS);

grid.getColumnConstraints().addAll(
        neverGrow,
        alwaysGrow,
        alwaysGrow,
        neverGrow,
        neverGrow);

// just use the most basic resizable nodes to demonstrate this
Region region1 = new Region();
region1.setStyle("-fx-background-color: red;");
region1.setMinHeight(50);
Region region2 = new Region();
region2.setStyle("-fx-background-color: blue;");
region2.setMinHeight(50);

// fill the first row with some nodes
grid.addRow(0,
        new Label("Some Text:"),
        region1,
        region2,
        new Button("Click me"),
        new Button("me too"));
...