根据此代码,按钮(“放大”)将触发一个调用方法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());
}
}
答案 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
时)。