Skip to main content

Sane JavaFX GUI Code

JavaFX GUI Sanity



JavaFX GUI code can be quite chaotic. Such a situation makes it a challenge to understand the code and to troubleshoot it. 

JavaFX GUIs are simple in concept but if you try hard enough, you can disorganise it. Disorganised code is a sign of confusion which is a sign of deeper malaise....

JavaFX graphic user interfaces can be built up very systematically by following a simple process:

  • All the GUI is contained in a Stage. This Stage constitutes the visible application window though it does not have to be visible.
  • On this stage is placed a Scene which contains Panes to organise and hold GUI controls such as buttons and text boxes. However, bad programming practice allows a programmer to add controls directly to the Scene. The problem with this practice is that there is no way to lay out such controls in a systematic pattern such as horizontal list or in a grid formation.
  • Each Scene can have zero, one or more Panes. Panes can contain other Panes. Most Pane names end with the word Pane such as BorderPane, TilePane, GridPane, FlowPane or AnchorPane. Others like HBox or VBox do not.
  • Panes allow GUI controls to be placed in a systematic patter. The following illustration shows the common JavaFX layout panes.



The relationship between Stage, Scene, Panes and Controls can be illustrated as follows:

The Code...

Building a GUI is like putting up a building: There is some planning, some design and then the construction. They call it software engineering or system analysis and design depending on which school of software thought you belong to. We are at construction stage.

Systematic code will make it easier to get the job done. The following, in my opinion, is an example of well-organised code:

package javafxhandler1;


import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class StackPaneDemo1 extends Application {

    private StackPane stackPane; //Global variable

    @Override
    public void start(Stage primaryStage) throws Exception {
         //Create GUI Controls
            // Create Label
            Label label = new Label("I'm a Label");
            label.setStyle("-fx-background-color:yellow");
            label.setPadding(new Insets(5,5,5,5));   
                
            // Create Button   
            Button button = new Button("I'm a Button");       
            button.setStyle("-fx-background-color: cyan");
            button.setPadding(new Insets(5,5,5,5));
            
            Button controlButton = new Button("Change Top");
               
            // Create CheckBox
            CheckBox checkBox = new CheckBox("I'm a CheckBox");
            checkBox.setOpacity(1);
            checkBox.setStyle("-fx-background-color:olive");
            checkBox.setPadding(new Insets(5,5,5,5));
        
        //Create layouts
        // Create StackPane
        stackPane = new StackPane();
        stackPane.setPrefSize(300, 150);
        stackPane.setStyle("-fx-background-color: Gainsboro;-fx-border-color: blue;");
        //Add controls to StackPane
        stackPane.getChildren().add(label);
        stackPane.getChildren().add(button);
        stackPane.getChildren().add(checkBox);        

        //Create VBox
        VBox root = new VBox();
        VBox.setMargin(stackPane, new Insets(10, 10, 10, 10));
        VBox.setMargin(controlButton, new Insets(10, 10, 10, 10));
        //Add controls/panes to VBox
        root.getChildren().add(stackPane);
        root.getChildren().add(controlButton);
        root.setAlignment(Pos.CENTER);
        
        //Create Scene
        Scene scene = new Scene(root, 550, 250);
        
        //Stage
        primaryStage.setTitle("StackPane Layout Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
        
        //Create Event Handlers
        controlButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                changeTop();
            }
        });       
    }

    //Methods 
    private void changeTop() {
        ObservableList<Node> childs = this.stackPane.getChildren();

        if (childs.size() > 1) {
            //
            Node topNode = childs.get(childs.size()-1);
            topNode.toBack();
        }
    }
    
    //Redundant main method - required by some IDEs
    public static void main(String[] args) {
        launch(args);
    }
}

The simple arrangement consists of:

  • GUI Controls
  • Panes
  • Scene
  • Stage
  • Listeners/handlers
  • Methods

The universe is very very orderly and precise for the simple reason that it was created by a very very precise and orderly God. Why reinvent Design? Follow the Designer of designers...Simplify life.

Comments

Popular posts from this blog

LAMBDA EXPRESSIONS FOR HANDLING EVENTS

Event handlers form the core of any application. They define what happens when you click a button, press a key, select a menu and so on. The discussion on this site demonstrates how to use Lambda expressions to handle events. It is elegant and greatly simplifies your code. The old way of handling a button-click looks like this: Button btn = new Button(); btn.setText("Say 'Hello World'");  btn.setOnAction(new EventHandler<ActionEvent>() {       @Override       public void handle(ActionEvent event)       {           System.out.println("Hello World!");       }  }); The following is a Lambda expression using a "goes to" operator (->): Button button = new Button("Click"); button.setOnAction(value -> { label.setText("Clicked!"); }); Even more elegant: someButton.setOnAction(evt -> someM...

JavaFX: After Netbeans what next?

I have taught JavaFX as a User Interface tool for a number of years. Just as it matured, the owners of Java decided to pull it out of the standard Java JDK, therefore,  using JavaFX is no longer a trivial matter. I used Netbeans to edit and run JavaFX code but Netbeans is also afloat, now owned by Apache Foundation. The new Apache Netbeans doesn't seem to run JavaFX without considerable effort. I have given up on Nerbeans. Whereto now? What do we use for our JavaFX? Do we give up on JavaFX and move on to some other UI tool? Python? plain old java with AWT/SWING? Not a chance. JavaFX has some elegance difficult to attain with these other tools. Its simple tool. Why complicate life by adopting ageing tools that just dont meet the demands of our fast-paced 21st century? Therefore, there was a need to figure out what can serve to build UIs. I choose JavaFX again but after some examination, I found that the IDE that seems to work and is actively being developed is Intellij IDEA. C...