改变我的程序,以便在矩形和圆形之间改变组合框

时间:2018-03-20 03:44:44

标签: javafx

我有一个代码可以创建多个随机矩形。我需要添加一个改变创建形状的组合框,我不知道如何去做。对不起,如果这段代码很难看。我对javafx了解不多。

public class ModernArtPt2 extends Application {
    //Array of names
    private String[] shapeName = {"Circle", "Square"};
    private ComboBox<String> cbo = new ComboBox<>();
    private DescriptionPane descriptionPane = new DescriptionPane();
    @Override
    public void start(Stage primaryStage) {
        Random rand = new Random();

// Set the first shape for display
        setDisplay(0);

        BorderPane pane = new BorderPane();

        BorderPane paneForComboBox = new BorderPane();
        paneForComboBox.setLeft(new Label("Select a shape: "));
        paneForComboBox.setCenter(cbo);
        pane.setTop(paneForComboBox);

        ObservableList<String> items =
                FXCollections.observableArrayList(shapeName);
        cbo.getItems().addAll(items);
        //pane.setCenter(descriptionPane);
        // Display the selected country
        cbo.setOnAction(e -> setDisplay(items.indexOf(cbo.getValue())));
// Create 50 rectangles
        Group group = new Group();
        for (int i = 0; i < 51; i++) {
            Rectangle r = new Rectangle();
            r.setX(rand.nextInt(600));
            r.setY(rand.nextInt(300));
            r.setWidth(rand.nextInt(90) + 10);
            r.setHeight(rand.nextInt(90) + 10);
            r.setFill(Color.color(Math.random(), Math.random(), Math.random()));
            r.setOpacity(Math.random());
            group.getChildren().add(r);
        }

// Create a scene and place it in the stage
        Scene scene = new Scene(new BorderPane(group), 600, 300); //New Scene
        primaryStage.setTitle("Modern Art"); // Stage Title
        primaryStage.setScene(scene); // Place the scene in stage
        primaryStage.show(); // Display the stage
    }

    public void setDisplay(int index) {
        descriptionPane.setTitle(shapeName[index]);
    }

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

}

1 个答案:

答案 0 :(得分:0)

以下是可以做的事情的一个例子。如上所述,这只是一个例子,可以根据用户可以选择的形状数量和错误管理进行一些改进。

/**
 * @since 20180320
 */
public class ModernArtPt2 extends Application {

   public enum MyShape {

      RECT("Rectangle"), CIRCLE("Circle");

      /** Name of the shape. */
      private String name;

      /**
       * Constructor.
       * 
       * @param pName
       *           the name of the shape.
       */
      private MyShape(String pName) {
         name = pName;
      }

      @Override
      public String toString() {
         return name;
      }

      /**
       * @return {@code true} if the selected shape is rectangle, {@code false} otherwise.
       */
      public boolean isRectSelected() {
         return "Rectangle".equals(this.toString());
      }
   }

   private ComboBox<MyShape> cbo = new ComboBox<>();

   private Group group;

   @Override
   public void start(Stage primaryStage) {
      BorderPane pane = new BorderPane();

      BorderPane paneForComboBox = new BorderPane();
      paneForComboBox.setLeft(new Label("Select a shape: "));
      paneForComboBox.setCenter(cbo);
      pane.setTop(paneForComboBox);

      // Create 50 rectangles
      group = initializeRandomShape();
      pane.setCenter(group);

      ObservableList<MyShape> items = FXCollections.observableArrayList(MyShape.values());
      cbo.getItems().addAll(items);
      // pane.setCenter(descriptionPane);
      // Display the selected country
      cbo.setOnAction(e -> changeDisplay(cbo.getValue()));
      cbo.getSelectionModel().select(0);

      // Create a scene and place it in the stage
      Scene scene = new Scene(pane, 600, 300); // New Scene
      primaryStage.setTitle("Modern Art"); // Stage Title
      primaryStage.setScene(scene); // Place the scene in stage
      primaryStage.show(); // Display the stage
   }

