JAVA:按下按钮时在边框窗格中移动对象

问题描述 投票:0回答:1

我正在做一项家庭作业,我需要在窗格中创建一个圆圈并使用屏幕底部的按钮移动它。我能够让圆圈和按钮出现在窗格中,但是当我按下按钮时,圆圈不会移动。

我的主要方法如下:

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 方法的目的是检查移动圆圈是否会将其延伸到窗口边界之外,如果不会,则移动它。但按下按钮时圆圈永远不会移动。

java object javafx event-handling
1个回答
0
投票

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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.