2016-02-04 6 views
1

Я довольно новичок в JavaFX и FXML. Я закодировал java swing, но это было давно. Чтобы узнать что-то новое, я создаю небольшую настольную игру, но, похоже, я не могу выровнять свою GridPane с прямоугольниками внутри нее (GridPane находится внутри BorderPane). Под этим я подразумеваю (я считаю), что моя GridPane не привязана должным образом. Как вы можете видеть на моем снимке экрана, GridPane не перемещается с помощью BorderPane при изменении размера окна.GridPane не привязывается к BorderPane

Это мои классы:

Главная

public class Main extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     BorderPane root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     Scene scene = new Scene(root, 800, 900); 

     primaryStage.setTitle("Testing"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
     primaryStage.toFront(); 
    } 

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

Контроллер:

public class Controller implements Initializable { 


    @FXML private GridPane gridBoard; 
    @FXML private BorderPane borderPane; 


    public void initialize(java.net.URL location, 
         java.util.ResourceBundle resources) { 

     gridBoard.prefHeightProperty().bind(borderPane.heightProperty()); 
     gridBoard.prefWidthProperty().bind(borderPane.widthProperty()); 

    } 

    public void fillBoardEvent(ActionEvent event) { 

     for(int i = 0; i < 50; i++) { 
      for(int j = 0; j < 50; j++) { 
       InitiateCells n; 

       // This is for creating the rectangles 
       // and to give some specific cells 
       // different color 
       if(i == 24) { 
        if(j == 19 || j == 20 || j == 21 || j == 22 || j == 23 || j == 24 || j == 25 || j == 26 || j == 27 || 
         j == 28 || j == 29) { 

         n = new InitiateCells("" + i + "/" + j, 12, 12, i, j, 0); 

        } else { 
         n = new InitiateCells("" + i + "/" + j, 12, 12, i, j); 
        } 
       } else { 
        n = new InitiateCells("" + i + "/" + j, 12, 12, i, j); 
       } 
      } 
     } 

    } 

    public void exitEvent(ActionEvent event) { 
     System.exit(0); 
    } 

    public class InitiateCells extends Rectangle { 
     private String name; 
     private double width; 
     private double height; 


     public InitiateCells(String name, double width, double height, int rowIndex, int columnIndex) { 
      super(width, height); 
      this.name = name; 
      this.width = width; 
      this.height = height; 

      setFill(Color.web("#282828")); 
      setStroke(Color.web("#3b3b3b")); 
      setStrokeType(StrokeType.OUTSIDE); 
      setStrokeWidth(2.0); 


      gridBoard.add(this, columnIndex, rowIndex); 

    } 


     public InitiateCells(String name, double width, double height, int rowIndex, int columnIndex, int value) { 
      super(width, height); 
      this.name = name; 
      this.width = width; 
      this.height = height; 

      setFill(Color.web("#282828")); 
      setStroke(Color.web("#3b3b3b")); 
      setStrokeType(StrokeType.OUTSIDE); 
      setStrokeWidth(2.0); 


      gridBoard.add(this, columnIndex, rowIndex); 
    } 

Sample.fxml

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" 
     prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" 
     fx:controller="sample.Controller" fx:id="borderPane"> 


    <center> 
     <GridPane prefHeight="770.0" prefWidth="800.0" BorderPane.alignment="CENTER" fx:id="gridBoard" > 
      <children> 

      </children> 
     </GridPane> 
    </center> 

    <top> 
     <VBox prefHeight="30.0" prefWidth="800.0" BorderPane.alignment="TOP_CENTER"> 
      <children> 
       <MenuBar> 
        <menus> 
         <Menu text="File"> 
          <items> 
           <MenuItem text="New Game" onAction="#fillBoardEvent"/> 
           <MenuItem text="Save as GIF"/> 
           <MenuItem text="Export statistics"/> 
           <MenuItem text="Exit" onAction="#exitEvent"/> 
          </items> 
         </Menu> 
         <Menu text="Help"> 
          <items> 
           <MenuItem text="Game of Life"/> 
           <MenuItem text="How to play"/> 
           <MenuItem text="Open Javadoc"/> 
          </items> 
         </Menu> 
         <Menu text="About"> 
          <MenuItem text="Game of Life"/> 
          <MenuItem text="How to play"/> 
          <MenuItem text="Open Javadoc"/> 
         </Menu> 
        </menus> 
       </MenuBar> 
      </children> 
     </VBox> 
    </top> 

