php editor Xinyi today introduces you to an interesting JAVA programming technique: moving objects in the border pane when pressing a button. This technique can add some interactivity to the user interface, allowing users to move objects by clicking buttons. The implementation method of this function is relatively simple. You only need to listen to the click event of the button and update the position of the object in the event processing method. In this way, we can provide users with a more vivid and interesting interface experience. Below we will introduce the implementation process of this technique in detail.
I'm doing a homework assignment where I need to create a circle in a pane and move it using the buttons at the bottom of the screen. I am able to get the circle and button to appear in the pane, but when I press the button the circle does not move.
My main method is as follows:
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); } }
The actual method of moving the circle is here:
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); } }
The purpose of the ballcontrol method is to check if moving the circle will extend it beyond the window bounds, and if not, move it. But when the button is pressed, the circle never moves.
borderpane
is a "layout pane", which means it will layout its child nodes according to its own algorithm. In particular, if the node is resizable and is within the constraints specified by its minimum, maximum, and preferred sizes, theborderpane
will expand the nodes in thecenter
region to fill the entire region , and then center it within that area.circle
is not resizable, so it only centers in that area.
Modifying the circle'scenterx
andcentery
coordinates won't help here: the circle's layout bounds will be a rectangle of about 20x20 pixels (since the radius is 10, this is The smallest rectangle that contains the circle; "approximately" here because the stroke may require some extra space). The rectangle will have a coordinate system that starts from and extends to the center radius, but then it will be centered in the center area according to the layout policy of the border pane. In fact, the coordinates of the center of the circle change, but these coordinates are only in the coordinate system of the circle itself, not in the coordinate system of the border pane.
One solution is to wrap the circle in a regularpane
that does not perform layout, and place thepane
in the center of theborderpane
. Thepane
is resizable, soborderpane
will resize it to the full size of the center area.pane
The circle is not laid out, so it remains at the coordinates defined bycenterx
andcentery
without any additional layout. (Actually, you make the circle's coordinate system the same as the pane's coordinate system.) This is the solution I'm using in the code below.
Another solution is to manipulate thetranslatex
andtranslatey
properties of the circle. These transformations are applied after layout.However, preventing the circle from leaving the bounds of its container becomes more complicated with this solution. (I'm not showing this solution in the code below.)
Seelayout documentationfor more details.
Here are the modifications to make this work. Note that I also modified how the bounds are calculated so it still works even if the window is resized.
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); } }
The above is the detailed content of JAVA: Move object in border pane when button pressed. For more information, please follow other related articles on the PHP Chinese website!