Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 83 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
83
Dung lượng
3,67 MB
Nội dung
Displaying Images 319 Figure 7–14 Window with tiled graphics image Listing 7–6 ImageTest.java 1. import java.awt.*; 2. import java.io.*; 3. import javax.imageio.*; 4. import javax.swing.*; 5. 6. /** 7. * @version 1.33 2007-04-14 8. * @author Cay Horstmann 9. */ 10. public class ImageTest 11. { 12. public static void main(String[] args) 13. { 14. EventQueue.invokeLater(new Runnable() 15. { 16. public void run() 17. { 18. ImageFrame frame = new ImageFrame(); 19. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20. frame.setVisible(true); 21. } 22. }); 23. } 24. } 25. 26. /** 27. * A frame with an image component 28. */ 29. class ImageFrame extends JFrame 30. { 31. public ImageFrame() 32. { 33. setTitle("ImageTest"); 34. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 35. Chapter 7. Graphics Programming Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapter 7 ■ Graphics Programming 320 36. // add component to frame 37. 38. ImageComponent component = new ImageComponent(); 39. add(component); 40. } 41. 42. public static final int DEFAULT_WIDTH = 300; 43. public static final int DEFAULT_HEIGHT = 200; 44. } 45. 46. /** 47. * A component that displays a tiled image 48. */ 49. class ImageComponent extends JComponent 50. { 51. public ImageComponent() 52. { 53. // acquire the image 54. try 55. { 56. image = ImageIO.read(new File("blue-ball.gif")); 57. } 58. catch (IOException e) 59. { 60. e.printStackTrace(); 61. } 62. } 63. 64. public void paintComponent(Graphics g) 65. { 66. if (image == null) return; 67. 68. int imageWidth = image.getWidth(this); 69. int imageHeight = image.getHeight(this); 70. 71. // draw the image in the top-left corner 72. 73. g.drawImage(image, 0, 0, null); 74. // tile the image across the component 75. 76. for (int i = 0; i * imageWidth <= getWidth(); i++) 77. for (int j = 0; j * imageHeight <= getHeight(); j++) 78. if (i + j > 0) g.copyArea(0, 0, imageWidth, imageHeight, i * imageWidth, j 79. * imageHeight); 80. } 81. 82. private Image image; 83. } Listing 7–6 ImageTest.java (continued) Chapter 7. Graphics Programming Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Displaying Images 321 • static BufferedImage read(File f) • static BufferedImage read(URL u) reads an image from the given file or URL. • boolean drawImage(Image img, int x, int y, ImageObserver observer) draws an unscaled image. Note: This call may return before the image is drawn. • boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) draws a scaled image. The system scales the image to fit into a region with the given width and height. Note: This call may return before the image is drawn. • void copyArea(int x, int y, int width, int height, int dx, int dy) copies an area of the screen. javax.imageio.ImageIO 1.4 java.awt.Graphics 1.0 Parameters: img The image to be drawn x The x-coordinate of the top-left corner y The y-coordinate of the top-left corner observer The object to notify of the progress of the rendering process (may be null ) Parameters: img The image to be drawn x The x-coordinate of the top-left corner y The y-coordinate of the top-left corner width The desired width of image height The desired height of image observer The object to notify of the progress of the rendering process (may be null ) Parameters: x The x-coordinate of the top-left corner of the source area y The y-coordinate of the top-left corner of the source area width The width of the source area height The height of the source area dx The horizontal distance from the source area to the target area dy The vertical distance from the source area to the target area Chapter 7. Graphics Programming Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapter 7 ■ Graphics Programming 322 This concludes our introduction to Java graphics programming. For more advanced techniques, you can turn to the discussion about 2D graphics and image manipulation in Volume II. In the next chapter, you will learn how your programs react to user input. Chapter 7. Graphics Programming Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapt er Chapter 323 E VENT H ANDLING ▼ B ASICS OF E VENT H ANDLING ▼ A CTIONS ▼ M OUSE E VENTS ▼ T HE AWT E VENT H IERARCHY Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapter 8 ■ Event Handling 324 E vent handling is of fundamental importance to programs with a graphical user interface. To implement user interfaces, you must master the way in which Java handles events. This chapter explains how the Java AWT event model works. You will see how to capture events from user interface components and input devices. We also show you how to work with actions, a more structured approach for processing action events. Basics of Event Handling Any operating environment that supports GUIs constantly monitors events such as keystrokes or mouse clicks. The operating environment reports these events to the pro- grams that are running. Each program then decides what, if anything, to do in response to these events. In languages like Visual Basic, the correspondence between events and code is obvious. One writes code for each specific event of interest and places the code in what is usually called an event procedure. For example, a Visual Basic button named “HelpButton” would have a HelpButton_Click event procedure associated with it. The code in this procedure executes whenever that button is clicked. Each Visual Basic GUI component responds to a fixed set of events, and it is impossible to change the events to which a Visual Basic component responds. On the other hand, if you use a language like raw C to do event-driven programming, you need to write the code that constantly checks the event queue for what the operat- ing environment is reporting. (You usually do this by encasing your code in a loop with a massive switch statement!) This technique is obviously rather ugly, and, in any case, it is much more difficult to code. The advantage is that the events you can respond to are not as limited as in languages, like Visual Basic, that go to great lengths to hide the event queue from the programmer. The Java programming environment takes an approach somewhat between the Visual Basic approach and the raw C approach in terms of power and, therefore, in resulting complexity. Within the limits of the events that the AWT knows about, you completely control how events are transmitted from the event sources (such as buttons or scrollbars) to event listeners. You can designate any object to be an event listener—in practice, you pick an object that can conveniently carry out the desired response to the event. This event delegation model gives you much more flexibility than is possible with Visual Basic, in which the listener is predetermined. Event sources have methods that allow you to register event listeners with them. When an event happens to the source, the source sends a notification of that event to all the lis- tener objects that were registered for that event. As one would expect in an object-oriented language like Java, the information about the event is encapsulated in an event object. In Java, all event objects ultimately derive from the class java.util.EventObject. Of course, there are subclasses for each event type, such as ActionEvent and WindowEvent . Different event sources can produce different kinds of events. For example, a button can send ActionEvent objects, whereas a window can send WindowEvent objects. To sum up, here’s an overview of how event handling in the AWT works: • A listener object is an instance of a class that implements a special interface called (naturally enough) a listener interface. • An event source is an object that can register listener objects and send them event objects. Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Basics of Event Handling 325 • The event source sends out event objects to all registered listeners when that event occurs. • The listener objects will then use the information in the event object to determine their reaction to the event. Figure 8–1 shows the relationship between the event handling classes and interfaces. Figure 8–1 Relationship between event sources and listeners Here is an example for specifying a listener: ActionListener listener = . . .; JButton button = new JButton("Ok"); button.addActionListener(listener); Now the listener object is notified whenever an “action event” occurs in the button. For buttons, as you might expect, an action event is a button click. To implement the ActionListener interface, the listener class must have a method called actionPerformed that receives an ActionEvent object as a parameter. class MyListener implements ActionListener { . . . public void actionPerformed(ActionEvent event) { // reaction to button click goes here . . . } } Whenever the user clicks the button, the JButton object creates an ActionEvent object and calls listener.actionPerformed(event) , passing that event object. An event source such as a button can have multiple listeners. In that case, the button calls the actionPerformed meth- ods of all listeners whenever the user clicks the button. Figure 8–2 shows the interaction between the event source, event listener, and event object. <<set of one or more>> 1… * <<implements>> Listener interface Event source Event listener Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapter 8 ■ Event Handling 326 Figure 8–2 Event notification Example: Handling a Button Click As a way of getting comfortable with the event delegation model, let’s work through all details needed for the simple example of responding to a button click. For this example, we will show a panel populated with three buttons. Three listener objects are added as action listeners to the buttons. With this scenario, each time a user clicks on any of the buttons on the panel, the associ- ated listener object then receives an ActionEvent that indicates a button click. In our sam- ple program, the listener object will then change the background color of the panel. Before we can show you the program that listens to button clicks, we first need to explain how to create buttons and how to add them to a panel. (For more on GUI ele- ments, see Chapter 9.) You create a button by specifying a label string, an icon, or both in the button construc- tor. Here are two examples: MyListener JButton MyFrame new addActionListener new actionPerformed Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Basics of Event Handling 327 JButton yellowButton = new JButton("Yellow"); JButton blueButton = new JButton(new ImageIcon("blue-ball.gif")); Call the add method to add the buttons to a panel: JButton yellowButton = new JButton("Yellow"); JButton blueButton = new JButton("Blue"); JButton redButton = new JButton("Red"); buttonPanel.add(yellowButton); buttonPanel.add(blueButton); buttonPanel.add(redButton); Figure 8–3 shows the result. Figure 8–3 A panel filled with buttons Next, we need to add code that listens to these buttons. This requires classes that imple- ment the ActionListener interface, which, as we just mentioned, has one method: actionPer- formed , whose signature looks like this: public void actionPerformed(ActionEvent event) NOTE: The ActionListener interface we used in the button example is not restricted to button clicks. It is used in many separate situations: • When an item is selected from a list box with a double click • When a menu item is selected • When the ENTER key is clicked in a text field • When a certain amount of time has elapsed for a Timer component You will see more details in this chapter and the next. The way to use the ActionListener interface is the same in all situations: the actionPerformed method (which is the only method in ActionListener) takes an object of type ActionEvent as a parameter. This event object gives you information about the event that happened. When a button is clicked, we want the background color of the panel to change to a par- ticular color. We store the desired color in our listener class. class ColorAction implements ActionListener { public ColorAction(Color c) { Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Chapter 8 ■ Event Handling 328 backgroundColor = c; } public void actionPerformed(ActionEvent event) { // set panel background color . . . } private Color backgroundColor; } We then construct one object for each color and set the objects as the button listeners. ColorAction yellowAction = new ColorAction(Color.YELLOW); ColorAction blueAction = new ColorAction(Color.BLUE); ColorAction redAction = new ColorAction(Color.RED); yellowButton.addActionListener(yellowAction); blueButton.addActionListener(blueAction); redButton.addActionListener(redAction); For example, if a user clicks on the button marked “Yellow,” then the actionPerformed method of the yellowAction object is called. Its backgroundColor instance field is set to Color.YELLOW , and it can now proceed to set the panel’s background color. Just one issue remains. The ColorAction object doesn’t have access to the buttonPanel vari- able. You can solve this problem in two ways. You can store the panel in the ColorAction object and set it in the ColorAction constructor. Or, more conveniently, you can make Color- Action into an inner class of the ButtonFrame class. Its methods can then access the outer panel automatically. (For more information on inner classes, see Chapter 6.) We follow the latter approach. Here is how you place the ColorAction class inside the ButtonFrame class: class ButtonPanel extends JFrame { . . . private class ColorAction implements ActionListener { . . . public void actionPerformed(ActionEvent event) { buttonPanel.setBackground(backgroundColor); } private Color backgroundColor; } private JPanel buttonPanel; } Look closely at the actionPerformed method. The ColorAction class doesn’t have a buttonPanel field. But the outer ButtonFrame class does. Chapter 8. Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... PDF Merge and Split Unregistered Version - http://www.simpopdf.com Mouse Events Listing 8–4 1 2 3 4 5 import import import import import MouseTest .java java.awt.*; java. awt.event.*; java. util.*; java. awt.geom.*; javax.swing.*; 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 /** * @version 1. 32 2007-06 -12 * @author Cay Horstmann */ public class MouseTest { public static void main(String[] args)... the listener should modify Listing 8 1 contains the complete program Whenever you click one of the buttons, the appropriate action listener changes the background color of the panel Listing 8 1 1 2 3 ButtonTest .java import java. awt.*; import java. awt.event.*; import javax.swing.*; 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 /** * @version 1. 33 2007-06 -12 * @author Cay Horstmann */ public... SwingUtilities.updateComponentTreeUI(PlafPanel.this); 3 35 Chapter 8 Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 336 Chapter 8 ■ Event Handling Figure 8–4 Switching the look and feel Listing 8–2 1 2 3 PlafTest .java import java. awt.EventQueue; import java. awt.event.*; import javax.swing.*; 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 /** * @version 1. 32 2007-06 -12 * @author Cay Horstmann... action objects Try it out—clicking either the buttons or pressing CTRL+Y, CTRL+B, or CTRL+R changes the panel color Listing 8–3 1 2 3 ActionTest .java import java. awt.*; import java. awt.event.*; import javax.swing.*; 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * @version 1. 33 2007-06 -12 * @author Cay Horstmann */ public class ActionTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable()... imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue"); imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red"); 51 52 53 54 55 56 // associate the names with actions ActionMap amap = buttonPanel.getActionMap(); amap.put("panel.yellow", yellowAction); amap.put("panel.blue", blueAction); amap.put("panel.red", redAction); 57 58 59 60 61 62 } 63 64 65 public class ColorAction extends AbstractAction { 347 Chapter 8 Event Handling Simpo... 39 40 add(buttonPanel); 41 } 42 43 /** * Makes a button to change the pluggable look and feel * @param name the button name * @param plafName the name of the look and feel class */ void makeButton(String name, final String plafName) { // add button to panel 44 45 46 47 48 49 50 51 52 JButton button = new JButton(name); buttonPanel.add(button); 53 54 55 // set button action 56 57 button.addActionListener(new... DEFAULT_WIDTH = 300; public static final int DEFAULT_HEIGHT = 200; 43 44 45 } 46 47 48 49 /** * A component with mouse operations for adding and removing squares */ 353 Chapter 8 Event Handling Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 354 Chapter 8 ■ Event Handling Listing 8–4 50 51 52 53 54 55 MouseTest .java (continued) class MouseComponent extends JComponent { public MouseComponent()... ColorAction(Color.RED); 50 51 52 53 54 // associate actions with buttons yellowButton.addActionListener(yellowAction); blueButton.addActionListener(blueAction); redButton.addActionListener(redAction); 55 56 57 58 } 59 60 /** * An action listener that sets the panel's background color */ private class ColorAction implements ActionListener { public ColorAction(Color c) { backgroundColor = c; } 61 62 63 64 65 66 67 68 69... squares = new ArrayList(); current = null; 56 addMouseListener(new MouseHandler()); addMouseMotionListener(new MouseMotionHandler()); 57 58 59 } 60 61 62 63 public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; 64 // draw all squares for (Rectangle2D r : squares) g2.draw(r); 65 66 67 68 } 69 70 71 72 73 74 75 76 77 78 79 80 81 82 /** * Finds the first square containing a point... java. util.EventObject 1. 1 • Object getSource() returns a reference to the object where the event occurred java. awt.event.ActionEvent 1. 1 • String getActionCommand() returns the command string associated with this action event If the action event originated from a button, the command string equals the button label, unless it has been changed with the setActionCommand method java. beans.EventHandler 1. 4 . JComponent 50 . { 51 . public ImageComponent() 52 . { 53 . // acquire the image 54 . try 55 . { 56 . image = ImageIO.read(new File("blue-ball.gif")); 57 . } 58 . catch (IOException e) 59 . . @version 1. 33 2007-04 -14 8. * @author Cay Horstmann 9. */ 10 . public class ImageTest 11 . { 12 . public static void main(String[] args) 13 . { 14 . EventQueue.invokeLater(new Runnable() 15 . { 16 . . final String plafName) 50 . { 51 . // add button to panel 52 . 53 . JButton button = new JButton(name); 54 . buttonPanel.add(button); 55 . 56 . // set button action 57 . 58 . button.addActionListener(new