我正在用矩形构建网格。
我要单击其中一个矩形,其颜色应更改。
但是,创建矩形后,我不知道如何在 Main 中访问矩形。
主要:
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args) {
launch(args);
}
public void changeColor(Pane p) {
p.setOnMouseClicked(me -> {
double posX = me.getX();
double posY = me.getY();
int colX = (int)(posX / 30);
int colY = (int) (posY / 30);
ObservableList<Node> children = p.getChildren();
for( Node d : children) {
if(d.getLayoutX() == colX && d.getLayoutY() == colY) {
// how can i access my rectangle here?
// basically, i want to be able to do .setFill()
}
}
});
}
@Override
public void start(Stage primaryStage) throws Exception {
Grid g = new Grid(30,30, 30);
Pane window = g.render();
Scene scene = new Scene(window, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
this.changeColor(window);
}
}
网格:
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class Grid {
Integer width, height, squareSize;
Color fill = Color.ALICEBLUE,
stroke = Color.BLACK;
public Grid(int x, int y, int squareSize){
this.width = x;
this.height = y;
this.squareSize = squareSize;
}
public Pane render() {
Pane p = new Pane();
Rectangle [][] rect = new Rectangle[this.width][this.height];
for(int i = 0; i < this.width; i++) {
for(int j = 0; j < this.height; j++) {
rect[i][j] = new Rectangle();
rect[i][j].setX(i * width);
rect[i][j].setY(j * height);
rect[i][j].setWidth(this.squareSize);
rect[i][j].setHeight(this.squareSize);
rect[i][j].setFill(this.fill);
rect[i][j].setStroke(this.stroke);
p.getChildren().add(rect[i][j]);
}
}
return p;
}
}
有人可以帮我弄清楚如何在主文件中再次访问矩形吗?
答案 0 :(得分:1)
按照当前的设计,您只需要测试鼠标是否在子级中单击,以及该子级是否为Rectangle
的实例;那么您可以投射并调用setFill
。但是,我建议更改changeColor
的名称,因为该名称并不代表该方法的作用。
public void installChangeColorHandler(Pane pane) {
pane.setOnMouseClicked(event -> {
for (Node child : pane.getChildren()) {
if (child instanceof Rectangle
&& child.contains(child.parentToLocal(event.getX(), event.getY()))) {
((Rectangle) child).setFill(/* YOUR COLOR */);
event.consume();
break;
}
}
});
}
由于事件处理程序已添加到Pane
,因此x
和y
鼠标坐标相对于所说的Pane
。但是由于您的Rectangle
是Pane
的直接子代,我们可以调用Node.parentToLocal
将这些坐标转换为Rectangle
的空间 1 。然后,我们需要使用Rectangle
测试Node.contains
的边界是否包含那些坐标;如果可以,请更改填充。
也就是说,您可能需要修改代码,以便将EventHandler
直接添加到Rectangle
中。这样,您可以使用Event.getSource()
。例如 2 :
public Pane render(EventHandler<MouseEvent> onClick) {
// outer loop...
// inner loop...
Rectangle r = new Rectangle();
// configure r...
r.setOnMouseClicked(onClick);
// end inner loop...
// end outer loop...
}
...
// may want to consume event
Pane window = new Grid(30, 30, 30).render(event ->
((Rectangle) event.getSource()).setFill(/* YOUR COLOR */));
1。即使他们不是直接的孩子,您仍然可以将坐标转换为局部空间。例如,您可以使用Node.sceneToLocal
和MouseEvent
提供的场景坐标(即getSceneX()
/ getSceneY()
)。
2。这仍然与您的设计保持接近。但是,您可能需要将事情重新考虑为适当的MVC(或其他)体系结构。 Applying MVC With JavaFx