Thinking in Java 3rd Edition phần 8 pdf

119 393 0
Thinking in Java 3rd Edition phần 8 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 14: Creating Windows & Applets 803 example, because a JLabel will be the size of its string, attempting to right-justify its text yields an unchanged display when using FlowLayout. Feedback GridLayout A GridLayout allows you to build a table of components, and as you add them they are placed left-to-right and top-to-bottom in the grid. In the constructor you specify the number of rows and columns that you need and these are laid out in equal proportions. Feedback //: c14:GridLayout1.java // Demonstrates GridLayout. // <applet code=GridLayout1 width=300 height=250></applet> import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; public class GridLayout1 extends JApplet { public void init() { Container cp = getContentPane(); cp.setLayout(new GridLayout(7,3)); for(int i = 0; i < 20; i++) cp.add(new JButton("Button " + i)); } public static void main(String[] args) { Console.run(new GridLayout1(), 300, 250); } } ///:~ In this case there are 21 slots but only 20 buttons. The last slot is left empty because no “balancing” goes on with a GridLayout. Feedback GridBagLayout The GridBagLayout provides you with tremendous control in deciding exactly how the regions of your window will lay themselves out and reformat themselves when the window is resized. However, it’s also the most complicated layout manager, and quite difficult to understand. It is intended primarily for automatic code generation by a GUI builder (GUI builders might use GridBagLayout instead of absolute placement). If your design is so complicated that you feel you need to use 804 Thinking in Java www.BruceEckel.com GridBagLayout, then you should be using a GUI builder tool to generate that design. If you feel you must know the intricate details, I’ll refer you to Core Java 2, Volume 1 by Horstmann & Cornell (Prentice Hall, 2001), or a dedicated Swing book, as a starting point. Feedback Absolute positioning It is also possible to set the absolute position of the graphical components in this way: 1. Set a null layout manager for your Container: setLayout(null). Feedback 2. Call setBounds( ) or reshape( ) (depending on the language version) for each component, passing a bounding rectangle in pixel coordinates. You can do this in the constructor, or in paint( ), depending on what you want to achieve. Feedback Some GUI builders use this approach extensively, but this is usually not the best way to generate code. Feedback BoxLayout Because people had so much trouble understanding and working with GridBagLayout, Swing also includes BoxLayout, which gives you many of the benefits of GridBagLayout without the complexity, so you can often use it when you need to do hand-coded layouts (again, if your design becomes too complex, use a GUI builder that generates layouts for you). BoxLayout allows you to control the placement of components either vertically or horizontally, and to control the space between the components using something called “struts and glue.” First, let’s see how to use the BoxLayout directly, in the same way that the other layout managers have been demonstrated: //: c14:BoxLayout1.java // Vertical and horizontal BoxLayouts. // <applet code=BoxLayout1 width=450 height=200></applet> import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; Chapter 14: Creating Windows & Applets 805 public class BoxLayout1 extends JApplet { public void init() { JPanel jpv = new JPanel(); jpv.setLayout(new BoxLayout(jpv, BoxLayout.Y_AXIS)); for(int i = 0; i < 5; i++) jpv.add(new JButton("jpv " + i)); JPanel jph = new JPanel(); jph.setLayout(new BoxLayout(jph, BoxLayout.X_AXIS)); for(int i = 0; i < 5; i++) jph.add(new JButton("jph " + i)); Container cp = getContentPane(); cp.add(BorderLayout.EAST, jpv); cp.add(BorderLayout.SOUTH, jph); } public static void main(String[] args) { Console.run(new BoxLayout1(), 450, 200); } } ///:~ The constructor for BoxLayout is a bit different than the other layout managers—you provide the Container that is to be controlled by the BoxLayout as the first argument, and the direction of the layout as the second argument. Feedback To simplify matters, there’s a special container called Box that uses BoxLayout as its native manager. The following example lays out components horizontally and vertically using Box, which has two static methods to create boxes with vertical and horizontal alignment: //: c14:Box1.java // Vertical and horizontal BoxLayouts. // <applet code=Box1 width=450 height=200></applet> import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; public class Box1 extends JApplet { public void init() { Box bv = Box.createVerticalBox(); for(int i = 0; i < 5; i++) bv.add(new JButton("bv " + i)); Box bh = Box.createHorizontalBox(); for(int i = 0; i < 5; i++) bh.add(new JButton("bh " + i)); 806 Thinking in Java www.BruceEckel.com Container cp = getContentPane(); cp.add(BorderLayout.EAST, bv); cp.add(BorderLayout.SOUTH, bh); } public static void main(String[] args) { Console.run(new Box1(), 450, 200); } } ///:~ Once you have a Box, you pass it as a second argument when adding components to the content pane. Feedback Struts add space between components, measured in pixels. To use a strut, you simply add it in between the addition of the components that you want spaced apart: //: c14:Box2.java // Adding struts. // <applet code=Box2 width=450 height=300></applet> import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; public class Box2 extends JApplet { public void init() { Box bv = Box.createVerticalBox(); for(int i = 0; i < 5; i++) { bv.add(new JButton("bv " + i)); bv.add(Box.createVerticalStrut(i*10)); } Box bh = Box.createHorizontalBox(); for(int i = 0; i < 5; i++) { bh.add(new JButton("bh " + i)); bh.add(Box.createHorizontalStrut(i*10)); } Container cp = getContentPane(); cp.add(BorderLayout.EAST, bv); cp.add(BorderLayout.SOUTH, bh); } public static void main(String[] args) { Console.run(new Box2(), 450, 300); } } ///:~ Chapter 14: Creating Windows & Applets 807 Struts separate components by a fixed amount, but glue is the opposite: it separates components by as much as possible. Thus it’s more of a “spring” than “glue” (and the design on which this was based was called “springs and struts” so the choice of the term is a bit mysterious). Feedback //: c14:Box3.java // Using Glue. // <applet code=Box3 width=450 height=300></applet> import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; public class Box3 extends JApplet { public void init() { Box bv = Box.createVerticalBox(); bv.add(new JLabel("Hello")); bv.add(Box.createVerticalGlue()); bv.add(new JLabel("Applet")); bv.add(Box.createVerticalGlue()); bv.add(new JLabel("World")); Box bh = Box.createHorizontalBox(); bh.add(new JLabel("Hello")); bh.add(Box.createHorizontalGlue()); bh.add(new JLabel("Applet")); bh.add(Box.createHorizontalGlue()); bh.add(new JLabel("World")); bv.add(Box.createVerticalGlue()); bv.add(bh); bv.add(Box.createVerticalGlue()); getContentPane().add(bv); } public static void main(String[] args) { Console.run(new Box3(), 450, 300); } } ///:~ A strut works in one direction, but a rigid area fixes the spacing between components in both directions: //: c14:Box4.java // Rigid areas are like pairs of struts. // <applet code=Box4 width=450 height=300></applet> import javax.swing.*; import java.awt.*; 808 Thinking in Java www.BruceEckel.com import com.bruceeckel.swing.*; public class Box4 extends JApplet { public void init() { Box bv = Box.createVerticalBox(); bv.add(new JButton("Top")); bv.add(Box.createRigidArea(new Dimension(120, 90))); bv.add(new JButton("Bottom")); Box bh = Box.createHorizontalBox(); bh.add(new JButton("Left")); bh.add(Box.createRigidArea(new Dimension(160, 80))); bh.add(new JButton("Right")); bv.add(bh); getContentPane().add(bv); } public static void main(String[] args) { Console.run(new Box4(), 450, 300); } } ///:~ You should be aware that rigid areas are a bit controversial. Since they use absolute values, some people feel that they cause more trouble than they are worth. Feedback The best approach? Swing is powerful; it can get a lot done with a few lines of code. The examples shown in this book are reasonably simple, and for learning purposes it makes sense to write them by hand. You can actually accomplish quite a bit by combining simple layouts. At some point, however, it stops making sense to hand-code GUI forms—it becomes too complicated and is not a good use of your programming time. The Java and Swing designers oriented the language and libraries to support GUI building tools, which have been created for the express purpose of making your programming experience easier. As long as you understand what’s going on with layouts and how to deal with the events (described next), it’s not particularly important that you actually know the details of how to lay out components by hand—let the appropriate tool do that for you (Java is, after all, designed to increase programmer productivity). Feedback Chapter 14: Creating Windows & Applets 809 The Swing event model In the Swing event model a component can initiate (“fire”) an event. Each type of event is represented by a distinct class. When an event is fired, it is received by one or more “listeners,” which act on that event. Thus, the source of an event and the place where the event is handled can be separate. Since you typically use Swing components as they are, but need to write code that is called when the components receive an event, this is an excellent example of the separation of interface and implementation. Feedback Each event listener is an object of a class that implements a particular type of listener interface. So as a programmer, all you do is create a listener object and register it with the component that’s firing the event. This registration is performed by calling an addXXXListener( ) method in the event-firing component, in which “XXX” represents the type of event listened for. You can easily know what types of events can be handled by noticing the names of the “addListener” methods, and if you try to listen for the wrong events you’ll discover your mistake at compile time. You’ll see later in the chapter that JavaBeans also use the names of the “addListener” methods to determine what events a Bean can handle. Feedback All of your event logic, then, will go inside a listener class. When you create a listener class, the sole restriction is that it must implement the appropriate interface. You can create a global listener class, but this is a situation in which inner classes tend to be quite useful, not only because they provide a logical grouping of your listener classes inside the UI or business logic classes they are serving, but because (as you shall see later) the fact that an inner class object keeps a reference to its parent object provides a nice way to call across class and subsystem boundaries. Feedback All the examples so far in this chapter have been using the Swing event model, but the remainder of this section will fill out the details of that model. Feedback 810 Thinking in Java www.BruceEckel.com Event and listener types All Swing components include addXXXListener( ) and removeXXXListener( ) methods so that the appropriate types of listeners can be added and removed from each component. You’ll notice that the “XXX” in each case also represents the argument for the method, for example: addMyListener(MyListener m). The following table includes the basic associated events, listeners, and methods, along with the basic components that support those particular events by providing the addXXXListener( ) and removeXXXListener( ) methods. You should keep in mind that the event model is designed to be extensible, so you may encounter other events and listener types that are not covered in this table. Feedback Event, listener interface and add- and remove-methods Components supporting this event ActionEvent ActionListener addActionListener( ) removeActionListener( ) JButton, JList, JTextField, JMenuItem and its derivatives including JCheckBoxMenuItem, JMenu, and JpopupMenu. AdjustmentEvent AdjustmentListener addAdjustmentListener( ) removeAdjustmentListener( ) JScrollbar and anything you create that implements the Adjustable interface. ComponentEvent ComponentListener addComponentListener( ) removeComponentListener( ) *Component and its derivatives, including JButton, JCheckBox, JComboBox, Container, JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, JFrame, JLabel, JList, JScrollbar, JTextArea, and JTextField. ContainerEvent ContainerListener addContainerListener( ) removeContainerListener( ) Container and its derivatives, including JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, and JFrame. FocusEvent FocusListener addFocusListener( ) removeFocusListener( ) Component and derivatives*. KeyEvent Ke y Listener Component and derivatives*. Chapter 14: Creating Windows & Applets 811 Event, listener interface and add- and remove-methods Components supporting this event addKeyListener( ) removeKeyListener( ) MouseEvent (for both clicks and motion) MouseListener addMouseListener( ) removeMouseListener( ) Component and derivatives*. MouseEvent 8 (for both clicks and motion) MouseMotionListener addMouseMotionListener( ) removeMouseMotionListener( ) Component and derivatives*. WindowEvent WindowListener addWindowListener( ) removeWindowListener( ) Window and its derivatives, including JDialog, JFileDialog, and JFrame. ItemEvent ItemListener addItemListener( ) removeItemListener( ) JCheckBox, JCheckBoxMenuItem, JComboBox, JList, and anything that implements the ItemSelectable interface. TextEvent TextListener addTextListener( ) removeTextListener( ) Anything derived from JTextComponent, including JTextArea and JTextField. You can see that each type of component supports only certain types of events. It turns out to be rather difficult to look up all the events supported by each component. A simpler approach is to modify the ShowMethods.java program from Chapter 10 so that it displays all the event listeners supported by any Swing component that you enter. Feedback Chapter 10 introduced reflection and used that feature to look up methods for a particular class—either the entire list of methods or a subset of those whose names match a keyword that you provide. The magic of reflection 8 There is no MouseMotionEvent even though it seems like there ought to be. Clicking and motion is combined into MouseEvent, so this second appearance of MouseEvent in the table is not an error. 812 Thinking in Java www.BruceEckel.com is that it can automatically show you all the methods for a class without forcing you to walk up the inheritance hierarchy, examining the base classes at each level. Thus, it provides a valuable timesaving tool for programming: because the names of most Java methods are made nicely verbose and descriptive, you can search for the method names that contain a particular word of interest. When you find what you think you’re looking for, check the JDK documentation. Feedback However, by Chapter 10 you hadn’t seen Swing, so the tool in that chapter was developed as a command-line application. Here is the more useful GUI version, specialized to look for the “addListener” methods in Swing components: //: c14:ShowAddListeners.java // Display the "addXXXListener" methods of any Swing class. // <applet code=ShowAddListeners // width=500 height=400></applet> import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.lang.reflect.*; import java.util.regex.*; import com.bruceeckel.swing.*; public class ShowAddListeners extends JApplet { private JTextField name = new JTextField(25); private JTextArea results = new JTextArea(40, 65); private static Pattern addListener = Pattern.compile("(add\\w+?Listener\\(.*?\\))"); private static Pattern qualifier = Pattern.compile("\\w+\\."); class NameL implements ActionListener { public void actionPerformed(ActionEvent e) { String nm = name.getText().trim(); if(nm.length() == 0) { results.setText("No match"); return; } Class klass; try { klass = Class.forName("javax.swing." + nm); } catch(ClassNotFoundException ex) { [...]... mouseDragged(MouseEvent) mouseMoved(MouseEvent) WindowListener WindowAdapter windowOpened(WindowEvent) windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent) ItemListener itemStateChanged(ItemEvent) Chapter 14: Creating Windows & Applets 81 5 This is not an exhaustive listing, partly because the event... javax.swing.event.*; import java. awt.*; import java. awt.event.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class List extends JApplet { private String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; private DefaultListModel lItems=new DefaultListModel(); 83 8 Thinking in Java www.BruceEckel.com... (only a few are shown here) Feedback 82 0 Thinking in Java www.BruceEckel.com 3 Because of the naming convention used for Swing events, it’s fairly easy to guess how to write and install a handler for a particular type of event Use the lookup program ShowAddListeners .java from earlier in this chapter to aid in your investigation of a particular component Feedback 4 When things start to get complicated you... predetermined period of time, a tiny box containing your text will pop up next to the mouse Feedback Text fields This example shows the extra behavior that JTextFields are capable of: //: c14:TextFields .java // Text fields and Java events // import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import java. awt.*; import java. awt.event.*;... contents of the JTextField, in this case) It automatically copies all text from t1 into t2 In addition, t1’s document is set to a derived class of PlainDocument, called UpperCaseDocument, which forces all characters to uppercase It automatically detects backspaces and performs the deletion, adjusting the caret and handling everything as you would expect Feedback 82 8 Thinking in Java www.BruceEckel.com... Respond to mouse click } 81 6 Thinking in Java www.BruceEckel.com } This doesn’t work, but it will drive you crazy trying to figure out why, since everything will compile and run fine—except that your method won’t be called for a mouse click Can you see the problem? It’s in the name of the method: MouseClicked( ) instead of mouseClicked ( ) A simple slip in capitalization results in the addition of a completely... solution, since MyButton can be used only in conjunction with TrackEvent This kind of code is sometimes called “highly coupled”: //: c14:TrackEvent .java // Show events as they happen // import javax.swing.*; import java. awt.*; import java. awt.event.*; import java. util.*; import com.bruceeckel.swing.*; 9 In Java 1.0/1.1 you could not usefully inherit... www.BruceEckel.com To open a file and bring in the image, simply create an ImageIcon and hand it the file name From then on, you can use the resulting Icon in your program Feedback //: c14:Faces .java // Icon behavior in Jbuttons // import javax.swing.*; import java. awt.*; import java. awt.event.*; import java. io.*; import com.bruceeckel.swing.*; public class Faces... e.paramString()); } public void keyTyped(KeyEvent e) { report("keyTyped", e.paramString()); } }; MouseListener ml = new MouseListener() { public void mouseClicked(MouseEvent e) { report("mouseClicked", e.paramString()); } public void mouseEntered(MouseEvent e) { report("mouseEntered", e.paramString()); } public void mouseExited(MouseEvent e) { report("mouseExited", e.paramString()); } 81 8 Thinking in Java. .. that’s called when the window is closing, so you don’t get the desired results Despite the inconvenience, an interface will guarantee that the methods are properly implemented Feedback Tracking multiple events To prove to yourself that these events are in fact being fired, and as an interesting experiment, it’s worth creating an applet that tracks extra behavior in a JButton (in addition to whether . mouseMoved(MouseEvent) WindowListener WindowAdapter windowOpened(WindowEvent) windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent). c14:Box4 .java // Rigid areas are like pairs of struts. // <applet code=Box4 width=450 height=300></applet> import javax.swing.*; import java. awt.*; 80 8 Thinking in Java www.BruceEckel.com. error. 81 2 Thinking in Java www.BruceEckel.com is that it can automatically show you all the methods for a class without forcing you to walk up the inheritance hierarchy, examining the base

Ngày đăng: 14/08/2014, 00:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan