swing: the art of the gui

26
Swing: the art of the GUI COMP204, Bernhard Pfahringer

Upload: barrett-hall

Post on 30-Dec-2015

107 views

Category:

Documents


0 download

DESCRIPTION

Swing: the art of the GUI. COMP204, Bernhard Pfahringer. Swing. Swing is very powerful, but also complex built on top of AWT Swing classes start with J.., e.g. JFrame need (at least): import javax.swing.*; - PowerPoint PPT Presentation

TRANSCRIPT

Swing: the art of the GUI

COMP204, Bernhard Pfahringer

Swing Swing is very powerful, but also complex built on top of AWT

Swing classes start with J.., e.g. JFrame need (at least): import javax.swing.*; often Swing classes are subclasses of AWT classes,

e.g. javax.swing JFrame extends java.awt.Frame Swing GUIs use double-buffering (default) => no

flickering GUI elements are either:

Objects with specific function (e.g. JButton) Containers for GUI elements (e.g. JFrame)

Generic GUI app (composition)

Swing is NOT thread-safe, for efficiency reasons (see link on web-page for more details)

Need to be careful:

public static void main (String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new GUIClass().createAndShowGUI(); } });

cont. public void createAndShowGUI() { _frame = new JFrame(”Title"); // make sure closing exits

_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// // … more setup code // _frame.pack(); _frame.setVisible(true); }

Updating the display Whenever something changes (e.g. text of a JLabel), need to

call repaint() NEVER call paint directly Event handling thread queues repaint() request, will fuse

multiple calls on the same object into one, and eventually call paint

All Components have appropriate paint methods, but you can do your own, if you need (e.g. animation, see code example)

public void paint(Graphics g) { g.setColor(_color); g.fillOval(_x-_radius,_y-_radius,2*_radius,2*_radius);}

LayoutManagerContainer classes need to know where elements

go to on the screen:

Container content = getContentPane(); LayoutManager layout = new GridLayout(3, 2); content.setLayout(layout); _celsiusLabel = new JLabel("Celsius"); content.add(_celsiusLabel);

Typical: BorderLayout, FlowLayout, BoxLayout, CardLayout, GridBagLayout, …

see JavaDoc for details, and others

Buttons and ActionListenersSpecify interaction by attaching Listeners to GUI objects

JButton b = new JButton(“do it!”);b.addActionListener(new DoIt());…private class DoIt implements ActionListener {

public void actionPerformed( ActionEvent e) {// whatever

}}

Alternative: inheritance + interface implementation in one go

private class ColorButton extends JButton implements ActionListener {private Color c;

public ColorButton(Color c1, String name) {super(name);c = c1;addActionListener(this); // OURSELVES !!!

}

public void actionPerformed(ActionEvent e) { setFromColor(c);

}}

Abstract class: ButtonAdapter abstract class ButtonAdapter extends Jbutton

implements ActionListener { public ButtonAdapter(String name) {

super(name);addActionListener(this);

}public void actionPerformed(ActionEvent e) {

pressed();}public abstract void pressed();

}

UsageUse with anonymous class:

JPanel p = new JPanel();p.add(new ButtonAdapter(“Quit”) { public void pressed() {

System.exit(0);}

} );

MouseListener InterfaceFive events:

mousePressed(MouseEvent e)mouseReleased(..)mouseClicked(..)mouseEntered(..)mouseExited(..)

tedious to implement all when only one is needed: instead subclass abstract MouseAdapter

see also: MouseMotionListener

http://java.sun.com/docs/books/tutorial/uiswing/events/mouselistener.html

Animations: javax.swing.Timer ActionListener incrementYPosition = new ActionListener() {

public void actionPerformed(ActionEvent evt) { if (_y < 400) { _y++; if (_frame != null) _frame.repaint(); } else { _timer.stop(); } }};

_timer = new javax.swing.Timer(10,incrementYPosition);_timer.start();

Safe loading of an ImageIcon /** Returns an ImageIcon, or null if the path was invalid. */ protected static ImageIcon createImageIcon(String path) { java.net.URL imgURL = ButtonDemo.class.getResource(path); if (imgURL != null) { return new ImageIcon(imgURL); } else { System.err.println("Couldn't find file: " + path); return null; }}

ButtonDemo action method public void actionPerformed(ActionEvent e) { if ("disable".equals(e.getActionCommand())) { b2.setEnabled(false); b1.setEnabled(false); b3.setEnabled(true); } else { b2.setEnabled(true); b1.setEnabled(true); b3.setEnabled(false); } }

Setting up a buttonb1 = new JButton("Disable middle button", leftButtonIcon);b1.setVerticalTextPosition(AbstractButton.CENTER); //aka LEFT, for left-to-right locales b1.setHorizontalTextPosition(AbstractButton.LEADING)b1.setMnemonic(KeyEvent.VK_D);b1.setActionCommand("disable");b1.addActionListener(this);b1.setToolTipText("Click this button to disable the middle

button.");

JCheckbox Maintain/display labeled binary

state (on/off, yes/no, selected/unselected)

getLabel(), setLabel(String), isSelected(), setSelected() also: an ItemListener for an

ItemEvent

Trivial exampleimport javax.swing.*;import java.awt.*;import java.awt.event.*;

public class CheckBoxTest extends JFrame { private JCheckBox cb = new JCheckBox("off"); public static void main(String[] args) { CheckBoxTest w = new CheckBoxTest(); w.show(); }

cont.

public CheckBoxTest() { setTitle("CheckBoxTest"); setSize(300,70); cb.addItemListener(new CheckBoxTestListener()); add("Center", cb); }

private class CheckBoxTestListener implements ItemListener { public void itemStateChanged(ItemEvent e) { cb.setLabel( (cb.isSelected()) ? "ON" : "OFF"); } }

RadioButtonDemopublic class RadioButtonDemo extends JPanel implements ActionListener { static String birdString = "Bird"; …. JRadioButton birdButton = new JRadioButton(birdString); birdButton.setMnemonic(KeyEvent.VK_B); birdButton.setActionCommand(birdString); birdButton.setSelected(true); .... ButtonGroup group = new ButtonGroup(); group.add(birdButton); group.add(catButton); …

cont. birdButton.addActionListener(this); … JPanel radioPanel = new JPanel(new GridLayout(0, 1));

radioPanel.add(birdButton); … add(radioPanel, BorderLayout.LINE_START); add(picture, BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(20,20,20,20)); public void actionPerformed(ActionEvent e) { picture.setIcon(createImageIcon("images/" + e.getActionCommand() + ".gif"));}

Dialogs Special purpose window displayed shortly To notify, or ask simple questions Always attached to a Frame Modal: demands user response, prevents

further actions; show() won’t return until dismissed, setVisible(false)

Nonmodal: actions often placed into separate Thread

Dialog dig = new Dialog(this,false);

Dialog examplepublic class DialogTest extends JFrame { public static void main(String[] args) { DialogTest w = new DialogTest(); w.show(); }

private JTextArea d = new JTextArea(); private JCheckBox cb = new JCheckBox("Modal Dialog?");

public DialogTest() { setTitle("DialogTest"); setSize(300,220); add("West",cb); add("East",new MakeButton());

add("South",d); }

cont private void makeDialog(boolean modalFlag) { final JDialog dialog = new JDialog(this,modalFlag); dialog.setSize(100,100); dialog.add("North",new CountButton(1)); dialog.add("West",new CountButton(2)); dialog.add("East",new CountButton(3)); dialog.add("South", new ButtonAdapter("Hide") { public void pressed() { dialog.setVisible(false); } }); dialog.show(); }

cont. private class MakeButton extends ButtonAdapter {

public MakeButton() { super("Make Dialog"); }

public void pressed() { makeDialog(cb.isSelected()); }

}

private class CountButton extends ButtonAdapter { public CountButton(int value) { super("" + value); } public void pressed() { d.append("Button " + getLabel() + " pressed\

n"); } } }

JFileChooserimport javax.swing.filechooser.*;fc = new JFileChooser();

public void actionPerformed(ActionEvent e) { if (e.getSource() == openButton) {

int returnVal = fc.showOpenDialog(FileChooserDemo.this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); // … This is where a real application would open the file.

log.append("Opening: " + file.getName() + "." + newline); } else { log.append("Open command cancelled by user." + newline); } log.setCaretPosition(log.getDocument().getLength());

JMenuBar Attached to JFrame by setJMenuBar():

JMenuBar bar = new JMenuBar(); setJMenuBar(bar);

Add menus: JMenu HelpMenu = new JMenu(“Help”); bar.add(helpMenu);

Add menu items: JMenuItem quitItem = new JMenuItem(“Quit”); quitItem.addActionListener(new QuitListener()); helpMenu.add(quitItem);