    <bottom> 
     <VBox prefHeight="70.0" prefWidth="800.0" BorderPane.alignment="BOTTOM_CENTER"> 
      <children> 
       <ProgressBar prefHeight="70.0" prefWidth="800.0" progress="50.0" /> 
      </children> 
     </VBox> 
    </bottom> 
</BorderPane> 

Это проблема; Когда я пытаюсь изменить размер окна, мои GridPane и VBox остаются в одном месте. При изменении размера окна он должен перейти от края к краю. Вот как это выглядит: Board

+0

Можете ли вы уточнить, ant, если вы увеличиваете размер окна?В настоящее время (по умолчанию) столбцы и строки в сетке остаются одинаковыми, потому что они будут сами по себе быть достаточно большими, чтобы содержать их содержимое. Вы можете довольно легко изменить это с помощью ограничений столбцов и объектов ограничений строк; однако прямоугольники имеют фиксированные размеры, поэтому вы вводите промежутки между ними. Какое поведение вы действительно ищете здесь? –

+0

Я хочу, чтобы прямоугольники автоматически изменялись с помощью окна при каждом изменении размера (то же самое с GridPane). Но вы говорите, что это невозможно без введения пробелов? – patski

+1

Ну, все возможно :). Но я бы не использовал 'Rectangle' здесь, я бы использовал что-то изменчивое (например,« Регион »). Позвольте мне составить ответ ... –

ответ

3

Проблема заключается не в том, что панель сетки не изменение размеров: проблема заключается в том, что когда панели сетки изменяет размер, столбцы и строки не изменить. Следовательно, в области сетки много пробелов после горизонтального пространства, занятого столбцами, и после вертикального пространства, занимаемого строками. (Это также объясняет, почему он не отображается по центру: сама панель сетки сосредоточена в пограничной панели, но строки и столбцы отображаются в верхнем левом углу самой панели сетки.)

Вы можете исправить это достаточно легко, установив ограничения столбцов и строк ограничений на панели сетки:

public void fillBoardEvent(ActionEvent event) { 

    int numRows = 50 ; 
    int numColumns = 50 ; 

    for (int i = 0 ; i < numRows; i++) { 
     RowConstraints row = new RowConstraints(); 
     row.setVgrow(Priority.ALWAYS); 
     gridBoard.getRowConstraints().add(row); 
    } 

    for (int j = 0 ; j < numColumns; j++) { 
     ColumnConstraints col = new ColumnConstraints(); 
     col.setHgrow(Priority.ALWAYS); 
     gridBoard.getColumnConstraints().add(col);    
    } 

    for(int i = 0; i < numRows; i++) { 
     for(int j = 0; j < numColumns; j++) { 
      InitiateCells n; 

      // code as before... 
     } 
    } 
} 

Теперь столбцы и строки будут расти, но их содержание не будет. Таким образом, вы в конечном итоге с пространством между клетками, как это:

enter image description here

Вы не можете исправить это легко с помощью Rectangle с, потому что Rectangle s не изменяемыми, и поэтому все настройки вы положили на панели сетки , он не сможет изменять размеры прямоугольников для вас. (Вы можете ввести привязки между размером сетки и шириной и высотой прямоугольников, но это будет очень ужасно очень быстро.) Я бы использовал Region s вместо Rectangle s, так как Region s могут быть изменены. Обратите внимание, что значения, которые вы назначаете как ширину и высоту ячеек, действительно являются предпочтительной шириной и высотой, так как вы хотите, чтобы они изменялись с помощью окна.

Region не fill, stroke и т.д., но это может быть стиль с помощью CSS, так что я бы

public class InitiateCells extends Region { 
    private String name; 
    private double width; 
    private double height; 


    public InitiateCells(String name, double width, double height, int rowIndex, int columnIndex) { 
     this.name = name; 
     this.width = width; 
     this.height = height; 

     setPrefSize(width, height); 
     getStyleClass().add("board-cell"); 

     gridBoard.add(this, columnIndex, rowIndex); 

    } 


    public InitiateCells(String name, double width, double height, int rowIndex, int columnIndex, int value) { 
     this(name, width, height, rowIndex, columnIndex); 
     pseudoClassStateUpdated(PseudoClass.getPseudoClass("on"), true); 
    } 

} 

Теперь в главном классе, добавить внешнюю таблицу стилей:

scene.getStylesheets().add(getClass().getResource("board-style.css").toExternalForm()); 

и добавьте файл board-style.css с

.board-cell { 
    -fx-background-color: #3b3b3b, #282828 ; 
    -fx-background-insets: 0, 2 ; 
} 

.board-cell:on { 
    -fx-background-color: #3b3b3b, white ; 
    -fx-background-insets: 0, 2 ; 
} 
+1

Ничего себе, я не ожидал такого ответа, когда я разместил вопрос. Большое вам спасибо за то, что нашли время, чтобы не только дать мне лучшее решение, но и потратить время, чтобы рассказать мне, почему это лучшее решение с примерами. Спасибо :) – patski

 Смежные вопросы

  • Нет связанных вопросов^_^