我正在做一项家庭作业,我需要在窗格中创建一个圆圈并使用屏幕底部的按钮移动它。我能够让圆圈和按钮出现在窗格中,但是当我按下按钮时,圆圈不会移动。
我的主要方法如下:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class MoveBall extends Application {
@Override
public void start(Stage primaryStage) {
Circle ball = new Circle(10);
Button btUp = new Button("Up");
Button btDown = new Button("Down");
Button btLeft = new Button("Left");
Button btRight = new Button("Right");
HBox pane = new HBox();
BorderPane bPane = new BorderPane();
ball.setFill(Color.RED);
ball.setStroke(Color.BLACK);
pane.setSpacing(10);
pane.setAlignment(Pos.CENTER);
pane.getChildren().addAll(btUp, btDown, btLeft, btRight);
bPane.setCenter(ball);
bPane.setBottom(pane);
btUp.setOnAction((ActionEvent e) -> BallControl.moveUp(ball));
btDown.setOnAction((ActionEvent e) -> BallControl.moveDown(ball));
btLeft.setOnAction((ActionEvent e) -> BallControl.moveLeft(ball));
btRight.setOnAction((ActionEvent e) -> BallControl.moveRight(ball));
Scene scene = new Scene(bPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Move the Ball");
primaryStage.show();
}
public static void main (String[] args)
{
launch(args);
}
}
实际移动圆的方法在这里:
class BallControl{
public static void moveUp(Circle circle){
if(circle.getCenterY() - circle.getRadius() - 10 < 0) return;
circle.setCenterY(circle.getCenterY() - 10);
}
public static void moveDown(Circle circle){
if(circle.getCenterY() + circle.getRadius() + 10 > 400) return;
circle.setCenterY(circle.getCenterY() + 10);
}
public static void moveLeft(Circle circle){
if(circle.getCenterX() - circle.getRadius() - 10 < 0) return;
circle.setCenterX(circle.getCenterX() - 10);
}
public static void moveRight(Circle circle){
if(circle.getCenterX() + circle.getRadius() + 10 > 400) return;
circle.setCenterX(circle.getCenterX() + 10);
}
}
BallControl 方法的目的是检查移动圆圈是否会将其延伸到窗口边界之外,如果不会,则移动它。但按下按钮时圆圈永远不会移动。
A
BorderPane
是一种“布局窗格”,这意味着它将根据自己的算法布局其子节点。特别是,如果该节点可调整大小,并且在其最小、最大和首选大小指定的约束范围内,则 BorderPane
将扩展 center
区域中的节点以填充整个区域,然后将其居中地区。 A Circle
不可调整大小,因此它只是在该区域居中。
修改圆的
centerX
和 centerY
坐标在这里不会有帮助:圆的布局边界将是一个大约 20x20 像素的矩形(因为半径为 10,所以这是包含圆的最小矩形;“大约“这是因为笔划可能需要一些额外的空间)。该矩形将具有一个从中心半径开始并延伸到中心+半径的坐标系,但随后它将根据边框窗格的布局策略在中心区域居中。实际上,圆心的坐标发生了变化,但这些坐标仅在圆本身的坐标系内,而不在边框窗格的坐标系内。
一种解决方案是将圆包裹在常规的
Pane
中,不执行任何布局,并将 Pane
放置在 BorderPane
的中心。 Pane
是可调整大小的,因此 BorderPane
会将其大小调整为中心区域的完整大小。 Pane
不会对圆进行布局,因此它保持在由 centerX
和 centerY
定义的坐标处,无需任何其他布局。 (实际上,您使圆的坐标系与窗格的坐标系相同。)
请参阅布局文档了解更多详细信息。
这是使此工作正常进行的修改。请注意,我还修改了边界的计算方式,因此即使调整窗口大小,它仍然有效。
package org.jamesd.examples.movingball;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class MoveBall extends Application {
@Override
public void start(Stage primaryStage) {
Circle ball = new Circle(200, 200, 10);
Button btUp = new Button("Up");
Button btDown = new Button("Down");
Button btLeft = new Button("Left");
Button btRight = new Button("Right");
HBox controls = new HBox();
BorderPane bPane = new BorderPane();
ball.setFill(Color.RED);
ball.setStroke(Color.BLACK);
controls.setSpacing(10);
controls.setAlignment(Pos.CENTER);
controls.getChildren().addAll(btUp, btDown, btLeft, btRight);
Pane ballPane = new Pane(ball);
bPane.setCenter(ballPane);
bPane.setBottom(controls);
btUp.setOnAction((ActionEvent e) -> moveUp(ball));
btDown.setOnAction((ActionEvent e) -> moveDown(ball));
btLeft.setOnAction((ActionEvent e) -> moveLeft(ball));
btRight.setOnAction((ActionEvent e) -> moveRight(ball));
Scene scene = new Scene(bPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Move the Ball");
primaryStage.show();
}
public static void main (String[] args)
{
launch(args);
}
public void moveUp(Circle circle){
if(circle.getCenterY() - circle.getRadius() - 10 < 0) return;
circle.setCenterY(circle.getCenterY() - 10);
}
public void moveDown(Circle circle){
if(circle.getCenterY() + circle.getRadius() + 10 > circle.getParent().getBoundsInLocal().getHeight()) return;
circle.setCenterY(circle.getCenterY() + 10);
}
public void moveLeft(Circle circle){
System.out.println(circle.getBoundsInLocal());
if(circle.getCenterX() - circle.getRadius() - 10 < 0) return;
circle.setCenterX(circle.getCenterX() - 10);
}
public void moveRight(Circle circle){
if(circle.getCenterX() + circle.getRadius() + 10 > circle.getParent().getBoundsInLocal().getWidth()) return;
circle.setCenterX(circle.getCenterX() + 10);
}
}