2014-12-25 4 views
0

Я хотел бы показать квадрат GridPane внутри окна. Окно может иметь все возможные размеры и обычно ширина и высота не равны. Во всяком случае, я хотел бы, чтобы отобразить GridPane как квадрат по центру, как это:Изменение размера квадратной сетки

width greater than height

соответственно

height greater than width

В идеале конфигурируемый обивка вокруг площади. Изображения взяты из подхода холста, но я хочу переключиться на стандартные элементы управления. Может ли кто-нибудь дать мне несколько советов, как это сделать?

ответ

1

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

Вместо GridPane простой Group более гибкий для перемещения своих детей, хотя для этого требуется ручная компоновка.

Этот простой фрагмент основан на реализации JavaFX игры 2048, вы можете найти here. Он использует узорные прямоугольники для создания сетки, и над ними добавляются «плитки». Чтобы узнать больше о стилизации, макетировании или перемещении плитки, перейдите по ссылке.

private static final int NUM_CELLS = 15; 
private static final int CELL_SIZE = 50; 
private static final int TILE_SIZE = CELL_SIZE-15; 
private final static int MARGIN = 20; 

@Override 
public void start(Stage primaryStage) { 
    // create background square grid 
    Group gridGroup = new Group(); 
    IntStream.range(0,NUM_CELLS).boxed().forEach(i-> 
     IntStream.range(0,NUM_CELLS).boxed().forEach(j->{ 
      Rectangle cell = new Rectangle(i * CELL_SIZE, j * CELL_SIZE, CELL_SIZE, CELL_SIZE); 
      cell.setFill(Color.WHEAT); 
      cell.setStroke(Color.GREY); 
      gridGroup.getChildren().add(cell); 
     }) 
    ); 
    // Add grid to board 
    Group board = new Group(gridGroup); 

    // add random tiles to board 
    IntStream.range(0,NUM_CELLS).boxed().forEach(i-> 
     IntStream.range(0,NUM_CELLS).boxed().forEach(j->{ 
      if(i==j || NUM_CELLS-i-1==j){ 
       Label label = new Label(); 
       label.setMinSize(TILE_SIZE, TILE_SIZE); 
       label.setPrefSize(TILE_SIZE, TILE_SIZE); 
       label.setMaxSize(TILE_SIZE, TILE_SIZE); 
       label.setStyle("-fx-background-color: red; -fx-background-radius: 50"); 
       label.setLayoutX((i+0.5)*CELL_SIZE-TILE_SIZE/2); 
       label.setLayoutY((j+0.5)*CELL_SIZE-TILE_SIZE/2); 
       board.getChildren().add(label); 
      } 
     }) 
    ); 

    Bounds gameBounds = board.getLayoutBounds(); 

    StackPane root = new StackPane(board); 

    // Listener to rescale and center the board 
    ChangeListener<Number> resize = (ov, v, v1) -> { 
     double scale = Math.min((root.getWidth() - MARGIN)/gameBounds.getWidth(), 
           (root.getHeight() - MARGIN)/gameBounds.getHeight()); 
     board.setScaleX(scale); 
     board.setScaleY(scale); 
     board.setLayoutX((root.getWidth() - gameBounds.getWidth())/2d); 
     board.setLayoutY((root.getHeight() - gameBounds.getHeight())/2d); 
    }; 
    root.widthProperty().addListener(resize); 
    root.heightProperty().addListener(resize); 

    Scene scene = new Scene(root); 

    // Maximum size of window 
    Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds(); 
    double factor = Math.min(visualBounds.getWidth()/(gameBounds.getWidth() + MARGIN), 
      visualBounds.getHeight()/(gameBounds.getHeight() + MARGIN)); 
    primaryStage.setScene(scene); 
    primaryStage.setWidth((gameBounds.getWidth() + MARGIN) * factor); 
    primaryStage.setHeight((gameBounds.getHeight() + MARGIN) * factor); 
    primaryStage.show(); 
} 

И это, как он будет выглядеть после некоторого изменения размеров окна:

Grid

+0

Извините за поздний ответ и прием. Единственным недостатком является то, что это решение создает «Исключение в потоке» JavaFX Application Thread »java.lang.IllegalStateException: не для потока приложений FX; currentThread = JavaFX Application Thread', когда вы выполняете изменение размера и закрываете приложение. Это нормально, когда вы просто запускаете и закрываете его. – ChrLipp

+0

Хм ... У меня нет такого исключения. Просто запустите мой код? Посмотрите на ссылку, опубликованную в моем ответе, вы найдете полностью работающее приложение. –

+0

Происходит только при его максимизации и последующем закрытии (на macbook). – ChrLipp

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