Introduction
This article is meant for the individual who has little or no experience in Java GUI programming. As such, this paper will focus on the hierarchal tree structure that roots at the frame and goes into the content pane panel. The primary focus will then be on the button widget (control in .NET) and the corresponding method used to handle that event listener. Any .NET programmer will find these concepts extremely similar, except that the coding style requires more text is some cases and the terms used are different. A quick and easy way to compile this code on the command line after installing Sun's Java Runtime at www.java.com and Sun's J2EE SDK 5.0 is to go to the default directory: c:\Sun\SDK\JDK\bin> type con > somecode.java Ctrl-Z and then compile. To set your path:set PATH=%PATH%;.;C:\Sun\SDK\JDK\bin.
Java GUI programming involves two packages: the original abstract windows kit (AWT) and the newer Swing toolkit. Swing components have the prefix J to distinguish them from the original AWT ones (e.g. JFrame
instead of Frame
). To include Swing components and methods in your project, you must import the java.awt.*, java.awt.event.*, and javax.swing.* packages. Displayable frames are top-level containers such as JFrame
, JWindows
, JDialog
, and JApplet
, which interface with the operating system's window manager. Non-displaying content panes are intermediate containers such as JPanel
, JOptionsPane
, JScrollPane
, and JSplitPane
. Containers are therefore widgets or GUI controls that are used to hold and group other widgets such as text boxes, check boxes, radio buttons, et al. In .NET the main UI, called the Windows Form, holds the controls that are dragged and dropped onto the control surface. Every GUI starts with a window meant to display things. In Swing, there are three types of windows: the Applet, the Dialog, and the Frame. These interface with the windows manager. In swing, a frame
object is called a JFrame
. A JFrame
is considered the top most container. These are also called displayable frames. Non-displaying content panes are intermediate containers such as JPanel
, JScrollPane
, JLayeredPane
, JSplitPane
and JTabbedPane
which organize the layout structure when multiple controls are being used. Stated simply, the content pane is where we place out text fields are other widgets, so to add and display GUI controls, we need to specify that it is the content pane that we are adding to. The content pane is then at the top of a containment hierarchy, in which this tree-like hierarchy has a top-level container (in our case JFrame
). Working down the tree, we would find other top level containers like JPanel
to hold the components. Here is the code that produces a simple frame
upon to build on:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame1 extends JFrame
{
JPanel pane = new JPanel();
Frame1()
{
super("My Simple Frame"); setBounds(100,100,300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane();
con.add(pane);
setVisible(true);
}
public static void main(String args[]) {new Frame1();}
}
If you have never compiled Java code, then consider this basic code in order to show the compilation and interpretation process. As .NET compilers emit IL code and metadata, where the metadata tables are read by the CLR to verify type safety (that is, that the correct data types are passed to the correct methods), the JIT compiler converts the IL code into native code for execution. There is no interpretation as there is with the Java Virtual Machine. The Java platform is defined by the APIs (collections of compiled libraries for use programs and the JVM (which is similar to the CLR). A Java source code file is compiled into byte code wherein a class file is generated that functions as a blueprint for the runtime execution. Here is an example:
import java.util.*;
public class Sys {
public static void main(String[] args) {
System.out.println
("This is a string passed to the print line method of the System class");
}
}
c:\Sun\SDK\jdk\bin>javac.exe Sys.java // the javac.exe compiler
// compiles the source code
c:\Sun\SDK\jdk\bin>java.exe Sys // the java.exe interprets the byte code file
// (in the same directory where the class file is.
This is a string passed to the print line method of the System class.
Here is code that show a GUI with a button.
The button, however, does nothing when pressed:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame2 extends JFrame
{
JPanel pane = new JPanel();
JButton pressme = new JButton("Press Me");
Frame2()
{
super("JPrompt Demo"); setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane();
con.add(pane);
pressme.setMnemonic('P');
pane.add(pressme); pressme.requestFocus();
setVisible(true);
}
public static void main(String args[]) {new Frame2();}
}
C:\...\bin>Javac.exe Frame2.java
C:\...\bin>Java.exe Frame2
Java GUIs are event based as they respond to the standard input devices like key presses, mouse-clicks, radio buttons, etc. Here is the output of the button press:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame3 extends JFrame implements ActionListener
{
JLabel answer = new JLabel("");
JPanel pane = new JPanel();
JButton pressme = new JButton("Press Me");
Frame3()
{
super("Event Handler Demo"); setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane();
con.add(pane); pressme.setMnemonic('P');
pressme.addActionListener(this);
pane.add(answer); pane.add(pressme); pressme.requestFocus();
setVisible(true);
}
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if (source == pressme)
{
answer.setText("Button pressed!");
JOptionPane.showMessageDialog(null,"I hear you!","Message Dialog",
JOptionPane.PLAIN_MESSAGE); setVisible(true);
}
}
public static void main(String args[]) {new Frame3();}
}
The first step in adding a basic button push event handler to the above example is to import awt.event.* which contains all of the event classes. Next add the phrase implements ActionListener
to the class header to use the interface
. Register event listeners for each button widget using the addActionListener(this)
method. The reserved word this
indicates that the required (by implements ActionListener
) handler method called actionPerformed()
will be included in the current class. For example, consider this more colorful example:
import javax.swing.*;
import java.awt.Color;
public class ButtonDemo{
public JPanel createContentPane (){
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
JPanel titlePanel = new JPanel();
titlePanel.setLayout(null);
titlePanel.setLocation(10, 0);
titlePanel.setSize(250, 30);
totalGUI.add(titlePanel);
JLabel redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(100, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
titlePanel.add(redLabel);
JLabel blueLabel = new JLabel("Blue Team");
blueLabel.setLocation(120, 0);
blueLabel.setSize(100, 30);
blueLabel.setHorizontalAlignment(0);
blueLabel.setForeground(Color.blue);
titlePanel.add(blueLabel);
JPanel scorePanel = new JPanel();
scorePanel.setLayout(null);
scorePanel.setLocation(10, 40);
scorePanel.setSize(250, 30);
totalGUI.add(scorePanel);
JLabel redScore = new JLabel("0");
redScore.setLocation(0, 0);
redScore.setSize(100, 30);
redScore.setHorizontalAlignment(0);
scorePanel.add(redScore);
JLabel blueScore = new JLabel("0");
blueScore.setLocation(120, 0);
blueScore.setSize(100, 30);
blueScore.setHorizontalAlignment(0);
scorePanel.add(blueScore);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 80);
buttonPanel.setSize(250, 70);
totalGUI.add(buttonPanel);
JButton redButton = new JButton("Red Score!");
redButton.setLocation(0, 0);
redButton.setSize(100, 30);
buttonPanel.add(redButton);
JButton blueButton = new JButton("Blue Score!");
blueButton.setLocation(120, 0);
blueButton.setSize(100, 30);
buttonPanel.add(blueButton);
JButton resetButton = new JButton("Reset Score");
resetButton.setLocation(0, 40);
resetButton.setSize(220, 30);
buttonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
ButtonExample demo = new ButtonExample();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 190);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
OUTPUT
Nothing will happen when the buttons are pressed as the event listener is needed:
import javax.swing.*;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ButtonDemo_Extended implements ActionListener{
int redScoreAmount = 0;
int blueScoreAmount = 0;
JPanel titlePanel, scorePanel, buttonPanel;
JLabel redLabel, blueLabel, redScore, blueScore;
JButton redButton, blueButton, resetButton;
public JPanel createContentPane (){
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
titlePanel = new JPanel();
titlePanel.setLayout(null);
titlePanel.setLocation(10, 0);
titlePanel.setSize(250, 30);
totalGUI.add(titlePanel);
redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(120, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
titlePanel.add(redLabel);
blueLabel = new JLabel("Blue Team");
blueLabel.setLocation(130, 0);
blueLabel.setSize(120, 30);
blueLabel.setHorizontalAlignment(0);
blueLabel.setForeground(Color.blue);
titlePanel.add(blueLabel);
scorePanel = new JPanel();
scorePanel.setLayout(null);
scorePanel.setLocation(10, 40);
scorePanel.setSize(260, 30);
totalGUI.add(scorePanel);
redScore = new JLabel(""+redScoreAmount);
redScore.setLocation(0, 0);
redScore.setSize(120, 30);
redScore.setHorizontalAlignment(0);
scorePanel.add(redScore);
blueScore = new JLabel(""+blueScoreAmount);
blueScore.setLocation(130, 0);
blueScore.setSize(120, 30);
blueScore.setHorizontalAlignment(0);
scorePanel.add(blueScore);
buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 80);
buttonPanel.setSize(260, 70);
totalGUI.add(buttonPanel);
redButton = new JButton("Red Score!");
redButton.setLocation(0, 0);
redButton.setSize(120, 30);
redButton.addActionListener(this);
buttonPanel.add(redButton);
blueButton = new JButton("Blue Score!");
blueButton.setLocation(130, 0);
blueButton.setSize(120, 30);
blueButton.addActionListener(this);
buttonPanel.add(blueButton);
resetButton = new JButton("Reset Score");
resetButton.setLocation(0, 40);
resetButton.setSize(250, 30);
resetButton.addActionListener(this);
buttonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == redButton)
{
redScoreAmount = redScoreAmount + 1;
redScore.setText(""+redScoreAmount);
}
else if(e.getSource() == blueButton)
{
blueScoreAmount = blueScoreAmount + 1;
blueScore.setText(""+blueScoreAmount);
}
else if(e.getSource() == resetButton)
{
redScoreAmount = 0;
blueScoreAmount = 0;
redScore.setText(""+redScoreAmount);
blueScore.setText(""+blueScoreAmount);
}
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
ButtonDemo_Extended demo = new ButtonDemo_Extended();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(280, 190);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Suggested Reading
History
- 20th February, 2009: Initial post