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 } }