java - 如何调整多边形的大小?

标签 java javafx

我的任务是制作一个笑脸,当窗口调整大小时,它会适合边框。我可以让所有其他形状来做到这一点,但是当我尝试使用多边形时,我不知道该怎么做。因此,如果我能获得有关如何从 javafx.node.shape.Shape 包调整多边形大小的帮助,那就太好了。

一如既往地感谢您及时的帮助,如果我违反了许多规则,我深表歉意。

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.stage.Stage;
    import javafx.scene.shape.Polygon;
    import javafx.scene.shape.Ellipse;
    import javafx.scene.shape.*;

    public class smiley extends Application{
      @Override // Override the start method in the Application class
      public void start(Stage primaryStage) {
        Pane pane = new Pane();
        // Create a circle and set its properties
        Circle circle = new Circle();
        circle.centerXProperty().bind(pane.widthProperty().divide(2));
        circle.centerYProperty().bind(pane.heightProperty().divide(2)); 
        circle.setRadius(50);
        circle.setStroke(Color.BLACK);
        circle.setFill(null);

        Polygon nose = new Polygon();
        nose.getPoints().addAll(new Double[]{ 100.0, 90.0, 90.0, 120.0, 110.0, 120.0 });
        nose.setStroke(Color.BLACK);
        nose.setFill(null);

        Ellipse leftEye = new Ellipse();
        leftEye.centerXProperty().bind(pane.widthProperty().divide(2).add(20));
        leftEye.centerYProperty().bind(pane.heightProperty().divide(2).subtract(20));
        leftEye.setRadiusX(15.0f);
        leftEye.setRadiusY(10.0f);
        leftEye.setStroke(Color.BLACK);
        leftEye.setFill(null);

        Ellipse rightEye = new Ellipse();
        rightEye.centerXProperty().bind(pane.widthProperty().divide(2).subtract(20));
        rightEye.centerYProperty().bind(pane.heightProperty().divide(2).subtract(20));
        rightEye.setRadiusX(15.0f);
        rightEye.setRadiusY(10.0f);
        rightEye.setStroke(Color.BLACK);
        rightEye.setFill(null);

        Circle leftPupil = new Circle();
        leftPupil.centerXProperty().bind(pane.widthProperty().divide(2).add(20));
        leftPupil.centerYProperty().bind(pane.heightProperty().divide(2).subtract(20));
        leftPupil.setRadius(7);
        leftPupil.setStroke(Color.BLACK);

        Circle rightPupil = new Circle();
        rightPupil.centerXProperty().bind(pane.widthProperty().divide(2).subtract(20));
        rightPupil.centerYProperty().bind(pane.heightProperty().divide(2).subtract(20));
        rightPupil.setRadius(7);
        rightPupil.setStroke(Color.BLACK);

        Arc smile = new Arc();
        smile.centerXProperty().bind(pane.widthProperty().divide(2));
        smile.centerYProperty().bind(pane.heightProperty().divide(2).add(20));
        smile.setRadiusX(25.0f);
        smile.setRadiusY(10.0f);
        smile.setStartAngle(180.0f);
        smile.setLength(180.0f);
        smile.setType(ArcType.OPEN);
        smile.setFill(null);
        smile.setStroke(Color.BLACK);

        pane.getChildren().add(circle);
        pane.getChildren().add(nose);
        pane.getChildren().add(leftEye);
        pane.getChildren().add(rightEye);
        pane.getChildren().add(leftPupil);
        pane.getChildren().add(rightPupil);
        pane.getChildren().add(smile);

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane, 200, 200);
        primaryStage.setTitle("Assignment 14"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage


      }
    } 

最佳答案

从您的代码来看,您似乎并不是在谈论笑脸随着舞台的增大/缩小,而是在舞台调整大小时保持在舞台的中心。除了多边形 Nose 之外,所有笑脸部件都会这样做。 Nose 不这样做的原因是您已经使用固定在场景根部的 Pane 的坐标系定义了带有点的多边形。 如果您确实希望调整脸部大小而不仅仅是移动,那么您的方法将涉及相同概念的稍微不同的应用,特别是方法 2 的应用。

我可以想到两种方法来实现让 Nose 与脸部其他部分一起移动的目标,我将按优先顺序列出我的方法:

方法 1:专门针对面部的 Pane 。 不是让笑脸的每个子部分定义其相对于整个场景的位置,而是让笑脸的所有部分定义其相对于 Pane 的位置,该 Pane 的大小刚好足以容纳笑脸的外圆。然后定义该 Pane 相对于场景根 Pane 的位置。

我更喜欢这种方法的原因是它具有更好的封装性。例如,如果您后来决定希望整个笑脸在屏幕上移动,您只需定义代码来移动容器 Pane 而不是所有单独的部分。同样,添加新片段只需要在该 Pane 的坐标系中工作,因此您不必考虑确保它在整个场景中适当移动。

仅将脸部圆圈添加到此类 smileyPane 的示例代码片段。多边形和其余部分留作练习:-)

    //This pane is the root of the scene, and stretches with the
    //stage. It will hold the smileyPane.
    Pane rootPane = new Pane();

    double smileyRadius = 50.0;

    //This pane is just big enough to hold the outer circle of
    //the smiley face. It holds all the individual pieces that 
    //make up the face.
    Pane smileyPane = new Pane();
    rootPane.widthProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            double smileyPaneStartX = (newValue.doubleValue()/2)-(smileyRadius); 
            smileyPane.setLayoutX(smileyPaneStartX);
        }
    });

    rootPane.heightProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            double smileyPaneStartY = (newValue.doubleValue()/2)-(smileyRadius); 
            smileyPane.setLayoutY(smileyPaneStartY);
        }
    });

方法 2:监听外部 Pane 尺寸,用于重新计算 Nose 的位置。基本上,您定义一些在外部 Pane 的大小发生变化时运行的代码,以便您可以重新计算 Nose /多边形的正确位置。

  Polygon nose = new Polygon();
  nose.setStroke(Color.BLACK);
  nose.setFill(null);

  //Add initial nose position points
  nose.getPoints().addAll(new Double[]{ 100.0, 90.0, 90.0, 120.0, 110.0, 120.0 });
  pane.widthProperty().addListener(new ChangeListener<Number>(){
    @Override
    public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
        //The overall pane width changed. Recalculate the position of nose points
        //Actual position calculation left as exercise.
    }
  });

  //Similar thing needs to be done with height. Left as exercise.
<小时/>

我遗漏了一些部分,故意省略了整个解决方案。这显然是家庭作业。这应该足以让您开始,但希望您能通过自己填写这些内容学到一些东西!

关于java - 如何调整多边形的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33989761/

相关文章:

java - 将自定义类型的 FXML 属性设置为自定义 javafx 组件的属性

javafx - 我不明白关于在 JavaFX 和 SceneBuilder 中切换场景的代码

java - 将二维数组拆分为多个较小数组的数组?

java - SQLiteOpenHelper : OnCreate Function not called

java - ClassLoader loadClass() 的工作是什么

javafx - 标签的格式文本

javafx - 如何在基于 Gluon Mobile 的项目上设置图标?

java - 如何一次设置所有 Java Swing GUI 组件背景和前景(字体)颜色?

java - 使用 JPA (Hibernate) 获取旧实体

javafx 模块 javafx.scene.media.AudioClip 未找到