从集合中获取对象
Get Object from Collection
我正在用矩形构建网格。
我想单击其中一个矩形,它的颜色应该会改变。
但是,我不知道如何在创建 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;
}
}
有人可以帮我弄清楚如何在主文件中再次访问我的矩形吗?
与您当前的设计保持一致,您只需要测试鼠标是否在子项内单击以及该子项是否是 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
的 space1 。然后我们需要使用 Node.contains
测试 Rectangle
的边界是否包含这些坐标;如果是,请更改填充。
也就是说,您可能需要修改代码,以便将 an/the 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.即使它们不是直接子代,您仍然可以将坐标转换为本地 space。例如,您可以使用 Node.sceneToLocal
和 MouseEvent
提供的场景坐标(即 getSceneX()
/getSceneY()
)。
2。这仍然接近您的设计。但是,您可能需要重新考虑将事情纳入适当的 MVC(或其他)架构。
我正在用矩形构建网格。
我想单击其中一个矩形,它的颜色应该会改变。
但是,我不知道如何在创建 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;
}
}
有人可以帮我弄清楚如何在主文件中再次访问我的矩形吗?
与您当前的设计保持一致,您只需要测试鼠标是否在子项内单击以及该子项是否是 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
的 space1 。然后我们需要使用 Node.contains
测试 Rectangle
的边界是否包含这些坐标;如果是,请更改填充。
也就是说,您可能需要修改代码,以便将 an/the 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.即使它们不是直接子代,您仍然可以将坐标转换为本地 space。例如,您可以使用 Node.sceneToLocal
和 MouseEvent
提供的场景坐标(即 getSceneX()
/getSceneY()
)。
2。这仍然接近您的设计。但是,您可能需要重新考虑将事情纳入适当的 MVC(或其他)架构。