2014-04-24 7 views
1

JavaFX에서 다양한 수의 사각형이 포함 된 표를 표시하고 싶습니다. 이 그리드의 크기를 조정할 수없는 것이 중요합니다.JavaFX의 고정 크기 GridPane에 요소를 동적으로 추가합니다.

GridPane 레이아웃을 선택했습니다. 동적으로 javafx.scene.shape.Rectangle을 추가합니다. 다음은 2 행 4 열의 그리드 모습입니다. 크기 조정시

Grid 4x2

, 나는 동일한 전체 형태를 유지하기를 원하는 것, 즉, 각 Rectangle는 동일한 크기의 내 Rectangle들 사이의 수평 및 수직 간격을 유지하는 말을하는 것입니다. enter image description here

문제점이되고 :

  • 마지막 행과 마지막 열에는 Rectangle의 나머지와 같은 크기가없는

    그러나

    , 여기에 내가 4x4 그리드와 함께 무엇을 얻을 .

  • 틈이 사라졌습니다. 여기

디스플레이 새로 고침에 대한 내 코드가 담당하는 다음 setFillWidthsetHgrow이 중 어떤 결과를 얻을 수 없다 사용

public void refreshConstraints() { 
    getRowConstraints().clear(); 
    getColumnConstraints().clear(); 

    for (int i = 0; i < nbRow; i++) { 
     RowConstraints rConstraint = new RowConstraints(); 
     // ((nbRow - 1) * 10/nbRow) = takes gap into account (10% of height) 
     rConstraint.setPercentHeight(100/nbRow - ((nbRow - 1) * 10/nbRow)); 
     getRowConstraints().add(rConstraint); 
    } 

    for (int i = 0; i < nbColumn; i++) { 
     ColumnConstraints cConstraint = new ColumnConstraints(); 
     cConstraint.setPercentWidth(100/nbColumn - ((nbColumn - 1) * 10/nbColumn)); 
     getColumnConstraints().add(cConstraint); 
    } 

} 

을, 격차가 내 Rectangle의 사이에 유지되지만 Rectangle의 크기가 조절되지 않습니다 나머지 GUI 요소와 중첩됩니다.


