Graphical User Interface Programming
Graphical User Interface Programming
When Java 1.0 was introduced, it contained a class library, called the Abstract
Window Toolkit (AWT), for basic GUI programming.
The basic AWT library deals with user interface elements by delegating their
creation and behavior to the native GUI toolkit on each target platform (Windows,
Linux, Macintosh, and so on).
For example, if you used the original AWT to put a text box on a Java window, an
underlying “peer” text box actually handled the text input.
Cont..
With peer-based approach user interface elements such as menus, scrollbars, and
text fields can have subtle differences in behavior on different platforms.
Moreover, some graphical environments (such as X11/Motif) do not have as rich a
collection of user interface components as does Windows or the Macintosh.
Developers complained that they had to test their applications on each platform—
a practice derisively called “write once, debug everywhere.”
Cont..
In 1996, Netscape created a GUI library they called the IFC (Internet Foundation Classes) that
user interface elements, such as buttons, menus, and so on, were painted onto blank windows.
Netscape’s IFC widgets looked and behaved the same no matter which platform the program ran
on.
Sun Microsystems worked with Netscape to perfect this approach, creating a user interface
library with the code name “Swing.”
Swing is now the official name for the non-peer-based GUI toolkit.
Swing is not a complete replacement for the AWT—it is built on top of the AWT architecture.
Swing simply gives you more capable user interface components.
Displaying Frames
A top-level window (that is, a window that is not contained inside another
window) is called a frame in Java.
The AWT library has a class, called Frame.
The Swing version of this class is called JFrame and extends the Frame class.
Most Swing component classes start with a “J”: JButton, JFrame, and so on.
A Simple Frame Example
import java.awt.*; import javax.swing.*;
public class SimpleFrameTest
{ public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{ var frame = new SimpleFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
} }
class SimpleFrame extends JFrame
{ private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public SimpleFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
} }
Inheritance Hierarchy For The Jframe
Most of the methods for working with the size and position of a frame come from the various
superclasses of JFrame.
Frame Properties
To draw on a component, you define a class that extends JComponent and override the
paintComponent method in that class.
The paintComponent method takes one parameter of type Graphics.
Painting occurs when the user increases the size of the window, or minimizes and then restores
the window.
The paintComponent method is called automatically whenever a part of your application needs to
be redrawn.
If you need to force repainting of the screen, call the repaint method instead of paintComponent.
Displaying text is considered a special kind of drawing.
Cont..
A component should tell its users how big it would like to be. Override the getPreferredSize method and
return an object of the Dimension class with the preferred width and height.
When you fill a frame with one or more components, and you simply want to use their preferred size, call
the pack method instead of the setSize method
import javax.swing.*; import java.awt.*;
public class NotHelloWorld
{ public static void main(String[] args)
{ EventQueue.invokeLater(() ->
{ var frame = new NotHelloWorldFrame();
frame.setTitle("NotHelloWorld");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true); } ); } }
class NotHelloWorldFrame extends JFrame
{ public NotHelloWorldFrame()
{ add(new NotHelloWorldComponent()); pack(); } }
class NotHelloWorldComponent extends JComponent
{ public static final int MESSAGE_X = 75, MESSAGE_Y = 100, DEFAULT_WIDTH = 300,
DEFAULT_HEIGHT = 200;
public void paintComponent(Graphics g)
{ g.drawString("Not a Hello, World program", MESSAGE_X, MESSAGE_Y); }
Event Handling
Any operating environment that supports GUIs constantly monitors events such as keystrokes or
mouse clicks.
These events are then reported to the programs that are running. Each program then decides what
to do in response to these events.
In the Java AWT, event sources (such as buttons or scrollbars) have methods that allow you to
register event listeners.
Event listeners are objects that carry out the desired response to the event.
Different event sources can produce different kinds of events.
For example, a button can send ActionEvent objects, whereas a window can send WindowEvent
objects.
Handling a Button Click
To implement the ActionListener interface, the listener class must have a method called
actionPerformed that receives an ActionEvent object as a parameter.
To create a button, specify a label string, an icon, or both in the button constructor. Here are two
examples:
var yellowButton = new JButton("Yellow");
var blueButton = new JButton(new ImageIcon("blue-ball.gif"));
Call the add method to add the buttons to a panel:
buttonPanel.add(yellowButton);
When a button is clicked, we want the background color of the panel to change to a particular
color.
Cont..
We then construct one object for each color and set the objects as the button listeners.
var yellowAction = new ColorAction(Color.YELLOW);
yellowButton.addActionListener(yellowAction);
Mouse Events
You do not need to handle mouse events explicitly if you just want the user to be able to click on
a button or menu.
These mouse operations are handled internally by the various components in the user interface.
However, if you want to enable the user to draw with the mouse, you will need to trap the
mouse move, click, and drag events.
When the user clicks a mouse button, three listener methods are called: mousePressed when the
mouse is first pressed, mouseReleased when the mouse is released, and, finally, mouseClicked.
For example let us see a simple graphics editor application that allows the user to place, move,
and erase squares on a canvas
Cont..
Cont..
When you click on a pixel that is not inside any of the squares that have been drawn, a new
square is added.
This is implemented in the mousePressed method so that the user receives immediate feedback
and does not have to wait until the mouse button is released.
When a user double-clicks inside an existing square, it is erased.
We implemented this in the mouseClicked method because we need the click count.
To distinguish between single, double, and triple (!) clicks, use the getClickCount method.
Cont..
public void mousePressed(MouseEvent event)
{
current = find(event.getPoint());
if (current == null) // not inside a square
add(event.getPoint());
}
public void mouseClicked(MouseEvent event)
{
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2)
remove(current);
}
Cont..
It also traps mouse motion events to change the cursor to a different shape (a cross hair) when it is over
a square.
This is done with the getPredefinedCursor method of the Cursor class.
A semantic event is one that expresses what the user is doing, Such as “clicking
that button”.
Low-level events are those events that make this possible, such as series of mouse
moves and keystroke for clicking a button.
Adjusting a scrollbar is a semantic event, but dragging the mouse is a low-level
event.
For example:
ActionEvent and AdjustmentEvent are a semantic events.
KeyEvent and MouseEvent are low-level events.
Event
Handling
Summar
y
Components with Swing
Layout Managers
Consider buttons that are contained in a JPanel object and are managed by the flow layout
manager, the default layout manager for a panel.
When you add more buttons to the panel, a new row is started when there is no more room.
Border Layout
The border layout manager is the default layout manager of the content pane of every JFrame.
Unlike the flow layout manager, which completely controls the position of each component, You
can choose to place the component in the center, north, south, east, or west of the content pane.
The edge components are laid out first, and the remaining available space is occupied by the center.
When the container is resized, the dimensions of the edge components are unchanged, but the center
component changes its size.
Add components by specifying a constant CENTER, NORTH, SOUTH, EAST, or WEST of the
BorderLayout class.
If you don’t supply any value, CENTER is assumed.
Cont..
frame.add(component, BorderLayout.SOUTH);
Cont..
Unlike the flow layout, the border layout grows all components to fill the available space.
And, if you were to add another button to the southern region, it would just displace the first
button.
So, create a new JPanel object, then add the individual buttons to the panel. Then, add the panel
to the content pane of the frame.
Grid Layout
The grid layout arranges all components in rows and columns like a spreadsheet. All components
are given the same size.
The usual way to add a text field to a window is to add it to a panel or other container.
It can be initialized by parameters to place string and column width.
The column width that you set in the JTextField constructor is not an upper limit on the number
of characters the user can enter.
The user can still type in longer strings, but the input scrolls when the text exceeds the length of
the field.
With JPasswordField class, each typed character is represented by an echo character, such as a
bullet (•).
With JTextArea component, the number of rows and columns for the text areacan be specified.
Cont..
var panel = new JPanel();
var textField = new JTextField("Default input", 20);
panel.add(textField);
textArea = new JTextArea(8, 40); // 8 lines of 40 columns each
Labels and Labeling Components
In Swing, a text area does not have scrollbars. If you want scrollbars, you have
to place the text area inside a scroll pane.
Scrollbars automatically appear if there is more text than the text area can display,
and they vanish again if text is deleted and the remaining text fits inside the area.
if you want to group the buttons for layout purposes, you also need to add them to
a container such as a JPanel.
Each radio button gets a different listener object.
we define an action listener that sets the font size to a particular value:
BorderFactory.createCompoundBorder.
Combo Boxes
Unlike radio buttons which take up too much screen space, when user clicks on combo boxes , a
list of choices drops down, and the user can then select one of them.
Cont..
Add the choice items with the addItem method.
combo.getItemAt(combo.getSelectedIndex())
Menus
A menu bar at the top of a window contains the names of the pull-down menus.
Clicking on a name opens the menu containing menu items and submenus.
Cont..
First, create a menu bar, then For each menu, create a menu object.
Add the top-level menus to the menu bar: menuBar.add(editMenu);
Add menu items, separators, and submenus to the menu object:
cutAction.putValue(Action.SMALL_ICON, new
ImageIcon("cut.gif"));
By default, the menu item text is placed to the right of the icon.
If you prefer the text to be placed on the left, call the setHorizontalTextPosition method that the
JMenuItem class inherits from the AbstractButton class.
cutItem.setHorizontalTextPosition(SwingConstants.LEFT);
Checkbox and Radio Button Menu Items
When the user selects the menu item, the item automatically toggles between checked and unchecked.
A pop-up menu is a menu that is not attached to a menu bar but floats somewhere.
Cont..
popup.add(item);
In Windows and Linux, the pop-up trigger is the nonprimary (usually, the right) mouse button.
To pop up a menu when the user clicks on a component, using the pop-up trigger, simply call the
method
component.setComponentPopupMenu(popup);
Keyboard Mnemonics
You can create a keyboard mnemonic for a menu item.
The keyboard mnemonic is displayed automatically in the menu, with the mnemonic letter
underlined.
If the mnemonic letter is not part of the menu string, then typing it still selects the item, but the
mnemonic is not displayed in the menu.
aboutAction.putValue(Action.MNEMONIC_KEY,
Integer.valueOf('A'));
You can specify which character you want to have underlined by calling the
setDisplayedMnemonicIndex method.
Keyboard Accelerators
accelerators are keyboard shortcuts that let you select menu items without ever opening a menu.
Use the setAccelerator method which takes an object of type Keystroke.
openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));
You can attach accelerators only to menu items, not to menus.
Enabling and Disabling Menu Items
Occasionally, a particular menu item should be selected only in certain contexts.
For example, when a document is opened in read-only mode, the Save menu item is not
meaningful.
A deactivated menu item is shown in gray and cannot be selected
Cont..
saveItem.setEnabled(false);
To do this, we must register a listener for the “menu selected” event.
public void menuSelected(MenuEvent event)
{
saveAction.setEnabled(!readonlyItem.isSelected());
saveAsAction.setEnabled(!readonlyItem.isSelected());
}
It does not work for menu items that also have accelerator keys.
Since the menu is never opened when the accelerator key is pressed, the action is never disabled,
and is still triggered by the accelerator key.
Dialog Boxes
The JOptionPane has four static methods to show these simple dialogs:
Components in a dialog
A dialog can have:
an icon, a message, and one or more option buttons
ERROR_MESSAGE INFORMATION_MESSAGE
WARNING_MESSAGE QUESTION_MESSAGE
PLAIN_MESSAGE
The PLAIN_MESSAGE type has no icon.
Each dialog type also has a method that lets you supply your own icon instead.
The message
For each dialog type, you can specify a message.
This message can be a string, an icon, a user interface component, or any other object.
The buttons
The buttons at the bottom depend on the dialog type and the option type.
When calling showMessageDialog and showInputDialog, you get only a standard set of buttons
(OK and OK/Cancel, respectively).
When calling showConfirmDialog, you can choose among four option types:
DEFAULT_OPTION YES_NO_OPTION
YES_NO_CANCEL_OPTION OK_CANCEL_OPTION
With the showOptionDialog you can specify an arbitrary set of options.
You supply an array of objects for the options.
Each array element can be rendered as String, Icon, Component or any other object.
Return values
The showConfirmDialog and showOptionDialog return integers to indicate which button the user
chose.
For the option dialog, this is simply the index of the chosen option or the value
CLOSED_OPTION if the user closed the dialog instead of choosing an option.
For the confirmation dialog, the return value can be one of the following:
if (selection == JOptionPane.OK_OPTION) . . .