   /**
    * Creates a group and return it with 50 random shapes.
    * 
    * @return a {@link Group} populated with 50 random shapes.
    */
   private Group initializeRandomShape() {
      Random rand = new Random();
      // Create 50 rectangles
      Group group = new Group();
      for(int i = 0; i < 51; i++) {
         Rectangle r = new Rectangle();
         r.setX(rand.nextInt(600));
         r.setY(rand.nextInt(300));
         r.setWidth(rand.nextInt(90) + 10);
         r.setHeight(rand.nextInt(90) + 10);
         r.setFill(Color.color(Math.random(), Math.random(), Math.random()));
         r.setOpacity(Math.random());
         group.getChildren().add(r);
      }

      return group;
   }

   /**
    * @param pShape
    */
   public void changeDisplay(MyShape pShape) {
      Shape lSelectedShape = getSelectedShape(pShape.toString());

      if(lSelectedShape != null) {
         List<Shape> nodeList = new ArrayList<>();
         for(Node node: group.getChildrenUnmodifiable()) {
            if(Shape.class.isInstance(node)) {
               Shape lShape = changeShape(Shape.class.cast(node), pShape.isRectSelected());
               if(lShape != null) {
                  nodeList.add(lShape);
               }
            }
         }
         if(nodeList.size() > 0) {
            group.getChildren().clear();
            group.getChildren().addAll(nodeList);
         } else {
            // LOG an error with a logger.
            System.out.println("An error occurs.");
         }
      }
   }

   /**
    * Creates a shape according to the provided String.<br>
    * Enumerate could be used with String and Shape associated, it will be cleaner.
    * 
    * @param pString
    *           a {@link String} representing the selected shape by the user.
    * @return the {@link Shape} associated to the provided {@link String}.
    */
   private Shape getSelectedShape(String pString) {
      Shape lSelectedShape = null;
      if("Circle".equals(pString)) {
         lSelectedShape = new Arc();
      } else if("Rectangle".equals(pString)) {
         lSelectedShape = new Rectangle();
      }
      return lSelectedShape;
   }

   /**
    * Changes the provided shape by the new one (also provided).<br>
    * It actually extract the useful data of the current shape in order to parameterized the new
    * shape. If the new one is equal to the previous one, does nothing.
    * 
    * @param pCurrentShape
    *           the current shape to change.
    * @param pIsRectangleSelected
    *           a {@link Boolean} indicating if the selected shape by user is a rectangle.
    * @return the new created shape.
    */
   private Shape changeShape(Shape pCurrentShape, boolean pIsRectangleSelected) {
      Shape lShape;
      if(Rectangle.class.isInstance(pCurrentShape) && !pIsRectangleSelected) {
         Rectangle rect = Rectangle.class.cast(pCurrentShape);
         double centerX = rect.getX() + rect.getWidth() / 2;
         double centerY = rect.getY() + rect.getHeight() / 2;
         Arc arc = new Arc(centerX, centerY, rect.getWidth() / 2, rect.getHeight() / 2, 0, 360.0);
         arc.setFill(rect.getFill());
         arc.setOpacity(rect.getOpacity());
         lShape = arc;
      } else if(Arc.class.isInstance(pCurrentShape) && pIsRectangleSelected) {
         Arc lArc = Arc.class.cast(pCurrentShape);
         double lX = lArc.getCenterX() - lArc.getRadiusX();
         double lY = lArc.getCenterY() - lArc.getRadiusY();
         Rectangle rect = new Rectangle(lX, lY, 2 * lArc.getRadiusX(), 2 * lArc.getRadiusY());
         rect.setFill(lArc.getFill());
         rect.setOpacity(lArc.getOpacity());
         lShape = rect;
      } else {
         lShape = null;
         System.out.println("Not a rectangle : " + pCurrentShape);
      }
      return lShape;
   }

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

}