This tutorial looks at GUI programming using the new JFC/Swing classes. It assumes a background of the AWT, and concentrates on additional features and changes from the AWT.
import javax.swing.*;
public class JHello extends JFrame {
public static void main(String argv[])
{
new JHello();
}
JHello() {
JLabel hello = new JLabel("Hello World");
getContentPane().add(hello, "Center");
setSize(200, 200);
setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class JButtonImage extends JFrame {
public static void main(String argv[]) {
new JButtonImage().setVisible(true);
}
public JButtonImage() {
ImageIcon image1 =
new ImageIcon("bart.gif");
ImageIcon image2 =
new ImageIcon("swing.small.gif");
JButton btn1 = new JButton(image1);
JButton btn2 = new JButton(image2);
Container pane = getContentPane();
pane.setLayout(new GridLayout(1, 2));
pane.add(btn1);
pane.add(btn2);
pack();
}
}
If the image has a transparent background (the second one),
it looks better on pressing the button
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestRollover extends JFrame {
static public void main(String argv[]) {
new TestRollover().setVisible(true);
}
public TestRollover() {
ImageIcon left =
new ImageIcon("left.gif");
ImageIcon leftRollover =
new ImageIcon("leftRollover.gif");
ImageIcon leftDown =
new ImageIcon("leftDown.gif");
JButton button = new JButton("Left",
left);
button.setPressedIcon(leftDown);
button.setRolloverIcon(leftRollover);
button.setRolloverEnabled(true);
button.setToolTipText(
"This is a Button with a RolloverIcon");
getContentPane().add(button, "Center");
pack();
}
}
Event
AWTEvent
The class AWTEvent has subclasses:
id value to distinguish between them
public interface ActionListener
extends EventListener {
public void actionPerformed(ActionEvent e);
}
public interface MouseListener
extends EventListener {
public void mouseClicked(MouseEvent e);
public void mousePressed(MouseEvent e);
public void mouseReleased(MouseEvent e);
public void mouseEntered(MouseEvent e);
public void mouseExited(MouseEvent e);
}
addActionListener()
addMouseListener()
import javax.swing.*;
import java.awt.event.ActionListener;
public class JDelegateDemo
extends JFrame {
public static void main(String argv[]) {
new JDelegateDemo().setVisible(true);
}
public JDelegateDemo() {
// create the GUI objects
JButton left = new JButton("Left");
JButton right = new JButton("Right");
JLabel label = new JLabel(" ",
SwingConstants.CENTER);
// set their geometry
Container pane = getContentPane();
pane.add(left, "West");
pane.add(right, "East");
pane.add(label, "Center");
pack();
// continue constructor
// create a listener and add it to each Button
SimpleListener simple =
new SimpleListener(label);
left.addActionListener(simple);
right.addActionListener(simple);
}
}
/**
* A listener object that is invoked
* when a Button is activated it finds
* the Button's label and sets it in a Label
*/
class SimpleListener implements ActionListener {
private JLabel label;
public SimpleListener(JLabel l) {
// the listener needs to know the Label
// it will act on
label = l;
}
public void actionPerformed(ActionEvent e) {
// get the label showing in whichever
// Button was pressed
String name = e.getActionCommand();
// set this in the Label object
label.setText(name);
}
}
import java.awt.*;
import java.awt.event.*;
public class MapKey extends Frame {
public static void main(String argv[]) {
new MapKey().setVisible(true);
}
public MapKey() {
TextField text = new TextField(20);
add(text);
pack();
text.addKeyListener(new ToUpper());
}
}
class ToUpper implements KeyListener {
public void keyTyped(KeyEvent e) {
// empty
}
public void keyPressed(KeyEvent e) {
e.setModifiers(Event.SHIFT_MASK);
}
public void keyReleased(KeyEvent e) {
// empty
}
}
AWTEvent.consume()
public class Alpha implements KeyListener {
public void keyPressed(KeyEvent e) {
if (! Character.isLetter(e.getKeyChar())) {
Toolkit.getDefaultToolkit().beep();
e.consume();
}
}
public void keyReleased(KeyEvent e) {
// empty
}
public void keyTyped(KeyEvent e) {
// empty
}
}
Toolkit.getDefaultToolkit().getSystemEventQueue()
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class TestBorder extends JFrame {
static public void main(String argv[]) {
new TestBorder().setVisible(true);
}
public TestBorder() {
Border border = BorderFactory.
createBevelBorder(
BevelBorder.RAISED);
JLabel label = new JLabel("Hello");
label.setBorder(border);
getContentPane().add(label, "Center");
pack();
}
}
import java.awt.*;
class TestBorderLayout extends JFrame {
public TestBorderLayout() {
Container pane = getContentPane();
pane.add(new JButton("Push Me W"), "West");
pane.add(new JButton("Push Me E"), "East");
pane.add(new JButton("Push Me S"), "South");
pane.add(new JButton("Push Me N"), "North");
setSize(400, 200);
setVisible(true);
}
}
public interface LayoutManager {
void addLayoutComponent(String name, Component comp);
void removeLayoutComponent(Component comp);
Dimension preferredLayoutSize(Container parent);
Dimension minimumLayoutSize(Container parent);
void layoutContainer(Container parent);
}
class SizeLayout implements LayoutManager {
Dimension size;
public SizeLayout() {
size = new Dimension(0, 0);
}
public SizeLayout(Dimension s) {
size = new Dimension(s);
}
public void setSize(Dimension s) {
size = new Dimension(s);
}
public Dimension getSize() {
return new Dimension(size);
}
public void
addLayoutComponent(String n, Component c) {
}
public void
removeLayoutComponent(Component c) {
}
public Dimension
preferredLayoutSize(Container parent) {
if (parent.countComponents() == 0)
return new Dimension(width, height);
// use the first component added
Component c = parent.getComponent(0);
return c.preferredSize();
}
public Dimension
minimumLayoutSize(Container parent) {
if (parent.countComponents() == 0)
return new Dimension(width, height);
// use the first component added
Component c = parent.getComponent(0);
return c.minimumSize();
}
public void
layoutContainer(Container parent) {
if (parent.countComponents() == 0)
return;
// use the first component added
Component c = parent.getComponent(0);
c.setBounds(0, 0, size.width, size.height);
c.validate();
}
}
GridBagLayout.
This manager gives a ``box of buttons'' layout
public class ButtonBoxLayout
implements LayoutManager {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constraints =
new GridBagConstraints();
public void
addLayoutComponent(String name, Component comp) {
// empty -this should never be called
}
public void
removeLayoutComponent(Component comp) {
// empty - no state maintained here
}
// the next three methods restore state
// if the parent has had changes done to
// its children, before calling gridbag
public Dimension
preferredLayoutSize(Container parent) {
if ( ! parent.isValid()) {
layoutButtons(parent);
}
return gridbag.preferredLayoutSize(parent);
}
public Dimension
minimumLayoutSize(Container parent) {
if ( ! parent.isValid()) {
layoutButtons(parent);
}
return gridbag.minimumLayoutSize(parent);
}
public void
layoutContainer(Container parent) {
if ( ! parent.isValid()) {
layoutButtons(parent);
}
gridbag.layoutContainer(parent);
}
/**
* Find the height of the first component,
* and add half of it
* above and below using ipady.
* Find the largest width, and set ipadx
* for all components to give it that width
*/
protected void layoutButtons(Container parent) {
int width = parent.getSize().width;
int nbuttons = parent.getComponentCount();
if (nbuttons == 0)
return;
constraints.weightx = 1.0;
// stretch each component vertically
constraints.ipady =
parent.getComponent(0).
getPreferredSize().height/2;
// find the largest width
Dimension compSize;
int maxWidth = 0;
for (int n = 0; n < nbuttons; n++) {
compSize = parent.getComponent(n).
getPreferredSize();
maxWidth = Math.max(compSize.width, maxWidth);
}
// use the largest width or increase
// using available space
maxWidth = Math.max(width/(nbuttons*2), maxWidth);
// set the ipadx to make each button the same size
for (int n = 0; n < nbuttons; n++) {
Component component = parent.getComponent(n);
compSize = component.getPreferredSize();
constraints.ipadx = maxWidth - compSize.width;
gridbag.setConstraints(component, constraints);
}
}
}
public class LabelledTextField extends JPanel {
protected JLabel label;
protected JTextField text;
public LabelledTextField(String lab, int cols) {
setLayout(new BorderLayout());
label = new JLabel(lab);
text = new JTextField(cols);
add(label, BorderLayout.WEST);
add(text, BorderLayout.CENTER);
}
public String getText() {
return text.getText();
}
public void addActionListener(ActionListener al) {
text.addActionListener(al);
}
}
public ButtonModel getModel();
public void setButtonModel(ButtonModel);
public ButtonUI getUI();
public void setUI(ButtonUI ui);
public boolean isSelected() {
return model.isSelected():
}
paint()
getPreferredSize()
getMinimumSize()
public class CountButtonModel
extends DefaultButtonModel {
protected int count = 0;
public int getCount() {
return count;
}
public void setPressed(boolean b) {
// b is true if pressed,
// false if released
super.setPressed(b);
if (b) {
count++;
}
}
}
public class CountButton extends JButton {
public CountButton() {
this(null, null);
}
public CountButton(Icon icon) {
this(null, icon);
}
public CountButton(String text) {
this(text, null);
}
public CountButton(String text, Icon icon) {
super(text, icon);
// Create the model
setModel(new CountButtonModel());
}
public int getCount() {
return ((CountButtonModel) model).getCount();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import CountButton;
public class TestCountButton extends JFrame
implements ActionListener{
static public void main(String argv[]) {
new TestCountButton().setVisible(true);
}
public TestCountButton() {
CountButton btn = new CountButton("Press me");
getContentPane().add(btn, BorderLayout.CENTER);
pack();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent evt) {
CountButton btn = (CountButton) evt.getSource();
System.out.println("Count: " + btn.getCount());
}
}
UIManager.setLookAndFeel(String)
SwingUtilities.updateComponentTreeUI(Component)
where the String is eg
"javax.swing.motif.MotifLookAndFeel" and
the Component is the toplevel Frame or Applet
String [] elmts = {"one", "two", "three"};
Jlist list = new JList(elmts);
import javax.swing.event.*;
import javax.swing.*;
public class TestList extends JFrame
implements ListSelectionListener {
static public void main(String argv[]) {
new TestList().setVisible(true);
}
public TestList() {
String [] elmts = {"one", "two", "three"};
JList list = new JList(elmts);
getContentPane().add(list, "Center");
pack();
list.addListSelectionListener(this);
}
public void valueChanged(ListSelectionEvent evt) {
JList list = (JList)
evt.getSource();
String value = (String)
list.getSelectedValue();
if (value != null &&
! evt.getValueIsAdjusting()) {
System.out.println("Selected: " +
value);
}
}
}
import javax.swing.event.*;
import javax.swing.*;
public class TestIconList extends JFrame
implements ListSelectionListener {
static public void main(String argv[]) {
new TestIconList().setVisible(true);
}
public TestIconList() {
ImageIcon images[] = new ImageIcon[2];
images[0] = new ImageIcon("bart.gif");
images[1] = new ImageIcon("swing.small.gif");
JList list = new JList(images);
getContentPane().add(list, "Center");
pack();
list.addListSelectionListener(this);
}
public void valueChanged(ListSelectionEvent evt) {
JList list = (JList) evt.getSource();
int value = list.getSelectedIndex();
if (value != -1 && ! evt.getValueIsAdjusting()) {
System.out.println("Selected: " + value);
}
}
}
import java.awt.*;
import javax.swing.event.*;
import javax.swing.*;
public class TestLabelList extends JFrame {
static public void main(String argv[]) {
new TestLabelList().setVisible(true);
}
public TestLabelList() {
JList list = new JList(new String [] {"Bart", "Swing"});
getContentPane().add(list, "Center");
list.setCellRenderer(new LabelCellRenderer());
pack();
}
}
class LabelCellRenderer extends JLabel
implements ListCellRenderer {
static protected ImageIcon images[] = {
new ImageIcon("bart.gif"),
new ImageIcon("swing.small.gif")
};
public LabelCellRenderer() {
setOpaque(true);
}
public Component
getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
setText(value.toString());
setIcon(images[index]);
setBackground(isSelected ?
Color.red : Color.white);
setForeground(isSelected ?
Color.white : Color.black);
return this;
}
}
import java.awt.*;
import javax.swing.event.*;
import javax.swing.*;
public class TestDrawList extends JFrame
implements ListSelectionListener {
static public void main(String argv[]) {
new TestDrawList().setVisible(true);
}
public TestDrawList() {
JList list = new JList(new String []
{"Circle", "Square"});
getContentPane().add(list, "Center");
list.setCellRenderer(new DrawCellRenderer());
// fix cell sizes since list doesn't know them
list.setFixedCellWidth(30);
list.setFixedCellHeight(30);
pack();
}
}
class DrawCellRenderer extends JComponent
implements ListCellRenderer {
protected int index;
boolean selected;
public boolean isOpaque() {
return true;
}
public Component
getListCellRendererComponent(
JList list,
Object value,
int index,
boolean selected,
boolean cellHasFocus) {
this.index = index;
this.selected = selected;
return this;
}
public void paint(Graphics g) {
Color fg, bg;
if (selected) {
fg = Color.green;
bg = Color.black;
} else {
fg = Color.red;
bg = Color.white;
}
// fill background
g.setColor(bg);
g.fillRect(0, 0, getWidth(), getHeight());
// draw shape
g.setColor(fg);
if (index == 0) {
g.fillOval(5, 5, 25, 25);
} else {
g.fillRect(5, 5, 25, 25);
}
}
}
JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().setView(list);
The model is known as a Document, and can be shared
between Text objects.
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
public class Text2 extends JFrame {
public static void main(String argv[]) {
new Text2().setVisible(true);
}
public Text2() {
JTextArea text1 = new JTextArea("starting text", 5, 30);
JTextArea text2 = new JTextArea(5, 30);
text2.setDocument(text1.getDocument());
Border border = BorderFactory.
createLineBorder(Color.black);
text1.setBorder(border);
text2.setBorder(border);
Container pane = getContentPane();
pane.setLayout(new GridLayout(2, 1));
pane.add(text1);
pane.add(text2);
pack();
}
}
StyleConstants.setForeground(style, Color.red)
JTextPane.setCharacterAttributes(Style, Boolean)
DefaultStyledDocument.setLogicalStyle(int, Style)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class TestStyle extends JFrame
implements ActionListener {
private Style redStyle, blueStyle, greenStyle;
private JTextPane text;
public static void main(String argv[]) {
new TestStyle().setVisible(true);
}
public TestStyle() {
JTextPane text = createEditor();
getContentPane().add(text, "Center");
setJMenuBar(createMenu());
setSize(200, 200);
}
private JMenuBar createMenu() {
JMenuBar mbar = new JMenuBar();
JMenu color = new JMenu("Color");
mbar.add(color);
JMenuItem mi = new JMenuItem("Red");
color.add(mi);
mi.addActionListener(this);
mi = new JMenuItem("Blue");
color.add(mi);
mi.addActionListener(this);
mi = new JMenuItem("Green");
color.add(mi);
mi.addActionListener(this);
return mbar;
}
public void actionPerformed(ActionEvent evt) {
Style style = null;
String color = (String) evt.getActionCommand();
if (color.equals("Red")) {
style = redStyle;
} else if (color.equals("Blue")) {
style = blueStyle;
} else if (color.equals("Green")) {
style = greenStyle;
}
text.setCharacterAttributes(style, false);
}
private JTextPane createEditor() {
StyleContext sc = createStyles();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);
return (text = new JTextPane(doc));
}
private StyleContext createStyles() {
StyleContext sc = new StyleContext();
redStyle = sc.addStyle(null, null);
StyleConstants.setForeground(redStyle,
Color.red);
blueStyle = sc.addStyle(null, null);
StyleConstants.setForeground(blueStyle,
Color.blue);
greenStyle = sc.addStyle(null, null);
StyleConstants.setForeground(greenStyle,
Color.green);
StyleConstants.setFontSize(greenStyle, 24);
return sc;
}
}
ActionListener a =
new StyledEditorKit.ForegroundAction(
"set-foreground-red",
Color.red);
mi.addActionListener(a);
JFileChooser and JColorChooser
have a convenience method to post a dialog
JFileChooser
doesn't work properly in Swing 1.0, but does in
JDK 1.2 beta 4
// using an embedded JFileChooser
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BasicChooser extends JFrame
implements ActionListener {
JFileChooser chooser;
static public void main(String argv[]) {
new BasicChooser().setVisible(true);
}
public BasicChooser() {
getContentPane().add(chooser = new JFileChooser(),
BorderLayout.CENTER);
chooser.addActionListener(this);
pack();
}
public void actionPerformed(ActionEvent e) {
System.out.println(chooser.getSelectedFile().
getName());
}
}
// using a JFileChooser in a dialog
import java.awt.*;
import javax.swing.*;
public class BasicChooser extends JFrame {
JFileChooser chooser;
static public void main(String argv[]) {
BasicChoser bc = new BasicChooser();
bc.setVisible(true);
chooser.showOpenDialog(bc);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You selected file: " +
chooser.getSelectedFile().getName());
}
}
public BasicChooser() {
setSize(100, 100);
}
}
JMenu(String label)creates a non-tearable menu.
JMenu(String label, boolean tearOff)allows control of this
JToolBar
AbstractAction looks after this
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TestAction extends JFrame {
OpenAction openAction = new OpenAction();
SaveAction saveAction = new SaveAction();
public static void main(String argv[]) {
new TestAction().show();
}
TestAction()
{
createMenu();
createToolBar();
setSize(300, 300);
}
private void createMenu()
{
JMenuBar mb = new JMenuBar();
JMenu fileB = new JMenu("File");
mb.add(fileB);
fileB.add(openAction);
fileB.add(saveAction);
setJMenuBar(mb);
}
private void createToolBar() {
JToolBar bar = new JToolBar();
bar.add(openAction);
bar.add(saveAction);
getContentPane().add(bar, BorderLayout.NORTH);
}
}
class OpenAction extends AbstractAction {
public OpenAction() {
super("Open", new ImageIcon("open.gif"));
}
public void actionPerformed(ActionEvent e) {
System.out.println("Open action");
}
}
class SaveAction extends AbstractAction {
public SaveAction() {
super("Save", new ImageIcon("save.gif"));
}
public void actionPerformed(ActionEvent e) {
System.out.println("Save action");
}
}
import javax.swing.*;
import java.awt.event.*;
public class TestWarning extends JFrame
implements ActionListener {
public static void main(String argv[]) {
new TestWarning().setVisible(true);
}
public TestWarning() {
JButton btn = new JButton("Show dialog");
getContentPane().add(btn, "Center");
pack();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(this,
"Warning",
"Warning Dialog",
JOptionPane.WARNING_MESSAGE);
}
}
import javax.swing.*;
import java.awt.event.*;
public class TestConfirmation extends JFrame
implements ActionListener {
public static void main(String argv[]) {
new TestConfirmation().setVisible(true);
}
public TestConfirmation() {
JButton btn = new JButton("Show dialog");
getContentPane().add(btn, "Center");
pack();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent evt) {
int response = JOptionPane.showConfirmDialog(this,
"Answer Yes or No",
"Confirmation Dialog",
JOptionPane.YES_NO_OPTION);
String responseStr = null;
if (response == JOptionPane.YES_OPTION) {
responseStr = "Yes";
} else {
responseStr = "No";
}
System.out.println("Response: " + responseStr);
}
}
import javax.swing.*;
import java.awt.event.*;
public class TestInput extends JFrame
implements ActionListener {
public static void main(String argv[]) {
new TestInput().setVisible(true);
}
public TestInput() {
JButton btn = new JButton("Show dialog");
getContentPane().add(btn, "Center");
pack();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent evt) {
String response = JOptionPane.showInputDialog(this,
"Enter name",
"Input Dialog",
JOptionPane.DEFAULT_OPTION);
System.out.println("Response: " + response);
}
}
registerKeyboardAction(), which adds
an ActionListener to specified keys
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class TestKeyboardAction extends JFrame
implements ActionListener {
protected JButton [] buttons = new JButton[9];
static public void main(String argv[]) {
new TestKeyboardAction().show();
}
public TestKeyboardAction() {
Container pane = getContentPane();
pane.setLayout(new GridLayout(3, 3));
Border border = BorderFactory.
createLineBorder(
Color.black);
KeyStroke up = KeyStroke.getKeyStroke(
KeyEvent.VK_UP, 0);
KeyStroke down = KeyStroke.getKeyStroke(
KeyEvent.VK_DOWN, 0);
KeyStroke left = KeyStroke.getKeyStroke(
KeyEvent.VK_LEFT, 0);
KeyStroke right = KeyStroke.getKeyStroke(
KeyEvent.VK_RIGHT, 0);
JRootPane rootPane = getRootPane();
rootPane.registerKeyboardAction(this,
"up", up,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
rootPane.registerKeyboardAction(this,
"down", down,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
rootPane.registerKeyboardAction(this,
"right", right,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
rootPane.registerKeyboardAction(this,
"left", left,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
for (int n = 0; n < 9; n++) {
JButton button = new JButton();
button.setBorder(border);
button.setName(new Integer(n).toString());
pane.add(button);
buttons[n] = button;
}
setSize(200, 200);
}
public void actionPerformed(ActionEvent e) {
Component focusOwner = getFocusOwner(); // Window method
String name = focusOwner.getName(); // get btn's name
int index = Integer.parseInt(name); // as an int
buttons[index].setText(""); // clear text
String action = e.getActionCommand();
// find next index for this action
if (action.equals("up")) {
index = (index < 3) ? index + 6 : index - 3;
} else if (action.equals("down")) {
index = (index > 5) ? index - 6 : index + 3;
} else if (action.equals("left")) {
index = (index == 0) ? index = 8 : index - 1;
} else { // assume right
index = (index == 8) ? index = 0 : index + 1;
}
buttons[index].setText("X"); // set text in next btn
buttons[index].requestFocus(); // and focus to it
}
}