2017-03-06 133 views
0

我想在一個gridpane中添加一個不可見的行。然後我想根據用戶選擇顯示並隱藏它。我已經設法使一般功能正常工作,但問題是當行內容被隱藏時有一個額外的空間。我不確定這是實際行還是vgap?無論如何,我想擺脫這個額外的空間。 這裏是我的gridpane:在javafx gridpane中添加不可見行

public class CustomGrid extends GridPane{ 

public CustomGrid() { 
    this.setHgap(20); 
    this.setVgap(20); 

    ColumnConstraints firstColConstraints = new ColumnConstraints(); 
    firstColConstraints.setHalignment(HPos.RIGHT); 
    firstColConstraints.setPercentWidth(50.0); 
    firstColConstraints.setHgrow(Priority.ALWAYS); 
    ColumnConstraints secondColConstraints = new ColumnConstraints(); 
    ColumnConstraints thirdColConstraints = new ColumnConstraints(); 
    thirdColConstraints.setHgrow(Priority.ALWAYS); 
    thirdColConstraints.setHalignment(HPos.LEFT); 

    this.getColumnConstraints().addAll(firstColConstraints, secondColConstraints, thirdColConstraints); 
    VBox.setMargin(this, new Insets(10, 0, 50, 0)); 

} 

我添加的內容,然後把它藏在像這樣

Pane content = new Pane() 
pane.setVisible(false); 
pane.setManaged(false); 
add(content, 0, 1); 

我很喜歡它,當用戶使其可見,但是當它被隱藏有一個行之間的額外間隙。誰能告訴我一種方法來解決這個問題。

謝謝。

+0

如果用戶點擊後可以看到它。這意味着兩行之間有一些東西。你能看到什麼?你能展示圖像嗎? – minigeek

+1

沒有看到問題,我可以想象隱藏時將高度更改爲0可能會有所幫助 – PendingValue

+1

@PierrePascalLindenberg謝謝!如果你可以把它作爲答案,我可以將其標記爲正確的。 – user3552551

回答

1

我認爲處理這個問題的最好方法是從網格窗格中實際刪除該行,而不是試圖使該行「不可見」。在GridPane的任意位置插入和刪除行是有點棘手的,因爲GridPane API沒有本地支持這些功能。所以我創建了一個基於你的自定義GridPane實現的小實用程序,演示瞭如何在GridPane中添加和刪除行。爲此,自定義實現必須保持內部概念,指出哪些節點位於哪些行,並在每次添加或刪除新行時更新每個節點和每個行的列約束。隱藏可以通過從網格窗格中刪除一行來完成,然後在稍後的階段將相同的行添加回到之前刪除的索引的網格窗格中。我明白這不是你正在尋找的東西,但它對我來說似乎是最合理的解決方案。

append

/** Click on a Label to remove the row containing the label from the GridPane */ 
import javafx.application.Application; 
import javafx.collections.*; 
import javafx.geometry.*; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.*; 
import javafx.stage.Stage; 

import java.util.*; 

public class HiddenNodes extends Application { 

    private static final int N_COLS = 3; 
    private static final int INIT_N_ROWS = 10; 

    private int nextRowId = 0; 
    private Node[] lastRemovedRow = null; 

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

    @Override 
    public void start(Stage stage) throws Exception { 
     CustomGrid grid = new CustomGrid(); 

     for (int i = 0; i < INIT_N_ROWS; i++) { 
      Label[] labels = createRow(grid); 
      grid.insertRow(i, labels); 
     } 

     Button prepend = new Button("Prepend"); 
     prepend.setOnAction(event -> { 
      Label[] labels = createRow(grid); 
      grid.insertRow(0, labels); 
     }); 

     Button append = new Button("Append"); 
     append.setOnAction(event -> { 
      Label[] labels = createRow(grid); 
      grid.insertRow(grid.getRowsSize(), labels); 
     }); 

     HBox controls = new HBox(10, prepend, append); 

     VBox layout = new VBox(10, controls, grid); 
     layout.setPadding(new Insets(10)); 

     stage.setScene(new Scene(layout, 200, 600)); 
     stage.show(); 
    } 

    private Label[] createRow(CustomGrid grid) { 
     Label[] labels = new Label[N_COLS]; 
     for (int j = 0; j < N_COLS; j++) { 
      final int fj = j; 
      labels[j] = new Label(nextRowId + ":" + j); 
      labels[j].setStyle("-fx-background-color: coral;"); 
      labels[j].setOnMouseClicked((MouseEvent e) -> { 
       lastRemovedRow = grid.removeRowContaining(labels[fj]); 
      }); 
     } 

     nextRowId++; 

     return labels; 
    } 

    class CustomGrid extends GridPane { 
     private ObservableList<Node[]> rows = FXCollections.observableArrayList(); 

     CustomGrid() { 
      this.setHgap(20); 
      this.setVgap(20); 

      ColumnConstraints firstColConstraints = new ColumnConstraints(); 
      firstColConstraints.setHalignment(HPos.RIGHT); 
      firstColConstraints.setPercentWidth(50.0); 
      firstColConstraints.setHgrow(Priority.ALWAYS); 
      ColumnConstraints secondColConstraints = new ColumnConstraints(); 
      ColumnConstraints thirdColConstraints = new ColumnConstraints(); 
      thirdColConstraints.setHgrow(Priority.ALWAYS); 
      thirdColConstraints.setHalignment(HPos.LEFT); 

      this.getColumnConstraints().addAll(firstColConstraints, secondColConstraints, thirdColConstraints); 
      VBox.setMargin(this, new Insets(10, 0, 50, 0)); 
     } 

     void insertRow(int rowIdx, Node... nodes) { 
      for (int i = rows.size() - 1; i >= rowIdx; i--) { 
       for (int j = 0; j < rows.get(i).length; j++) { 
        setConstraints(rows.get(i)[j], j, i + 1); 
       } 
      } 

      addRow(rowIdx, nodes); 
      rows.add(rowIdx, nodes); 
     } 

     private Node[] removeRow(int rowIdx) { 
      for (int i = rows.size() - 1; i > rowIdx; i--) { 
       for (int j = 0; j < rows.get(i).length; j++) { 
        setConstraints(rows.get(i)[j], j, i - 1); 
       } 
      } 

      for (Node node: rows.get(rowIdx)) { 
       getChildren().remove(node); 
      } 
      return rows.remove(rowIdx); 
     } 

     Node[] removeRowContaining(Node node) { 
      Iterator<Node[]> rowIterator = rows.iterator(); 
      int rowIdx = 0; 
      while (rowIterator.hasNext()) { 
       Node[] row = rowIterator.next(); 
       for (Node searchNode : row) { 
        if (searchNode == node) { 
         return removeRow(rowIdx); 
        } 
       } 

       rowIdx++; 
      } 

      return null; 
     } 

     int getRowsSize() { 
      return rows.size(); 
     } 
    } 
} 

上述程序只是一個輪廓,附加的邏輯將需要重新顯示「隱藏」節點(其已經從網格中刪除)將適當行索引處(這是一個相當棘手的問題)。

注意:您可能會考慮使用TableView而不是GridPane。通過操作支持TableView的項目列表,向TableView中添加和刪除節點非常簡單。當然,我知道TableView並不是適合所有這類問題的解決方案(因爲TableView帶有許多其他功能,如標題和排序,您可能不希望這樣)。