More about GUI. Chapter 9

Chapter 9 More about GUI We now further explore the issue of how to develop GUI in Java. We will discuss several layout managers provided by the lang...
Author: Diana Bell
9 downloads 2 Views 156KB Size
Chapter 9

More about GUI We now further explore the issue of how to develop GUI in Java. We will discuss several layout managers provided by the language, particularly the standard class library, and techniques for organizing GUI containers into component hierarchies. We will also look at some of the special features available for some of those components. We will also introduce more new GUI components and events.

1

GUI review Let’s review what are available for GUI design. As we already discussed, a Java GUI consists of three basic pieces: components, events and listeners. When designing a GUI, users put down various components such as push buttons, check boxes and radio button, labels, and text fields, into containers. Those components generate events, caused by users’ action, and listeners handle those events when they occur with the preset programs. We also had a look at the component hierarchy, made available via inheritance, and the convenient adapter for various classes, e.g., mouse events and mouse action events.

2

GUI Design We put up a GUI to provide a better solution to a problem. The goal is to provide a product that is useful to the users. Thus, we have to have a good design first. The following are several goals for a good GUI design: We have to know the users and their needs. To a user, the interface is the software. We have to come up with a user interface so that users can avoid as many mistakes as possible. For example, if the input must be one of several choices, we should use radio button, but not check boxes.

3

We also should help users to optimize their abilities. For example, while providing tools to novice, we should also provide shortcut to those who are more capable. Finally, consistency is the key to success. Thus, we should provide a common environment, in terms of organization, color, style, etc..

4

Layout managers In addition to the basic pieces, another important piece is the use of layout managers. A layout manager is an object that governs how components are arranged in a container (e.g., a frame), such as size, position, etc.. Every container has a default layout manager, although we can always replace it with our own. The layout manager is always consulted whenever a change to the visual appearance of the contents of the associated container might be needed. For example, when the size of the container is adjusted, the layout manager will decide how the layout of all the components contained should be adjusted. So is the case when another component is added.

5

Border Layout There are various layout managers. With border layout specified, the system organize components into five areas (North, South, East, West, and Center). The following is an example.

6

Box Layout If the Box Layout is specified, the system will organize the components into a single row, or column. For example, the following shows an arrangement with the box layout.

Question: Where is the box layout used in the Window system? 7

Flow Layout With Flow Layout, the system will organize components from left to right, starting new rows if necessary. The following figure show two such arrangements, one with only one row, the other with two.

The Card Layout specification will organize components into one area such that only one is visible at a time. 8

Griding Layout With the Griding Layout specification, components will be organized into a grid of cells.

9

Replace layout managers Every layout manager has its own special rules that governs the layout of its components. For some of them, the order of addition plays a role about the position of the just added piece. Some of them also take the preferred size of components as a factor. Thus, it is important to know those rules before using or revising those managers. We can use the setLayout method of a container to change its layout manager. For example, the following code changes the layout manager of a JPanel from a default flow layout to a border layout manager. JPanel panel=new JPanel(); panel.setLayout (new BorderLayout()); 10

