/* MovingBallFX.java Copyright (c) Kari Laitinen http://www.naturalprogramming.com/ 2014-12-10 File created. 2014-12-27 Last modification. This program shows a ball that can be moved with buttons. The color of the ball can be adjusted with a ChoiceBox. */ import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.* ; import javafx.scene.control.* ; // Label, Button, ChoiceBox import javafx.scene.layout.* ; import javafx.stage.Stage; import javafx.geometry.* ; // Pos, Insets import javafx.scene.paint.Color; import javafx.scene.shape.Circle ; import javafx.collections.* ; // FXCollections etc. import javafx.beans.value.* ; // ChangeListener, ObservableValue import javafx.beans.binding.ObjectBinding ; public class MovingBallFX extends Application { public void start( Stage stage ) { Circle ball_on_screen = new Circle( 100, 100, 50, Color.RED ) ; ball_on_screen.setStroke( Color.BLACK ) ; // Black outline for the ball Button left_button = new Button( " < " ) ; Button up_button = new Button( " Up " ) ; Button down_button = new Button( " Down " ) ; Button right_button = new Button( " > " ) ; left_button.setOnAction( ( ActionEvent event ) -> { ball_on_screen.setCenterX( ball_on_screen.getCenterX() - 3 ) ; } ) ; up_button.setOnAction( ( ActionEvent event ) -> { ball_on_screen.setCenterY( ball_on_screen.getCenterY() - 3 ) ; } ) ; down_button.setOnAction( ( ActionEvent event ) -> { ball_on_screen.setCenterY( ball_on_screen.getCenterY() + 3 ) ; } ) ; right_button.setOnAction( ( ActionEvent event ) -> { ball_on_screen.setCenterX( ball_on_screen.getCenterX() + 3 ) ; } ) ; Label ball_coordinates_label = new Label() ; HBox ball_coordinates_pane = new HBox() ; ball_coordinates_pane.getChildren().add( ball_coordinates_label ) ; ball_coordinates_pane.setPadding( new Insets( 10, 0, 0, 10 ) ) ; // Next we'll specify that whenever the ball coordinates change, // the text inside the Label that shows the coordinates will be // changed as well. // First we'll build a Binding object to compute the coordinates text. ObjectBinding coordinates_text_binding = new ObjectBinding() { { super.bind( ball_on_screen.centerXProperty(), ball_on_screen.centerYProperty() ) ; } @Override protected String computeValue() { return "(" + (int) ball_on_screen.getCenterX() + ", " + (int) ball_on_screen.getCenterY() + ")" ; } }; ball_coordinates_label.textProperty().bind( coordinates_text_binding ) ; ObservableList selectable_color_names = FXCollections.observableArrayList( "Red", "Orange", "Yellow", "Green", "Blue", "Magenta", "Cyan", "Pink", "LightGray" ) ; ChoiceBox color_selection_box = new ChoiceBox(); color_selection_box.setItems( selectable_color_names ) ; color_selection_box.setValue( "Red" ) ; Color[] selectable_colors = { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN, Color.PINK, Color.LIGHTGRAY } ; color_selection_box.getSelectionModel(). selectedIndexProperty().addListener( ( observable_value, value, new_value ) -> { ball_on_screen.setFill( selectable_colors[ new_value.intValue() ] ) ; } ) ; HBox operations_pane = new HBox(); operations_pane.getChildren().addAll( left_button, up_button, down_button, right_button, color_selection_box ) ; operations_pane.setAlignment( Pos.CENTER ) ; // The Box is centered operations_pane.setSpacing( 16 ) ; // Put some space between buttons // With an Insets object we can specify empty space around the HBox. // There will be 20 pixels padding below the HBox. operations_pane.setPadding( new Insets( 0, 0, 20, 0 ) ) ; BorderPane border_pane = new BorderPane() ; border_pane.setTop( ball_coordinates_pane ) ; border_pane.setBottom( operations_pane ) ; StackPane stack_pane = new StackPane() ; // With the following statement we disble the automatic layout // management of the Circle object. ball_on_screen.setManaged( false ) ; stack_pane.getChildren().addAll( ball_on_screen, border_pane ) ; Scene scene = new Scene( stack_pane, 600, 480 ) ; // The ball will be positioned in the middle of the scene. ball_on_screen.setCenterX( scene.getWidth() / 2 ) ; ball_on_screen.setCenterY( scene.getHeight() / 2 ) ; stage.setTitle( "MovingBallFX.java" ) ; stage.setScene( scene ) ; stage.show(); } public static void main( String[] command_line_parameters ) { launch( command_line_parameters ) ; } } /* NOTES: The following links useful while developing this program: http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/choice-box.htm#BCEDJAEH http://stackoverflow.com/questions/14134397/how-to-disable-automatic-layout-for-a-javafx-group http://docs.oracle.com/javafx/2/ui_controls/choice-box.htm https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/Circle.html // Here is another possibility to set the listener for the ChoiceBox: color_selection_box.getSelectionModel(). selectedIndexProperty().addListener( new ChangeListener() { public void changed( ObservableValue observable_value, Number value, Number new_value ) { ball_on_screen.setFill( selectable_colors[ new_value.intValue() ] ) ; } } ) ; */