2014-06-06 6 views
2

Donc, j'essaye d'afficher un échiquier dans javaFX. Je vais devoir effectuer différentes opérations et dessiner sur certaines tuiles, j'ai donc choisi d'utiliser un Canevas pour chaque tuile et un GridPane pour les organiser en quadrillage.
Malheureusement, j'ai quelques problèmes avec le redimensionnement des carreaux de grille; Je veux que tout mon échiquier adapte automatiquement sa taille à la scène. Par conséquent, j'ai ajouté un ChangeListener aux propriétés height et width du GridPane qui prend soin de redimensionner les tiles. Cela ne fonctionne que lorsque la fenêtre devient plus grande, quand la fenêtre est réduite à une taille plus petite tout devient encore plus grand!
est ici le plus SSCCE je suis venu avec REPRODUISANT mon problème:Echiquier avec redimensionnement automatique

package chessboardtest; 

import javafx.application.Application; 
import javafx.beans.value.*; 
import javafx.geometry.*; 
import javafx.scene.*; 
import javafx.scene.canvas.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.scene.paint.*; 
import javafx.stage.Stage; 

public class ChessboardTest extends Application { 

    final int size = 10; 

    @Override 
    public void start(Stage primaryStage) { 
     VBox root = new VBox(); 

     final GridPane chessboard = new GridPane(); 
     fillChessboard(chessboard, size); 

     ChangeListener<Number> resizeListener = new ChangeListener<Number>() { 

      @Override 
      public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) { 
       double newWidth = chessboard.getWidth()/size; 
       double newHeight = chessboard.getHeight()/size; 

       for(Node n: chessboard.getChildren()) { 
        Canvas canvas = (Canvas)n; 
        canvas.setWidth(newWidth); 
        canvas.setHeight(newHeight); 
       } 
      } 
     }; 

     chessboard.widthProperty().addListener(resizeListener); 
     chessboard.heightProperty().addListener(resizeListener); 

     root.getChildren().add(chessboard); 
     root.setPadding(new Insets(10)); 
     VBox.setVgrow(chessboard, Priority.ALWAYS); 

     Scene scene = new Scene(root, 300, 250); 

     primaryStage.setTitle("chessboard"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    void fillChessboard(GridPane pane, int size) { 
     class RedrawListener implements ChangeListener<Number> { 
      Color color; 
      Canvas canvas; 
      public RedrawListener(Canvas c, int i) { 
       if(i % 2 == 0) { 
        color = Color.BLACK; 
       } 
       else { 
        color = Color.WHITE; 
       } 
       canvas = c; 
      } 

      @Override 
      public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) { 
       canvas.getGraphicsContext2D().setFill(color); 
       canvas.getGraphicsContext2D().fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
      } 
     } 

     for(int row = 0; row < size; row++) { 
      for(int col = 0, i = row; col < size; col++, i++) { 
       Canvas c = new Canvas(); 
       RedrawListener rl = new RedrawListener(c, i); 
       c.widthProperty().addListener(rl); 
       c.heightProperty().addListener(rl); 

       pane.add(c, row, col); 
      } 
     } 
    } 

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

'' +1 pour SSCCE'' – Cruncher

+0

Avez-vous vraiment besoin d'une toile? Pouvez-vous juste utiliser quelque chose comme un «StackPane» pour les carrés? –

Répondre

5

Si vous n'avez pas besoin d'une toile (et vous ne probablement pas), il suffit d'utiliser StackPane s pour les places et leur demander de compléter la largeur et la hauteur. Vous pouvez toujours ajouter une toile (ou toute autre chose) aux StackPane s pour afficher leur contenu.

import javafx.application.Application; 
import javafx.geometry.HPos; 
import javafx.geometry.VPos; 
import javafx.scene.Scene; 
import javafx.scene.control.Control; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Priority; 
import javafx.scene.layout.RowConstraints; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class Chessboard extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     GridPane root = new GridPane(); 
     final int size = 8 ; 
     for (int row = 0; row < size; row++) { 
      for (int col = 0; col < size; col ++) { 
       StackPane square = new StackPane(); 
       String color ; 
       if ((row + col) % 2 == 0) { 
        color = "white"; 
       } else { 
        color = "black"; 
       } 
       square.setStyle("-fx-background-color: "+color+";"); 
       root.add(square, col, row); 
      } 
     } 
     for (int i = 0; i < size; i++) { 
      root.getColumnConstraints().add(new ColumnConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, HPos.CENTER, true)); 
      root.getRowConstraints().add(new RowConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, VPos.CENTER, true)); 
     } 
     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

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

Ceci est une bonne solution, mais le redimensionnement est beaucoup plus facile avec la liaison de données en Java FX. Vous pouvez masquer toutes les activités d'écoute de cette manière. Voici une solution beaucoup comme James D's, mais en utilisant insread de Rectangles Canevas pour les places:

public class ResizeChessboard extends Application { 
    GridPane root = new GridPane(); 
    final int size = 8; 

    public void start(Stage primaryStage) { 
     for (int row = 0; row < size; row++) { 
      for (int col = 0; col < size; col++) { 
       Rectangle square = new Rectangle(); 
       Color color; 
       if ((row + col) % 2 == 0) color = Color.WHITE; 
       else color = Color.BLACK; 
       square.setFill(color); 
       root.add(square, col, row); 
       square.widthProperty().bind(root.widthProperty().divide(size)); 
       square.heightProperty().bind(root.heightProperty().divide(size)); 
      } 
     } 
     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

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

Merci, j'aime aussi ta solution! – BlackBear

Questions connexes