Demo of layout managers A tabbed pane is another container that allows a user to select, by clicking a tab, from several visible panes identified by names in their tabs. public class LayoutDemo{ public static void main (String[] args){ JFrame frame = new JFrame ("Layout Manager Demo"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JTabbedPane tp = new JTabbedPane(); tp.addTab ("Intro", new IntroPanel()); tp.addTab ("Flow", new FlowPanel()); tp.addTab ("Border", new BorderPanel()); tp.addTab ("Grid", new GridPanel()); tp.addTab ("Box", new BoxPanel()); frame.getContentPane().add(tp); frame.pack(); frame.show(); } }

11

The intro panel The intro panel simply adds in two labels, giving out some introductory messages. public class IntroPanel extends JPanel{ public IntroPanel(){ setBackground (Color.green); JLabel l1=new JLabel("Layout Manger Demonstration"); JLabel l2=new JLabel("Choose a tab to see an" +" example of a layout manager."); add (l1); add (l2); } }

Question: Why are the two messages put back to back in this panel? Answer: The default layout manager for a JPanel object is the flow layout. 12

The flow panel The flow panel puts as many components, in this case, five buttons, as possible in a row. public class FlowPanel extends JPanel{ public FlowPanel (){ setLayout (new FlowLayout()); setBackground (Color.green); JButton JButton JButton JButton JButton

b1 b2 b3 b4 b5

= = = = =

new new new new new

JButton JButton JButton JButton JButton

("BUTTON ("BUTTON ("BUTTON ("BUTTON ("BUTTON

1"); 2"); 3"); 4"); 5");

add (b1); add (b2); add (b3); add (b4); add (b5); } }

Question: How to make those buttons work? Answer: We have to add in a listener for each button. 13

The border panel The border layout organizes components in five areas. A user can actually specify which component is put in which area. The four corner areas become as big as needed for the components, and if none is assigned, it will not take up any space. The Center area expands to fill in any unused space. public class BorderPanel extends JPanel{ public BorderPanel(){ setLayout (new BorderLayout()); setBackground (Color.green); JButton JButton JButton JButton JButton add add add add add

b1 b2 b3 b4 b5

(b1, (b2, (b3, (b4, (b5,

= = = = =

new new new new new

JButton JButton JButton JButton JButton

("BUTTON ("BUTTON ("BUTTON ("BUTTON ("BUTTON

1"); 2"); 3"); 4"); 5");

BorderLayout.CENTER); BorderLayout.NORTH); BorderLayout.SOUTH); BorderLayout.EAST); BorderLayout.WEST);

} } 14

The grid panel The grid layout organizes components in a rectangular grid of rows and columns, and all cells are of same size. The number of rows and columns for such a grid is given as parameters to the constructor when the layout manager is created. For example, the following example sets the number of rows and columns to be 2 and 3, respectively. public class GridPanel extends JPanel{ public GridPanel(){ setLayout (new GridLayout (2, 3)); setBackground (Color.green); JButton JButton JButton JButton JButton

b1 b2 b3 b4 b5

add (b1); add (b4);

= = = = =

new new new new new

JButton JButton JButton JButton JButton

add (b2); add (b5);

("BUTTON ("BUTTON ("BUTTON ("BUTTON ("BUTTON

1"); 2"); 3"); 4"); 5");

add (b3);

} } 15

The box layout The box layout organizes components in either one row or one column. When a BoxLayout object is created, we specify that it either follows the x direction, or the y direction, using containers defined in the BoxLayout class. public class BoxPanel extends JPanel{ public BoxPanel(){ setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); setBackground (Color.green); JButton JButton JButton JButton JButton add add add add add add add

b1 b2 b3 b4 b5

= = = = =

new new new new new

JButton JButton JButton JButton JButton

("BUTTON ("BUTTON ("BUTTON ("BUTTON ("BUTTON

1"); 2"); 3"); 4"); 5");

(b1); (Box.createRigidArea (new Dimension (0, 10))); (b2); (Box.createVerticalGlue()); (b3); add (b4); (Box.createRigidArea (new Dimension (0, 20))); (b5);

} } 16

The containment hierarchy The way components are grouped together into containers, and the way containers are nested with each other, establishes the containment hierarchy for a GUI. There is generally one primary containment at the top, called a top-level container, such as a frame or an applet. This top level container usually contains a few other containers, such as panels. Those panels may contain other panels as desired. Now the structure begins to form. Each container could have its own layout manager. The final appearance of a GUI is a function of the chosen layout managers and the design of the containment hierarchy. There could be many combination, and there is rarely the best option. 17

The overall interface Below shows the overall layout of an interface, with the guidelines provided by the containment hierarchy tree as shown in Figure 9.7.

Question: Between the hierarchy and the visual appearance, which one comes first? 18

A design example Below shows the hierarchy of a design.

Homework: Compare Figure 9.7 and the above interface, and complete Exercises 9.1, 9.6 and 9.7. 19

Special features Many Swing components have special features that enhance and facilitate their use. Tool tip will show a line when the mouse cursor stops over a component. For example, JButton button=new JButton("Computer"); button.setToolText("Calculates the area under the curve.")’ Mnemonic allows an action, such as a button push, to occur when a keyborad combo is pressed. For example, button.setMnemonic(’C’); Enable/Disable allows a component to be enabled or disabled when appropriate. For example, button.setEnabled(false); 20

Another example The following program presents an image of a light bulb and provides a button to turn it on and a button to turn it off.

21

Set up the bulb The following program sets up the basic configuration of a bulb. public class LightBulb{ public static void main (String[] args){ JFrame lightBulbFrame = new JFrame ("Light Bulb"); lightBulbFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); LightBulbPanel bulb=new LightBulbPanel(); LightBulbControls controls=new LightBulbControls(bulb); JPanel panel = new JPanel(); panel.setBackground(Color.black); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.add(Box.createRigidArea(new Dimension (0, 20))); panel.add(bulb); panel.add(Box.createRigidArea(new Dimension (0, 10))); panel.add(controls); panel.add(Box.createRigidArea(new Dimension (0, 10))); lightBulbFrame.getContentPane().add(panel); lightBulbFrame.pack(); lightBulbFrame.show(); } } 22

How to put up a bulb? The following program sets up the basic configuration of a bulb. public class LightBulbPanel extends JPanel{ private boolean on; private ImageIcon lightOn, lightOff; private JLabel imageLabel; public LightBulbPanel(){ lightOn = new ImageIcon ("lightBulbOn.gif"); lightOff = new ImageIcon ("lightBulbOff.gif"); setBackground (Color.black); on = true; imageLabel = new JLabel (lightOff); add (imageLabel); } public void paintComponent (Graphics page){ super.paintComponent(page); if (on) imageLabel.setIcon (lightOn); else imageLabel.setIcon (lightOff); } public void setOn (boolean lightBulbOn){ on = lightBulbOn; } }

Question: What happens if replacing on=true; with on=false; in the constructor? Why? 23

How to light up a bulb? The following program adds the control buttons to a control panel. public class LightBulbControls extends JPanel{ private LightBulbPanel bulb; private JButton onButton, offButton; public LightBulbControls (LightBulbPanel bulbPanel){ bulb = bulbPanel; onButton = new JButton ("On"); onButton.setEnabled (false); onButton.setMnemonic (’n’); onButton.setToolTipText ("Turn it on!"); onButton.addActionListener (new OnListener()); offButton = new JButton ("Off"); offButton.setEnabled (true); offButton.setMnemonic (’f’); offButton.setToolTipText ("Turn it off!"); offButton.addActionListener (new OffListener()); setBackground (Color.black); add (onButton); add (offButton); } }

Question: Where is bulb used in the method? 24

The listeners The following listeners monitor the clicking of the buttons. private class OnListener implements ActionListener{ public void actionPerformed (ActionEvent event){ bulb.setOn (true); onButton.setEnabled (false); offButton.setEnabled (true); bulb.repaint(); } } private class OffListener implements ActionListener{ public void actionPerformed (ActionEvent event){ bulb.setOn (false); onButton.setEnabled (true); offButton.setEnabled (false); bulb.repaint(); } }

Question: How is the bulb lit up? Homework: Complete Exercise 9.2. 25

Another feature Border provides a few border style to be chosen to surround a component. Empty border merely puts some buffering space around a component. Line border adds a single line around the component. Etched border creates the effect of an etched groove around. Bevel border raises the component above the surface. Titled border adds a title. Mattle border allows to specify the size of each edge. They can also be combined with the compound border feature, e.g, the following p7. 26

What to do... to set up the following GUI to demonstrate the effects of various border style?

Answer: Check out the next few pages.

27

The code starts here... import java.awt.*; import javax.swing.*; import javax.swing.border.*; public class BorderDemo{ public static void main (String[] args){ JFrame frame=new JFrame ("Border Demo"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JPanel panel=new JPanel(); panel.setLayout(new GridLayout (4, 2, 5, 10)); panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); JPanel p1=new JPanel(); p1.setBorder(BorderFactory.createLineBorder(Color.red,3)); p1.add (new JLabel ("Line Border")); panel.add (p1); JPanel p2=new JPanel(); p2.setBorder(BorderFactory.createEtchedBorder()); p2.add(new JLabel("Etched Border")); panel.add (p2);

28

JPanel p3 = new JPanel(); p3.setBorder (BorderFactory.createRaisedBevelBorder()); p3.add (new JLabel ("Raised Bevel Border")); panel.add (p3); JPanel p4 = new JPanel(); p4.setBorder (BorderFactory.createLoweredBevelBorder()); p4.add (new JLabel ("Lowered Bevel Border")); panel.add (p4); JPanel p5 = new JPanel(); p5.setBorder (BorderFactory.createTitledBorder("Title")); p5.add (new JLabel ("Titled Border")); panel.add (p5); JPanel p6 = new JPanel(); TitledBorder tb=BorderFactory.createTitledBorder("Title"); tb.setTitleJustification (TitledBorder.RIGHT); p6.setBorder (tb); p6.add (new JLabel ("Titled Border (right)")); panel.add (p6);

Notice the way p6 is set up, creating an instance first, specifying the title, then setting the border. 29

JPanel p7=new JPanel(); Border b1=BorderFactory.createLineBorder(Color.blue,2); Border b2=BorderFactory.createEtchedBorder (); p7.setBorder (BorderFactory.createCompoundBorder(b1,b2)); p7.add (new JLabel ("Compound Border")); panel.add (p7); JPanel p8 = new JPanel(); Border mb = BorderFactory.createMatteBorder (1, 5, 1, 1, Color.yellow); p8.setBorder (mb); p8.add (new JLabel ("Matte Border")); panel.add (p8); frame.getContentPane().add (panel); frame.pack(); frame.show(); } }

Notice that, in setting p8, we specify the size, in pixels, of its top, left, bottom and right edge, and its color.

30

Additional components When we deal with image or information too large to fit in a reasonable area, a scroll pane is useful. It is essentially a container that offers a limited view of a component, and provides vertical and/or horizontal scroll bars to change that view. public class TransitMap{ public static void main (String[] args){ JFrame frame=new JFrame("SEPTA Transit Map"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ImageIcon image = new ImageIcon ("septa.jpg"); JLabel imageLabel=new JLabel(image); JScrollPane sp = new JScrollPane (imageLabel); sp.setPreferredSize (new Dimension (450, 400)); frame.getContentPane().add (sp); frame.pack(); frame.show(); } }

31

The Juke Box We now checkout a juke box, where the user can select songs to play. It is implemented with a combo box, so that you can select only one thing, which is visible, while the others are hidden away.

32

Set things up The main method simply sets up a panel, constructs an instance of a JukeBoxControl, add it to the frame, and let it run. public class JukeBox{ public static void main (String[] args){ JFrame frame = new JFrame ("Java Juke Box"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JukeBoxControls controlPanel = new JukeBoxControls(); frame.getContentPane().add(controlPanel); frame.pack(); frame.show(); } }

33

The JukeBoxControl class import import import import import

java.awt.*; java.awt.event.*; javax.swing.*; java.applet.AudioClip; java.net.URL;

public class JukeBoxControls extends JPanel{ private JComboBox musicCombo; private JButton stopButton, playButton; private AudioClip[] music; private AudioClip current; public JukeBoxControls(){ URL url1, url2, url3, url4, url5, url6; url1 = url2 = url3 = url4 = url5 = url6 = null; try { url1 url2 url3 url4 url5 url6 } catch

= = = = = =

new new new new new new

URL URL URL URL URL URL

("file", ("file", ("file", ("file", ("file", ("file",

"localhost", "localhost", "localhost", "localhost", "localhost", "localhost",

"westernBeat.wav"); "classical.wav"); "jeopardy.au"); "newAgeRythm.wav"); "eightiesJam.wav"); "hitchcock.wav");

(Exception exception) {}

} 34

The JukeBoxControl class (II) music = new AudioClip[7]; music[0] = null; // Corresponds to "Make a Selection..." music[1] = JApplet.newAudioClip (url1); music[2] = JApplet.newAudioClip (url2); music[3] = JApplet.newAudioClip (url3); music[4] = JApplet.newAudioClip (url4); music[5] = JApplet.newAudioClip (url5); music[6] = JApplet.newAudioClip (url6); JLabel titleLabel = new JLabel ("Java Juke Box"); titleLabel.setAlignmentX (Component.CENTER_ALIGNMENT); }

Question: What does the last line do? Answer: It puts the title label in the middle, which will be added into the layout later.

35

The JukeBoxControl class (III) // Create the list of strings for the combo box options String[] musicNames = {"Make A Selection...", "Western Beat","Classical Melody","Jeopardy Theme", "New Age Rythm","Eighties Jam","Alfred Hitchcock"}; musicCombo = new JComboBox (musicNames); musicCombo.setAlignmentX (Component.CENTER_ALIGNMENT); // Set up the buttons playButton=new JButton("Play",new ImageIcon("play.gif")); playButton.setBackground (Color.white); playButton.setMnemonic (’p’); stopButton=new JButton("Stop",new ImageIcon("stop.gif")); stopButton.setBackground (Color.white); stopButton.setMnemonic (’s’); JPanel buttons = new JPanel(); buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS)); buttons.add (playButton); buttons.add (Box.createRigidArea (new Dimension(5,0))); buttons.add (stopButton); buttons.setBackground (Color.cyan); }

36

The JukeBoxControl class (IV) // Set up this panel setPreferredSize (new Dimension (300, 100)); setBackground (Color.cyan); setLayout (new BoxLayout (this, BoxLayout.Y_AXIS)); add (Box.createRigidArea (new Dimension(0,5))); add (titleLabel); add (Box.createRigidArea (new Dimension(0,5))); add (musicCombo); add (Box.createRigidArea (new Dimension(0,5))); add (buttons); add (Box.createRigidArea (new Dimension(0,5))); musicCombo.addActionListener (new ComboListener()); stopButton.addActionListener (new ButtonListener()); playButton.addActionListener (new ButtonListener()); current = null; }

37

The listeners Now, we get to the listeners. There are two of them. The ButtonListenter takes care of both the play button and the stop button. private class ComboListener implements ActionListener{ public void actionPerformed (ActionEvent event){ if (current != null) current.stop(); current = music[musicCombo.getSelectedIndex()]; } } private class ButtonListener implements ActionListener{ public void actionPerformed (ActionEvent event){ if (current != null) current.stop(); if (event.getSource() == playButton) if (current != null) current.play(); } }

Question: Where is the music clip hooked up to the chosen music? Homework: Check out Figure 9.7, then complete Exercise 9.4. 38