편집 : MCVE 코드 :

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.RowConstraints; 
import javafx.scene.paint.Paint; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class DynamicGrid extends Application { 

    //Class containing grid (see below) 
    private GridDisplay gridDisplay; 

    @Override 
    public void start(Stage primaryStage) { 

     //Represents the grid with Rectangles 
     gridDisplay = new GridDisplay(400, 200); 

     //Fields to specify number of rows/columns 
     TextField rowField = new TextField(); 
     TextField columnField = new TextField(); 
     //Function to set an action when text field loses focus 
     buildTextFieldActions(rowField, columnField); 
     HBox fields = new HBox(); 
     fields.getChildren().add(rowField); 
     fields.getChildren().add(new Label("x")); 
     fields.getChildren().add(columnField); 

     BorderPane mainPanel = new BorderPane(); 
     mainPanel.setLeft(gridDisplay.getDisplay()); 
     mainPanel.setBottom(fields); 

     Scene scene = new Scene(mainPanel); 
     primaryStage.setTitle("Test grid display"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

    private void buildTextFieldActions(final TextField rowField, final TextField columnField) { 
     rowField.focusedProperty().addListener(new ChangeListener<Boolean>() { 

      @Override 
      public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { 
       if (!t1) { 
        if (!rowField.getText().equals("")) { 
         try { 
          int nbRow = Integer.parseInt(rowField.getText()); 
          gridDisplay.setRows(nbRow); 
          gridDisplay.updateDisplay(); 
         } catch (NumberFormatException nfe) { 
          System.out.println("Please enter a valid number."); 
         } 
        } 
       } 
      } 
     }); 

     columnField.focusedProperty().addListener(new ChangeListener<Boolean>() { 

      @Override 
      public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { 
       if (!t1) { 
        if (!columnField.getText().equals("")) { 
         try { 
          int nbColumn = Integer.parseInt(columnField.getText()); 
          gridDisplay.setColumns(nbColumn); 
          gridDisplay.updateDisplay(); 
         } catch (NumberFormatException nfe) { 
          System.out.println("Please enter a valid number."); 
         } 
        } 
       } 
      } 
     }); 
    } 

    //Class responsible for displaying the grid containing the Rectangles 
    public class GridDisplay { 

     private GridPane gridPane; 
     private int nbRow; 
     private int nbColumn; 
     private int width; 
     private int height; 
     private double hGap; 
     private double vGap; 

     public GridDisplay(int width, int height) { 
      this.gridPane = new GridPane(); 
      this.width = width; 
      this.height = height; 
      build(); 
     } 

     private void build() { 
      this.hGap = 0.1 * width; 
      this.vGap = 0.1 * height; 
      gridPane.setVgap(vGap); 
      gridPane.setHgap(hGap); 
      gridPane.setPrefSize(width, height); 
      initializeDisplay(width, height); 
     } 

     //Builds the first display (correctly) : adds a Rectangle for the number 
     //of rows and columns 
     private void initializeDisplay(int width, int height) { 
      nbRow = height/100; 
      nbColumn = width/100; 

      for (int i = 0; i < nbColumn; i++) { 
       for (int j = 0; j < nbRow; j++) { 
        Rectangle rectangle = new Rectangle(100, 100); 
        rectangle.setStroke(Paint.valueOf("orange")); 
        rectangle.setFill(Paint.valueOf("steelblue")); 
        gridPane.add(rectangle, i, j); 

       } 
      } 
     } 

     //Function detailed in post 
     //Called in updateDisplay() 
     public void refreshConstraints() { 
      gridPane.getRowConstraints().clear(); 
      gridPane.getColumnConstraints().clear(); 
      for (int i = 0; i < nbRow; i++) { 
       RowConstraints rConstraint = new RowConstraints(); 
       rConstraint.setPercentHeight(100/nbRow - ((nbRow - 1) * 10/nbRow)); 
       gridPane.getRowConstraints().add(rConstraint); 
      } 

      for (int i = 0; i < nbColumn; i++) { 
       ColumnConstraints cConstraint = new ColumnConstraints(); 
       cConstraint.setPercentWidth(100/nbColumn - ((nbColumn - 1) * 10/nbColumn)); 
       gridPane.getColumnConstraints().add(cConstraint); 
      } 

     } 

     public void setColumns(int newColumns) { 
      nbColumn = newColumns; 
     } 

     public void setRows(int newRows) { 
      nbRow = newRows; 
     } 

     public GridPane getDisplay() { 
      return gridPane; 
     } 

     //Function called when refreshing the display 
     public void updateDisplay() { 
      Platform.runLater(new Runnable() { 

       @Override 
       public void run() { 
        //The gridpane is cleared of the previous children 
        gridPane.getChildren().clear(); 

        //A new rectangle is added for row*column 
        for (int i = 0; i < nbColumn; i++) { 
         for (int j = 0; j < nbRow; j++) { 
          Rectangle rectangle = new Rectangle(100, 100); 
          rectangle.setStroke(Paint.valueOf("orange")); 
          rectangle.setFill(Paint.valueOf("steelblue")); 
          gridPane.add(rectangle, i, j); 
         } 
        } 
        //Call to this function to update the grid's constraints 
        refreshConstraints(); 
       } 
      }); 

     } 

    } 

} 
+0

GridPane을 그룹에 고정하십시오. 문제가 해결 되었습니까? 그렇지 않다면 [MCVE] (http://stackoverflow.com/help/mcve)를 포함하도록 게시물을 수정하십시오. – jewelsea

+0

그룹을 사용해도 아무 것도 변경되지 않습니다. MCVE 포함. 행 수를 변경하려면 첫 번째 텍스트 필드를 클릭하고 정수를 입력 한 다음 다른 텍스트 필드를 클릭하십시오. 문제는 여기에 약간 다르게 보인다. GridPane은 크기를 조정하지 않고 싶을 때 크기를 조정한다. – Koln

답변

2

답변 주셔서 감사 많은. TilePane은 실제로 사용하기가 훨씬 쉽습니다. 필자가 작성한 내용이 내 질문에 완전히 대답하지는 않습니다.

자식의 창의 크기는 조정하지 않고 창의 크기를 조정할 창을 갖고 싶습니다. maxSizeprefSize 설정이 효과가없는 것으로 보입니다.

편집는 :

public class GridDisplay { 
    private ReadOnlyDoubleProperty heightProperty; 
    private ReadOnlyDoubleProperty widthProperty; 

    ... 
} 

그런 다음 나는 값에 해당하는이 회원에 할당 : 내 그리드의 고정 높이와 폭에 대응, 내 GridDisplay 클래스에서 자바 FX Property 두 가지를 사용하여 수행하는 관리 생성자에서 원하는 고정 크기. 그리드 내부의 자식 크기는 행과 열의 수에 따라 그리드의 높이와 너비의 일부에 해당합니다.다음은 내 updateDisplay()의 모습입니다.

public void updateDisplay() { 
    gridPane.getChildren().clear(); 
    for (int i = 0; i < nbColumn; i++) { 
     for (int j = 0; j < nbRow; j++) { 
      Rectangle rectangle = new Rectangle(100, 100); 
      //Binding the fraction of the grid size to the width 
      //and heightProperty of the child 
      rectangle.widthProperty().bind(widthProperty.divide(nbColumn)); 
      rectangle.heightProperty().bind(heightProperty.divide(nbRow)); 
      gridPane.add(rectangle, i, j); 
     } 
    } 
} 
9

TilePane처럼 보인다는 더 잘 맞는 GridPane 이상이 사용 사례입니다.

2by4 3by2

import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.TilePane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

// java 8 code 
public class DynamicTiles extends Application { 

    //Class containing grid (see below) 
    private GridDisplay gridDisplay; 

    //Class responsible for displaying the grid containing the Rectangles 
    public class GridDisplay { 

     private static final double ELEMENT_SIZE = 100; 
     private static final double GAP = ELEMENT_SIZE/10; 

     private TilePane tilePane = new TilePane(); 
     private Group display = new Group(tilePane); 
     private int nRows; 
     private int nCols; 

     public GridDisplay(int nRows, int nCols) { 
      tilePane.setStyle("-fx-background-color: rgba(255, 215, 0, 0.1);"); 
      tilePane.setHgap(GAP); 
      tilePane.setVgap(GAP); 
      setColumns(nCols); 
      setRows(nRows); 
     } 

     public void setColumns(int newColumns) { 
      nCols = newColumns; 
      tilePane.setPrefColumns(nCols); 
      createElements(); 
     } 

     public void setRows(int newRows) { 
      nRows = newRows; 
      tilePane.setPrefRows(nRows); 
      createElements(); 
     } 

     public Group getDisplay() { 
      return display; 
     } 

     private void createElements() { 
      tilePane.getChildren().clear(); 
      for (int i = 0; i < nCols; i++) { 
       for (int j = 0; j < nRows; j++) { 
        tilePane.getChildren().add(createElement()); 
       } 
      } 
     } 

     private Rectangle createElement() { 
      Rectangle rectangle = new Rectangle(ELEMENT_SIZE, ELEMENT_SIZE); 
      rectangle.setStroke(Color.ORANGE); 
      rectangle.setFill(Color.STEELBLUE); 

      return rectangle; 
     } 

    } 

    @Override 
    public void start(Stage primaryStage) { 

     //Represents the grid with Rectangles 
     gridDisplay = new GridDisplay(2, 4); 

     //Fields to specify number of rows/columns 
     TextField rowField = new TextField("2"); 
     TextField columnField = new TextField("4"); 

     //Function to set an action when text field loses focus 
     buildTextFieldActions(rowField, columnField); 

     HBox fields = new HBox(10); 
     fields.getChildren().add(rowField); 
     fields.getChildren().add(new Label("x")); 
     fields.getChildren().add(columnField); 

     BorderPane mainPanel = new BorderPane(); 
     mainPanel.setCenter(gridDisplay.getDisplay()); 
     mainPanel.setTop(fields); 

     Scene scene = new Scene(mainPanel, 1000, 800); 
     primaryStage.setTitle("Test grid display"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

    private void buildTextFieldActions(final TextField rowField, final TextField columnField) { 
     rowField.focusedProperty().addListener((ov, t, t1) -> { 
      if (!t1) { 
       if (!rowField.getText().equals("")) { 
        try { 
         int nbRow = Integer.parseInt(rowField.getText()); 
         gridDisplay.setRows(nbRow); 
        } catch (NumberFormatException nfe) { 
         System.out.println("Please enter a valid number."); 
        } 
       } 
      } 
     }); 

     columnField.focusedProperty().addListener((ov, t, t1) -> { 
      if (!t1) { 
       if (!columnField.getText().equals("")) { 
        try { 
         int nbColumn = Integer.parseInt(columnField.getText()); 
         gridDisplay.setColumns(nbColumn); 
        } catch (NumberFormatException nfe) { 
         System.out.println("Please enter a valid number."); 
        } 
       } 
      } 
     }); 
    } 
}