我对这个javafx ActionEvent代码感到困惑

时间:2018-03-31 07:27:49

标签: javafx actionevent

根据此代码,按钮(“放大”)将触发一个调用方法enlarge()的动作,该动作将执行:circle.setRadius(circle.getRadius()+ 2);

只是改变半径值。我不明白的是,仅仅改变半径将以某种方式使程序重绘整个圆圈。

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;


public class ControlCircle extends Application {

private CirclePane1 circlePane = new CirclePane1();
@Override
public void start(Stage primaryStage) {
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btEnlarge = new Button("Enlarge");
Button btShrink = new Button("Shrink");
hBox.getChildren().add(btEnlarge);
hBox.getChildren().add(btShrink);

btEnlarge.setOnAction(new EnlargeHandler());
btShrink.setOnAction(new ShrinkHandler());

BorderPane borderPane = new BorderPane();
borderPane.setCenter(circlePane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);

Scene scene = new Scene(borderPane, 200, 150);
primaryStage.setTitle("ControlCircle");
primaryStage.setScene(scene);
primaryStage.show();

}

class EnlargeHandler implements EventHandler<ActionEvent> {
    @Override
    public void handle(ActionEvent e) {
        circlePane.enlarge();
    }
}

class ShrinkHandler implements EventHandler<ActionEvent>{

    @Override
    public void handle(ActionEvent e) {
        circlePane.shrink();
    }
    }

}

class CirclePane1 extends StackPane{
private Circle circle = new Circle(50);

public CirclePane1() {

    getChildren().add(circle);
    circle.setStroke(Color.BLACK);
    circle.setFill(Color.WHITE);
}

public void enlarge() {
    circle.setRadius(circle.getRadius() + 2);

}

public void shrink() {
    circle.setRadius(circle.getRadius() > 2 ? circle.getRadius() - 2 
: circle.getRadius());
}
}

1 个答案:

答案 0 :(得分:0)

查看Circle的源代码,您可以看到如何定义radius属性:

private final DoubleProperty radius = new DoublePropertyBase() {

    @Override
    public void invalidated() {
        NodeHelper.markDirty(Circle.this, DirtyBits.NODE_GEOMETRY);
        NodeHelper.geomChanged(Circle.this);
    }

    @Override
    public Object getBean() {
        return Circle.this;
    }

    @Override
    public String getName() {
        return "radius";
    }
};

当您更改radius属性的值时,会调用其invalidated()方法。这就是&#34;魔术&#34;碰巧,它称之为以下两种方法:

    NodeHelper.markDirty(Circle.this, DirtyBits.NODE_GEOMETRY);
    NodeHelper.geomChanged(Circle.this);

现在,我不知道这些方法具体 - 我也没有时间/愿望研究它 - 但是他们告诉JavaFX运行时Circle需要重新绘制。这意味着下次渲染脉冲发生时(可能由这些方法触发),Circle将以其新半径绘制。

这一切都已经过优化,仅在适用的情况下才会重新绘制(例如仅在部分scene-graph时)。