Apache NetBeans has excellent support for developing desktop applications. By desktop applications, we mean applications that do not require a web or application server (even though one can be used in the back end), are installed in the user’s machine, and provide a richer Graphical User Interface (GUI) than the browser.
Historically, Abstract Window Toolkit (AWT) was the first GUI library released with JDK 1.0. The AWT is part of the Java Foundation Classes (JFC), the standard API for providing a GUI for a Java program. AWT’s components (or widgets) are “heavyweight” or native, which means that their look and feel (L&F) depended on the platform they were running (when run on Windows, a button would look like a Windows button; when run on MacOSX, like a MacOSX button etc.). AWT was multi-threaded, had only basic support of GUI components, and could run in the browser without the need for a plugin.
Swing was released with JDK 1.2 and was a replacement of AWT. Swing was developed to provide a more sophisticated set of “lightweight” GUI components (written entirely in Java and therefore platform independent) than the earlier Abstract Window Toolkit (AWT) ones. Swing provides a look and feel that emulates the look and feel of several platforms, and also supports a pluggable look and feel that allows applications to have a look and feel unrelated to the underlying platform. Swing follows a single-threaded programming model; all GUI related code is executed in the Event Dispatch Thread (EDT) . Additionally, the framework provides a layer of abstraction between the code structure and the graphic presentation of a Swing-based GUI.
JavaFX (https://openjfx.io/) is the most recent GUI library provided by Java to build rich GUIs or Rich Internet Applications (RIAs) that can run across a wide variety of devices. JavaFX abstracts the UI presentation (typically declared in an XML file – .fxml) from the actual logic (action events, etc.). This way one can use Cascading Style Sheets (CSS) to decorate the GUI without the need to recompile the application. JavaFX 1.0.2 was released in 2008. As of JDK 7u6 it has been integrated in the JDK. JavaFX 8 was included in JDK 8; however, as of JDK 11, JavaFX has again been separated from the JDK. JavaFX is actively maintained by Gluon (https://gluonhq.com/). While JavaFX is intended to be a replacement of Swing, both will stay on the market for quite some time.
Apache NetBeans Support for Desktop Applications
GUI Builder: this is where you design the GUI of your application. The GUI Builder, or Matisse, enables you to lay out forms by placing components where you want them and by providing visual feedback in the form of guidelines.
Navigator window: displays a tree hierarchy of all components contained in the currently opened form. These can be visual components and containers, such as buttons, labels, menus, panels, etc., as well as nonvisual components such as timers and data sources.
Palette window: contains groups of components or widgets that can be added to forms by drag and drop. The palette window can be customized to display its contents as icons only, or as icons with component names. With the help of the Palette Manager you add new components to the palette.
Properties window: allows changing the properties for the currently selected component, such as the displayed text, its size, etc. It also allows adding/modifying events and bindings.
Apache NetBeans supports development of desktop applications using either AWT, Swing, or JavaFX. The visual design capabilities are among NetBeans’ strongest features. Building prototypes of the application’s UI helps end users to state their requirements, and that’s one of the reasons visual GUI builders became so popular.
Typically, you create a new Java Application and then you add GUI components using wizards or by dragging and dropping widgets from the Palette.
Before you proceed, either open an existing Java Application NetBeans project, or create a new Java Application project, as shown in Figure 4-20, by selecting the File ➤ New Project menu item and clicking Next. In step 2 of the wizard, provide a project name and choose a suitable project location (anywhere in your hard disk) as shown in Figure 4-21. Then click Finish. Last, select the project or the Source Packages of the project in the Projects tab, and click on File ➤ New File as explained in the following sections.
AWT Support
Applet Form: creates a new java.applet.Applet. Applets are small applications that can run inside a (Java-enabled) browser.
Dialog Form: creates a new java.awt.Dialog within an application or Applet. Dialogs can be modal (the dialog is blocking the application waiting for user input) or modeless (the dialog is not blocking the application waiting for user input).
Frame Form: creates a new form that is based on java.awt.Frame and is usually used as the top-level window within an application.
Panel Form: creates a java.awt.Panel that can be added inside AWT containers such as Frames, Dialogs, or Applets.
Swing Support
JDialog Form: creates a new javax.swing.JDialog within an application. Dialogs can be modal or modeless.
JFrame Form: creates a new form that is based on javax.swing.JFrame, which is usually used as the top-level form within an application.
JInternalFrame Form: creates a new form that is based on javax.swing.JInternalFrame, which is used to implement multiple document interface (MDI) applications. These applications contain multiple resizable windows that are all displayed within the bounds of the application window (see https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html).
JPanel Form: creates a javax.swing.JPanel that can be used within Swing containers such as JFrames and JDialogs.
JApplet Form: creates a Swing applet that can be run from within a browser window that has the necessary Java Swing plugin. As applets have fallen out of favor and have been replaced by other technologies such as HTML5 and JavaScript, we won’t discuss them further in this book.
Bean Form: creates a new form based upon a JavaBean component.
Application Sample Form: creates a skeleton form application based on javax.swing.JFrame that contains the standard File, Edit, and Help menus created within the form. This can be a very useful starting point for the main window of your application.
MDI Application Sample Form: same as the previous skeleton form application, but it allows adding JInternalFrames to create an MDI application.
OK / Cancel Dialog Sample Form: creates a sample dialog (either modal or modeless) containing OK and Cancel buttons. You can use this template to create message boxes and any other dialogs.
Aligning Components
Source view displays the source code for the form.
Design view displays the GUI designer.
History displays the source code local history and can be useful if you need to revert to previous versions.
Selection mode: allows components to be selected.
Connection mode: allows creating connections between two components so that an event on one component can trigger an event on another component.
Preview design: allows previewing how the form will be displayed at runtime.
Align Left In Column: allows multiple components to be left-aligned.
Align Right In Column: allows multiple components to be right-aligned.
Center Horizontally: allows multiple components to be centered horizontally.
Align Top In Row: allows multiple components to be top-aligned.
Align Bottom In Row: allows multiple components to be bottom- aligned.
Center Vertically: allows multiple components to be centered vertically.
Change Horizontal Resizability: resize the selected component horizontally rather than being anchored to the left and right of other components.
Change Vertical Resizability: resize the selected component vertically rather than being anchored to the top and bottom of other components.
Matisse also allows a group of selected components to be centered down the axis of the first selected component. Horizontal and vertical centering are available. Multiple components must be selected; then all are centered on the widest selection. Another option allows centering components horizontally and vertically in their parent container. We shall see some examples later in this chapter.
Anchoring Components
As the name implies, anchoring a component to a position means that the component will stay in that position relative to other components or boundaries even if its container is resized.
You may also right-click on the widget and select Anchor ➤ (Left, Right, Top, Bottom) from the context menu.
Resizing Components
When we resize a form, anchored components move along to stay in their position while the form is resized, but they are not resized themselves.
You may also double-click on each of the surrounding empty spaces and define the exact size of the space using the Edit Layout Space dialog box.
To set two or more widgets to the same size, select them, right-click any one of them, and choose Set the Same Size ➤ Set Width (or Same Size ➤ Set Height) from the contextual menu.
Properties
Properties tab (see Figure 4-10): editable properties for the selected component can be edited in this section. Properties are usually grouped in the following groups: Properties, Other Properties, Layout, and Accessibility.
Events tab (see Figure 4-11): allows defining what actions are performed on a component when certain events (for example, mouse click, key pressed, etc.) are triggered. For example, to define an actionPerformed() on a button, click on the drop-down menu next to the actionPerformed event (a small black down arrow); a pop-up is displayed, suggesting a name for the event handler. This name consists of the name of the widget being edited, together with the name of the event. Upon selecting the name for the event handler, NetBeans automatically opens up the Source window, placing the caret ready for entering the event handler code. You will notice that the source code editor contains areas that cannot be edited. This is necessary because this code is automatically generated by the GUI Builder, and changing this code manually might break this binding between the code and the GUI designer. Finally, click on the … button in the GUI designer to add, remove, or rename an event handler.
Code tab (see Figure 4-12): allows providing custom code snippets for a component, for example, any pre/post initialization code, etc.
Note
Older versions of NetBeans (before the donation to Apache) had also a Binding tab. This has, unfortunately, been removed from Apache NetBeans due to licensing issues and due to the fact that JSR 295 (https://jcp.org/en/jsr/detail?id=295) has not become official. Take a look at this JIRA item (https://issues.apache.org/jira/browse/NETBEANS-530) for more information.
By directly editing its value,
By using the drop-down menu (if one exists),
By using the custom editor (via the … button).
Connection Tool
To view an example project that illustrates Swing forms, create a new project (menu File ➤ New Project), choose the Samples/Java category and the GUI Form Examples file type. The generated project contains three examples of Swing forms (Antenna, ContactEditor, and Find) that give you some ideas of the capabilities that Apache NetBeans IDE provides to design GUIs. The Anagram Game under the same category is another example.
JavaFX Support
Apache NetBeans allows you to create JavaFX projects by clicking on File ➤ New Project menu item. You may create Ant-based or Maven-based JavaFX projects. Select Java with Ant ➤ JavaFX category and choose one of the available JavaFX projects as shown in Figure 4-16. Or select the Java with Maven category and choose JavaFX Application project. In the first case, you can create a JavaFX application developing the GUI using Java code, or use an FXML file to script the GUI widgets of your application. You may also create an application that mixes Swing and JavaFX components.
Apache NetBeans doesn’t provide a GUI designer for JavaFX applications, like the Matisse GUI builder for Swing. One can, however, integrate SceneBuilder with NetBeans. SceneBuilder (see Figure 4-18) allows you to build JavaFX applications graphically. Oracle has stopped support of the SceneBuilder, which latest version is 2.0 (http://www.oracle.com/technetwork/java/javase/downloads/javafxscenebuilder-info-2157684.html). Gluon (https://gluonhq.com/products/scene-builder/) has taken over support and development of SceneBuilder. We shall see shortly how to set up Apache NetBeans to use SceneBuilder.
Sven Reimer’s Monet (http://plugins.netbeans.org/plugin/55434/monet-the-javafx-scene-builder-integration) plugin is an attempt to run SceneBuilder from within NetBeans to build the GUI of JavaFX applications the same way as when you use Matisse to build the GUI of your Swing applications.
- 1.
In Apache NetBeans, navigate to Tools ➤ Options ➤ Java ➤ JavaFX (Windows/Linux) or to NetBeans ➤ Preferences ➤ Java ➤ JavaFX (MacOSX), and click Activate if JavaFX support is not yet activated.
- 2.
After activation is finished, set the Scene Builder Home to be the Gluon directory (e.g., this is the path to /Applications/SceneBuilder.app in MacOS). Some Windows installers install SceneBuilder without asking you for a directory. SceneBuilder can be found in C:Users<User>AppDataLocalSceneBuilder or in C:Program FilesSceneBuilder.
- 3.
Click on OK and you are ready to start.
Note
If NetBeans complains with the message “Selected location ... does not represent a valid Java FX Scene Builder installation,” then do the following workaround.
- 1.
Navigate to the directory where SceneBuilder was installed,
- 2.
Enter app folder,
- 3.
Make a duplicate of SceneBuilder.cfg to SceneBuilder.properties in the same folder.
Developing a Swing Application
In NetBeans, create a new Java Application as shown in Figure 4-20, by selecting the File ➤ New Project menu item. In step 2 of the wizard, provide Todo as the project name and choose a suitable project location (anywhere in your hard disk) as shown in Figure 4-21. Then click Finish. Apache NetBeans creates the project containing a Java package named after the project name and a class named Main inside package todo.
Design the Main Tasks List Window
Create a new package by right-clicking on the todo package, selecting New ➤ Java package from the pop-up menu and giving the package name todo.view.
Now right-click the todo.view package icon and choose New ➤ Other (or choose File ➤ New File from the main menu), then select the Swing GUI Forms category and the JFrame Form file type (see Figure 4-4) and click Next.
An orange frame highlights the selected component (the JFrame content pane in Figure 4-1). The navigator displays all visual and nonvisual components of the JFrame, which is handy when you need to change the properties of a component hidden by another or one too small to be selected in the editor. On the right you see the component palette , which shows by default the standard Swing components (you can also add third-party JavaBeans by right-clicking on it and choosing Palette Manager), as well as the Properties windows. Properties are categorized to ease access to the ones most commonly used, and changed properties have their names highlighted in bold.
Repeat the process to insert a JLabel attached to the bottom of the JFrame. This label will be used as the status bar for the tasks window. Then add a JScrollPane, filling up the area between the JToolbar and the JLabel.
Now try resizing the JFrame content pane. The JToolbar, JLabel, and JScrollPane should resize to keep the borders attached to the JFrame’s corners and to each of the other borders.
You may give more descriptive names to the variables of the various widgets, by right-clicking on each of them in the Navigator window and selecting Change Variable Name from the pop-up menu. From the same context menu, you can modify the widget’s displayed text by selecting Edit Text action.
Next, let’s add a JTable inside the JScrollPane and create the toolbars’ buttons in order for the TasksWindow to start resembling the sketch of Figure 4-19.
You may use the icons provided together with the sources of this book. Copy the icons folder inside the Source Packages of the Todo project.
Non-Java files inside the Source Packages folder will be added by Apache NetBeans to the resulted application jar file that will be created inside the dist folder, and the application will be able to refer to them as classpath resources, no matter where the jar file is installed on the user machine. As a bonus, the application code doesn’t have to worry about platform-specific details like path separators and drive letters.
To add a button to the toolbar, drag it from the palette onto the toolbar. Clear the text property and click on the … button of the icon property to display the editor shown in Figure 4-24. Choose the appropriate package (icons) and the appropriate icon file.
Note
I use a convention to name the various widgets, called the Hungarian notation, which you are free to follow or not. In front of every widget’s variable name, I add three letters that describe the widget. For example, I use btn for buttons, lbl for labels, tbl for tables, etc. As you can see in Figure 4-24, I have named the first button as btnAddTask.
NetBeans also provides a customizer to define the JTable’s model property. Make sure to select the JTable widget from the Navigator window (and not the JScrollPane) and click on the … button of its model property. The dialog box of Figure 4-25 appears. I have edited the columns to look like the application we wish to develop. However, this customization is only useful for prototyping, as in the real application the model will be created from real (Task) objects. Typically, the customization of JTables will require the development of custom Java classes like cell renderers and editors, column models, etc.
Design the Task Details Dialog
According to Figure 4-19, there is a dialog to create/edit tasks. Right-click the todo.view package and select New ➤ Other. Select the Swing GUI Forms category and the JDialog Form file type (see Figure 4-4). Provide the class name TaskDetailsDialog and press Finish.
Add a JLabel attached to the left, top, and right borders of the dialog, with no spacing; it will serve as a message area for validation errors and the like. Rename it to lblMessageArea (right-click it in the Design view, then select Change Variable Name from the pop-up menu) and set its opaque property and the background color so that it looks like a band at the top of the dialog. Also add an EmptyBorder (border property) so there’s empty space around the text and the band’s borders.
Next add three JLabels for the description, priority, and due date fields (edit the text labels to Description, Priority, and Due Date respectively and rename the variables to lblDescription, lblPriority, lblDueDate respectively). Attach all three to the left of the JDialog internal area (the drawing area). Leave some spacing between the components and the border. Resize the two shorter labels to attach their right borders to the right border of the larger one. Then select the three labels (with Shift + click) and change the horizontalAlignment property to RIGHT.
Then add a JTextField next to the Description label (rename it to txtDescription) and a JSpinner (rename it to spPriority) next to the Priority label. Make sure that the guidelines keep the label and the field baseline aligned. The JSpinner does not provide any property to set a preferred or minimum width, while the JTextField uses the column property for this. However, you can resize the JSpinner and Matisse will set the component’s preferred size in pixels.
Note
Sizing GUI components in pixels is not guaranteed to work well in different platforms, or if your users change the default Swing Look and Feel (L&F). Use this Matisse feature with care!
For the due date, we can use a JFormattedText to save the date, but we shall see how to use a Date Picker Swing component instead. There are a number of available solutions, for example: JDatePicker (https://sourceforge.net/projects/jdatepicker/), JDateChooser (http://plugins.netbeans.org/plugin/658/jdatechooser-1-2), LGoodDatePicker (https://github.com/LGoodDatePicker/LGoodDatePicker) and the not maintained anymore SwingX JXDatePicker from SwingLabs (http://www.java2s.com/Code/Jar/s/Downloadswingxall165jar.htm). Unfortunately, none of them stores the picked date using the latest java.time.LocalDateTime. We will see how to integrate SwingX JXDatePicker from SwingLabs (it is left as an exercise to integrate any of the others if you wish). Download it and extract it to a folder on your machine.
Click on New Category button and give the name SwingX. Click the Add from JAR button, select the swingx-all-1.6.5.jar, from the location you downloaded previously, and click Next. In the next step, select all the available components and click Next. In the final step, choose the SwingX category you created earlier and click Finish. You just added a new category in the Palette that contains all the SwingX components.
Drag the JXDatePicker component on the TaskDetailsDialog form next to the Due Date label. Mainly, this is it. I let you explore the API of the widget to find out how to set the date format, if you are not happy with the default one, and how to get/set the date value.
Tip
OK, now that you learned the hard way, I must confess that there is an easier way. Once you have added the jar file of your library (e.g., swingx-all-1.6.5.jar) to your project (inside Libraries in the Projects tab), just expand the jar file, navigate to the class that is your widget, and drag it to your form. You don’t need to add the widget beans to the palette. For example, dragging org.desktop.swingx.JXDatePicker.class on the TaskDetailsDialog form has the same effect as dragging it from the palette.
To aid accessibility, it’s a good practice to set the labelFor property on a JLabel to describe which component the label is for. This can greatly enhance the performance of screen readers and other accessibility software.
Add a JLabel (label: Obs:, name: lblObs), a JScrollPane (name: spObs) and inside it add a JTextArea (name: txtaObs), a JCheckBox (text: Completed Task, name: chkCompleted), and four JButtons (text: Save, name: btnSave, text: Cancel, name: btnCancel, text: Clear, name: btnClear, text: Remove, name: btnRemove). The final TaskDetailsDialog form should look like the one in Figure 4-30.
btnClearActionPerformed() method
AddTask actionPerformed() method
Note
Apache NetBeans also added an action listener to the btnAddTask component under the hood (inside initComponents() method) so that this method would be invoked at the correct time.
Main.main() method
Our Todo prototype application is now complete, ready to be shown to your customers to get useful feedback before you begin implementing it.
Developing a JavaFX Application
We shall develop the Todo application of Figure 4-19 in JavaFX, too. We shall use a JDK with integrated JavaFX such as JDK 8 or 10. We shall see how to develop JavaFX applications with JDKs without JavaFX later.
There are two ways to develop a JavaFX application, either programmatically, using Java (JavaFX Application); or declaratively, declaring the GUI in a special XML format, called FXML (JavaFX FXML Application). We shall choose the second way here, which has also the advantage that you can use the SceneBuilder to graphically design the GUI.
The TodoFX project’s layout is shown in Figure 4-35.
If you need to create a JavaFX project using a JDK that doesn’t include JavaFX, like, for example, JDK 11 and later, you need to follow different steps as described in the JavaFX and NetBeans article (https://openjfx.io/openjfx-docs/#IDE-NetBeans).
Note
The Apache NetBeans JavaFX ant and Maven projects will be fixed to work correctly with JDK 11 and later versions in future Apache NetBeans versions.
With Scenebuilder you can quickly design your GUI by using a simple drag and drop of widgets, in a similar way that Matisse allows you to build Swing GUIs.
As this is not a book about JavaFX though, if you wish to develop TodoFX application, please follow this tutorial (http://wiki.netbeans.org/TodoFX).
Conclusion
In this chapter you learned how to develop Java Desktop Applications using the Apache NetBeans IDE. NetBeans allows you to build desktop applications using either AWT, or Swing or JavaFX. To develop Swing applications, Apache NetBeans provides a very advanced GUI Builder that has the code name Matisse. We saw the capabilities of Matisse and actually saw how to build a prototype application with it.
For more information about how to use the Matisse GUI Builder please refer to Chapter 11 of the “Developing Applications with NetBeans IDE” (https://docs.oracle.com/netbeans/nb82/netbeans/NBDAG/toc.htm) guide.
We also saw how we can integrate the SceneBuilder with NetBeans in order to develop JavaFX applications. Apache NetBeans provides GUI builders to build web applications, too. But let’s wait until the next chapter.