A GUI (Graphical User Interface)
application consists of at least two distinct components:
View: This represents the visual interface components
of the Graphical User Interface (GUI) application which
interacts with the user. The interaction is of an event-driven
nature where actions are initiated via keyboard and mouse.
Controller: This is the heart of
the control logic which associates user-generated events with actions.
It is important to keep these functions separate, putting them into different
classes where the classes reside in different packages.
The code which creates the view presentation is called Java Swing with classes and
interfaces mostly within the packages
The basis of most Java Swing GUI applications is a single object
created from an instance of a javax.swing.JFrame
Another common auxiliary view class is a javax.swing.JDialog extension.
Both JFrame and JDialog objects are swing Containers in that they hold
non-container objects, such as JButton and others,
which are responsible for capturing and presenting data
and generating events.
As indicated in our discussion,
we do not want these graphical components to be the handlers of the events.
The NetBeans Designer presents the visual components as forms which
are, in effect, combinations of an XML file (SomeClass.form) and a
Java source file (SomeClass.java).
The XML file specifies the visual interface used for constructing the component.
The two common Swing
forms are JFrame Form and JDialog Form.
The class contains portions of code which are
"designer generated" and not directly editable.
In Design mode, components can be configured easily via
point and click functionality. It is important to keep the Navigator
window active, as it reveals a hierarchy of window components used and allows
access to components not easily accessed otherwise.
NetBeans provides a Source mode available for editing the class
so that we can add our own interface methods
used by the non-graphical Controller class.
relieves us from the details of programming the add operations,
providing a simple drag-and-drop, point-and-click adding of components,
in particular through Palette menus,
The Properties, Set Text and
Change Variable Name features provides all the relevant
component settings and allows the user to easily set them.
Limitations of Designer
NetBeans Designer gives the option of creating a so-called
Desktop Application, but we do not want to use this
since it takes us too far afield from the basic Swing applications.
We will always work from Java Applications and add the
basic Swing containers (JFrame, JPanel, etc)
as NetBeans' visual forms.
The Designer does not really support our style of view/controller code separation.
For example, the JFrame Form automatically adds a main function, but this is
not where we want the application main function to be located.
More significantly, the Designer allows you to specify event handlers
for a components using the
Events sub-menu gotten from the right-click menu on the component.
There are two "lures" to add handler code say, for a button:
Right-click the button; select Events ⇾ Action ⇾ actionPerformed.
From the Window ⇾ IDE Tools ⇾ Properties. This may or may be
in the bottom, right, but you can make it appear. The
actionPerformed selection is accessible within the Events tab.
Please avoid this approach,
because both add the event handler code inside the view class.
The HelloGUI application
This is a very simple application which illustrates the desired controller/view
Please make sure the NetBeans Navigator (Window ⇾ Navigator)
window is visible as this window will frequently provide the easiest way
to access layout objects as well as other GUI components.
Create the initial structure
Select File ⇾ New Project
In the New Project window, select the Java category,
and choose Java Application.
In the New Java Application window, set this and click Finish.
Project Name: HelloGUI
The auto-generated hellogui package can serve as our
But we want a different Main class, so delete:
and, within the package hellogui, create
a new Main class with the name Controller, getting:
You can right-click on the package itself and create the class.
Now we want to create our views class. First we'll create the
views package. Right-click on the project, or "Source Packages" and select
New ⇾ Java Package
Give it the name views.
Right-click on the views package and select
New ⇾ JFrame Form.
The first time you do this on a system, you will have to locate this choice
through the "Other" selection, thereafter, it will appear directly:
New ( ⇾ Other ⇾ Swing GUI Forms ) ⇾ JFrame Form
The goal is to generate this class within the views package:
Alternatively, you can create the
You can create the views package and MyFrame class
both in one step when you create the JFrame Form by specifying
the class in the dialog:
(This step is optional)
Delete the main function in views.MyFrame.
Be carefult to delete only the main function and nothing else!
Go into Source mode, locate and delete it.
We never will use the auto-generated main function
in a view class.
Edit the class Controller.java.
Modify the code to be what is indicated.
The easiest thing to do is to select-copy and paste it over top
of the current Controller class code.
The first line sets the Frame's title in a generic way
and the second makes the frame appear centered within the screen.
Afterwards, the constructor
assigns event handlers to subcomponents of the frame (initially none).
The frame then "becomes visible" by the last line in main
where the visibilty property to true:
The initial layout of the JFrame created by Designer is called
Free Design. It is meant to be an easy drag-and-drop layout
which positions components at the desired (x,y) coordinate without further modifications.
Although this is not a good general-purpose layout, it is good enough for now.
Add a button
There are 3 distinct parts to this or any such operation:
Add and configure the component in Design mode in the frame.
Add the component interface access method in Source mode in the frame.
Add the event handler operations in the controller using the
interface access method.
Before we proceed, we'll restate our admonishment above:
First, the button. Edit views/MyFrame.java.
Initially it is presented in Design mode.
Right-click on the form and select
Set Layout. Observe the Free Design choice bolded,
indicating that this choice is the layout used by NetBeans in contrast
to the default Border Layout..
For simplicity we will keep this layout.
Add a JButton into the frame. You can do this in one of three ways:
Locate Button in the Swing Controls section of the
Palette window. Drag and drop it onto the frame.
Right-click on the JFrame, select
Add From Palette ⇾ Swing Controls ⇾ Button.
Locate the JFrame in the Navigator window.
Right-click on it and make the choices as in the previous item.
For now, the button can repositioned be anywhere.
Right-click on the button.
Select Edit Text and set the text to Hello.
Right-click on the button.
Select Change Variable Name... and set the new name to hello.
Next the access method.
Change to Source mode for views.MyFrame.
Add the access method, as depicted, just below the
Test it by running the application and pressing the button, looking for
the response in the output.
Add a TextField
The textfield we'll add will interact with the button in a simple way.
The idea is to enter text into the textfield, press the hello button
and have the text be converted to upper case. Here are the steps:
Access the frame in Design mode.
Add a JTextField object into the frame.
NetBeans Designer lists it as "Text Field."
Drag it to wherever you like.
Right-click on the textfield.
Select Edit Text and erase the initial text, resizing the textfield.
Again, select Change Variable Name ... and set the new variable name to
Edit the frame in Source mode. Add this access methods:
Make the textarea un-editable by the user.
This can be done directly by editing the Properties of the textarea, unchecking
the editable property, or it can be done directly in the controller code
by adding this line into the constructor:
Test it by running the application.
A point to bring out is that the newly
added count data member is considered to be part of the application's
state, like the frame member.
Local variables used in actionPerformed
If you try using count as a local variable instead of a member
variable, you'll get an error. Try commenting out
// private int count = 0;
and uncommenting the subsequent line:
int count = 0;
The error that comes up is this:
local variable referenced from an inner class must be final or effectively final
Trying to explicitly make it final won't work because of the "++count" usage.
In contrast, the other local variables
sampleTextArea, even though not declared final are
"effectively final" since they are not altered after being declared.
The status of count is like that of frame; they
are both "state variables" of the application.
Make a Standalone Application
At this point, HelloGUI, can be a standalone application since
all input and output are from the GUI application itself.
Check it for yourself, try running
Run ⇾ Clean and Build Project
or use the "Broom and Hammer" icon. It generates the file HelloGUI.jar
in the dist folder of the project (viewable through the Files window).
To get this JAR file to your desktop, you have to do so through
the file system explorer; but once you have done so, you can run it
by double-clicking on Windows or MAC.
Possibilities for the handler object
The event handler is an anonymous object instantiated from an
which implements the ActionListener interface
in the code used above:
These are overkill. As an inner or local class,
ButtonHandler only ever gets used once.
In the last case, the variable handler only gets used once.
Why do we need it these names? We don't.
An unnamed object of an
anonymous class provides the solution 99% of the time
saves us from having to invent names when
there is really no need for doing so.
Java 8 Lambda Expressions
Java 8 has
so called "lambda expressions" which can serve as event handlers.
These lambda expressesions can replace the anonymous inner classes
that we are using.
You'll see that NetBeans asks you whether you want to replace
what we have by a lambda expression equivalent. It is not
the purview (currently) of this class to explain lambda expressions.