从gridpane中删除行并向上移动其余行

时间:2015-07-13 23:14:22

标签: java javafx

我使用GridPane作为组件创建了一个场景。它基本上有5行2列,我在每个单元格中设置标签。现在我有一个问题,我需要根据条件删除一行。我能够使用setManaged()甚至setVisibleProperty()绑定它,但这会在UI上留下空白 我希望以下行占用空白区域。这可以实现吗?请帮忙。 ?这是fxml文件 `

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

<?import javafx.scene.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?>

<AnchorPane fx:id="anchor1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.lynden.fms.shipmentdetail.ui.ShipmentInfoTestController"> <children>
      <GridPane fx:id="gridPane" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <columnConstraints>
            <ColumnConstraints halignment="LEFT" minWidth="25.0" />
            <ColumnConstraints halignment="LEFT" minWidth="25.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints minHeight="25.0" prefHeight="25.0" valignment="TOP" vgrow="ALWAYS" />
            <RowConstraints minHeight="25.0" prefHeight="25.0" valignment="TOP" vgrow="ALWAYS" />
            <RowConstraints minHeight="25.0" prefHeight="25.0" valignment="TOP" vgrow="ALWAYS" />
            <RowConstraints minHeight="25.0" prefHeight="25.0" valignment="TOP" vgrow="ALWAYS" />
            <RowConstraints minHeight="25.0" prefHeight="25.0" valignment="TOP" vgrow="ALWAYS" />
         </rowConstraints>
         <children>
            <Label fx:id="label1" styleClass="info-label-font" text="Label2" GridPane.rowIndex="1">
               <GridPane.margin>
                  <Insets right="5.0" />
               </GridPane.margin>
            </Label>
            <Label fx:id="value1" styleClass="info-value-label-font" text="Value111111" GridPane.columnIndex="1">
               <padding>
                  <Insets left="10.0" />
               </padding>
            </Label>
            <Label fx:id="value3" styleClass="info-value-label-font" text="Date/Time" GridPane.columnIndex="1" GridPane.rowIndex="2">
               <padding>
                  <Insets left="10.0" />
               </padding>
            </Label>
            <Label fx:id="label0" styleClass="info-label-font" text="Label1">
               <GridPane.margin>
                  <Insets right="5.0" />
               </GridPane.margin>
            </Label>
            <Label fx:id="label4" styleClass="info-label-font" text="Label4" GridPane.rowIndex="3" />
            <Label fx:id="label5" styleClass="info-label-font" text="Label5" GridPane.rowIndex="4" />
            <Label fx:id="value4" styleClass="info-value-label-font" text="Value here " GridPane.columnIndex="1" GridPane.rowIndex="3">
               <padding>
                  <Insets left="10.0" />
               </padding>
            </Label>
            <Label fx:id="value5" styleClass="info-value-label-font" text="Value" GridPane.columnIndex="1" GridPane.rowIndex="4">
               <padding>
                  <Insets left="10.0" />
               </padding>
            </Label>
            <VBox fx:id="value2" prefWidth="100.0" styleClass="info-value-label-font" stylesheets="@../styles/ShipmentDetail.css" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS">
               <padding>
                  <Insets left="10.0" />
               </padding>
            </VBox>
            <Label fx:id="label3" styleClass="info-label-font" text="Label3" GridPane.rowIndex="2">
               <GridPane.margin>
                  <Insets right="5.0" />
               </GridPane.margin>
            </Label>
         </children>
      </GridPane>    </children> </AnchorPane>

&#39;

2 个答案:

答案 0 :(得分:2)

fx:id添加到与要隐藏的行对应的任何RowConstraints,然后在控制器中将min/pref/maxHeight属性绑定到要删除的条件行。

示例:

HideRowGridPane.fxml:

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

<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.geometry.Insets?>

<GridPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="HideRowGridPaneController" 
    alignment="TOP_CENTER">

    <CheckBox fx:id="showOptional" text="Show optional elements" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
    <Label fx:id="requiredLabel1" text="Required:" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
    <TextField fx:id="requiredTextField1" GridPane.columnIndex="1" GridPane.rowIndex="1"/> 
    <Label fx:id="optionalLabel1" text="Optional:" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
    <TextField fx:id="optionalTextField1" GridPane.columnIndex="1" GridPane.rowIndex="2"/> 
    <Label fx:id="requiredLabel2" text="Required:" GridPane.columnIndex="0" GridPane.rowIndex="3"/>
    <TextField fx:id="requiredTextField2" GridPane.columnIndex="1" GridPane.rowIndex="3"/> 
    <Label fx:id="optionalLabel2" text="Optional:" GridPane.columnIndex="0" GridPane.rowIndex="4"/>
    <TextField fx:id="optionalTextField2" GridPane.columnIndex="1" GridPane.rowIndex="4"/> 
    <Label fx:id="requiredLabel3" text="Required:" GridPane.columnIndex="0" GridPane.rowIndex="5"/>
    <TextField fx:id="requiredTextField3" GridPane.columnIndex="1" GridPane.rowIndex="5"/> 

    <rowConstraints>
        <RowConstraints />
        <RowConstraints />
        <RowConstraints fx:id="row2"/>
        <RowConstraints />
        <RowConstraints fx:id="row4"/>
        <RowConstraints />
    </rowConstraints>

    <padding>
        <Insets top="10" bottom="10" left="10" right="10" />
    </padding>
</GridPane>

HideRowGridPaneController.java:

import java.util.stream.Stream;

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.Region;
import javafx.scene.layout.RowConstraints;


public class HideRowGridPaneController {
    @FXML
    private RowConstraints row2 ;
    @FXML
    private RowConstraints row4 ;
    @FXML
    private Label requiredLabel1 ;
    @FXML
    private TextField requiredTextField1 ;
    @FXML
    private Label requiredLabel2 ;
    @FXML
    private TextField requiredTextField2 ;
    @FXML
    private Label requiredLabel3 ;
    @FXML
    private TextField requiredTextField3 ;
    @FXML
    private Label optionalLabel1 ;
    @FXML
    private TextField optionalTextField1 ;
    @FXML
    private Label optionalLabel2 ;
    @FXML
    private TextField optionalTextField2 ;
    @FXML
    private CheckBox showOptional ;

    public void initialize() {
        Stream.of(optionalLabel1, optionalTextField1, optionalLabel2, optionalTextField2)
            .forEach(n -> n.visibleProperty().bind(showOptional.selectedProperty()));

        Stream.of(row2, row4)
            .forEach(row -> {
                row.minHeightProperty().bind(Bindings.when(showOptional.selectedProperty())
                        .then(Region.USE_PREF_SIZE)
                        .otherwise(0));
                row.prefHeightProperty().bind(Bindings.when(showOptional.selectedProperty())
                        .then(Region.USE_COMPUTED_SIZE)
                        .otherwise(0));
                row.maxHeightProperty().bind(Bindings.when(showOptional.selectedProperty())
                        .then(Region.USE_PREF_SIZE)
                        .otherwise(0));
            });
    }
}

应用:

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

public class HideRowGridPane extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(FXMLLoader.load(getClass().getResource("HideRowGridPane.fxml")), 400, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

还有其他方法可以执行此操作,例如使用gridPane.getChildren().remove(...)从网格窗格中实际删除控件,并在执行此操作时手动重置下面组件的rowIndex属性。这可能有点棘手,但是可行。

答案 1 :(得分:0)

这是我根据自己的需要进行调整的一种方法。它不是FXML,但您可能会发现它很有用。

  

defaultRowSpan

如果您的行是倍数

(0,1,2,3,4,... defaultRowSpan = 1)

(0,2,4,6,8,... defaultRowSpan = 2)

private void deleteRow(GridPane grid, final int row) 
{       
    Set<Node> deleteNodes = new HashSet<>();
    for (Node child : grid.getChildren()) 
    {
        // get index from child
        Integer rowIndex = GridPane.getRowIndex(child);
        if(rowIndex == row)
        {
            deleteNodes.add(child);
        }
    }

    // remove nodes from row
    grid.getChildren().removeAll(deleteNodes);

    // shift rows up
    int i = row;
    for (Node child : grid.getChildren()) 
    {
        int nodeRowIndex = GridPane.getRowIndex(child);

        if(nodeRowIndex == (i + (defaultRowSpan * 2)))
        {
            i += defaultRowSpan;
        }

        if(nodeRowIndex > i)
        {
            GridPane.setRowIndex(child, i);
            System.out.println("set row index: " + child + " , row: " + i);
        }
    }
}