Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 77 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
77
Dung lượng
1,23 MB
Nội dung
} public interface Command { public void execute(); } The TestStrategy interface is implemented by the StartsWithAEIOU and AlphabeticChars classes so the CardLayoutPanel application can apply different string algorithms to the user-specified text. Regular expression constructs are used to determine the patterns of the strings passed into the test method: public interface TestStrategy { public boolean test(String s); } public class StartsWithAEIOU implements TestStrategy { public boolean test(String s) { if( s == null || s.length() == 0) return false; return (s.toUpperCase().charAt(0) == ‘A’ || s.toUpperCase().charAt(0) == ‘E’ || s.toUpperCase().charAt(0) == ‘I’ || s.toUpperCase().charAt(0) == ‘O’ || s.toUpperCase().charAt(0) == ‘U’ ); } } public class convertUppercase implements TestStrategy { public boolean test(String s) { if( s == null || s.length() == 0 ) return false; Pattern pattern = Pattern.compile(“[a-zA-Z]”); Matcher match = pattern.matcher(s); if (!match.find()) { return false; } else { return (true); } } } // main routine omitted for brevity } Figure 4-14 represents the CardLayoutPanel application modeled in the previous source code. Users can enter text in the card layout shown in the top panel and click either strategy pattern button to apply the appropriate Strategy algorithm to that text. Results of those actions will be rendered in the card lay- out below. All of the button components employ the Command pattern to allow the application to deter- mine at runtime the proper execute() method to invoke based on the user’s navigations. 207 Chapter 4: Developing Effective User Interfaces with JFC 09_777106 ch04.qxp 11/28/06 10:43 PM Page 207 Figure 4-14 GroupLayout The GroupLayout manager is a component of the NetBeans framework that is being considered for inclu- sion in the SE 6 Java framework. The GroupLayout manager is important in that it allows for horizontal and vertical layout positioning in an independent, flexible manner.With this manager, layout groups can be formed in both a sequential and parallel fashion. Sequentially, they are placed one after another, and in parallel, they are placed on top of one another and are aligned with a common reference axis. A sample pizza delivery placement component design is shown in Figure 4-15. This model incorporates GroupLayout manager classes to position components on the user view. With this application, a user specifies his or her name, the toppings desired, and the size of the pizza for delivery. When the user makes the proper selections and clicks the order button, a receipt is generated with the user preferences. All of the Swing components are instantiated and initialized at the onset of the GroupLayoutPanel class so they can be easily referenced by the GroupLayoutPanel method for display rendering. All of the user-selected data will be managed with a JTree object: package com.grouplayout; import java.util.logging.Logger; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import org.jdesktop.layout.*; public class GroupLayoutPanel extends JPanel implements ActionListener { 208 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_777106 ch04.qxp 11/28/06 10:43 PM Page 208 private JRadioButton largePizzaButton = new JRadioButton(“Large”); private JRadioButton mediumPizzaButton = new JRadioButton(“Medium”); private JRadioButton smallPizzaButton = new JRadioButton(“Small”); private JLabel label = new JLabel(“Name:”);; private JTextField textField = new JTextField(); private JCheckBox anchoviesCheckBox = new JCheckBox(“Anchovies”); private JCheckBox mushroomsCheckBox = new JCheckBox(“Mushrooms”); private JCheckBox onionsCheckBox = new JCheckBox(“Onions”); private JCheckBox greenpeppersCheckBox = new JCheckBox(“Green Peppers”); private JCheckBox sardinesCheckBox = new JCheckBox(“Sardines”); private JCheckBox pepperoniCheckBox = new JCheckBox(“Pepperoni”); private JButtonOrder orderButton = new JButtonOrder(“Order”); private JButtonAllToppings allToppingsButton = new JButtonAllToppings(“All Toppings”); private JPanel results = new JPanel(); private JScrollPane scrollPane; private JTree tree; private DefaultMutableTreeNode root; Figure 4-15 JTextField GroupLayout JTree JCheckBox JButton (order) JButton (toppings) JCheckBox JRadioButton JCheckBox JCheckBox JRadioButton Command pattern: execute() JCheckBox JCheckBox JRadioButton 209 Chapter 4: Developing Effective User Interfaces with JFC 09_777106 ch04.qxp 11/28/06 10:43 PM Page 209 Results selected by the user will be reflected in a scroll pane to indicate all of the different dimensions and toppings the user has chosen for the pizza delivery: public GroupLayoutPanel() { anchoviesCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); mushroomsCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); onionsCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); greenpeppersCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); sardinesCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); pepperoniCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); results.setLayout(new GridLayout(0,1)); results.setPreferredSize(new Dimension(75, 75)); results.setBorder(BorderFactory.createLineBorder (Color.blue, 2)); results.setBackground(new Color(255, 255, 100)); scrollPane = new JScrollPane(); scrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setSize(75, 75); scrollPane.setPreferredSize(new Dimension(75, 75)); scrollPane.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(“Pizza Order”), BorderFactory.createEmptyBorder(5,5,5,5)), scrollPane.getBorder())); root = new DefaultMutableTreeNode(“Pizza Order”); tree = new JTree(root); scrollPane.getViewport().add( tree ); results.add(scrollPane); Here is where the GroupLayout manager is instantiated and constructed to place the different Swing components for display rendering. Notice that horizontal groups are established and embedded on one another to get the grouping effect desired for presentation: GroupLayout layout = new GroupLayout(this); setLayout(layout); layout.setAutocreateGaps(true); layout.setAutocreateContainerGaps(true); layout.setHorizontalGroup(layout.createSequentialGroup() .add(label) .add(layout.createParallelGroup(GroupLayout.LEADING) .add(textField) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(GroupLayout.LEADING) .add(anchoviesCheckBox) .add(onionsCheckBox) .add(pepperoniCheckBox)) .add(layout.createParallelGroup(GroupLayout.LEADING) 210 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_777106 ch04.qxp 11/28/06 10:43 PM Page 210 .add(mushroomsCheckBox) .add(greenpeppersCheckBox) .add(sardinesCheckBox)) .add(layout.createParallelGroup(GroupLayout.LEADING) .add(largePizzaButton) .add(mediumPizzaButton) .add(smallPizzaButton))) //) .add(results)) .add(layout.createParallelGroup(GroupLayout.LEADING) .add(orderButton) .add(allToppingsButton)) ); Vertical groups are established with the setVerticalGroup method so they can be aligned properly with previous horizontal group designations: layout.linkSize(new Component[] { orderButton, allToppingsButton }, GroupLayout.HORIZONTAL); layout.setVerticalGroup(layout.createSequentialGroup() .add(layout.createParallelGroup(GroupLayout.BASELINE) .add(label) .add(textField) .add(orderButton)) .add(layout.createParallelGroup(GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(layout.createParallelGroup(GroupLayout.BASELINE) .add(anchoviesCheckBox) .add(mushroomsCheckBox) .add(largePizzaButton)) .add(layout.createParallelGroup(GroupLayout.BASELINE) .add(onionsCheckBox) .add(greenpeppersCheckBox) .add(mediumPizzaButton)) .add(layout.createParallelGroup(GroupLayout.BASELINE) .add(pepperoniCheckBox) .add(sardinesCheckBox) .add(smallPizzaButton))) .add(allToppingsButton)) .add(layout.createParallelGroup(GroupLayout.BASELINE) .add(results)) ); Now that all of the layout positions have been defined, the listeners associated with the individual com- ponents can be defined to track user event selections: orderButton.addActionListener(this); allToppingsButton.addActionListener(this); largePizzaButton.addActionListener(this); largePizzaButton.setActionCommand(“large pizza”); mediumPizzaButton.addActionListener(this); mediumPizzaButton.setActionCommand(“medium pizza”); smallPizzaButton.addActionListener(this); 211 Chapter 4: Developing Effective User Interfaces with JFC 09_777106 ch04.qxp 11/28/06 10:43 PM Page 211 smallPizzaButton.setActionCommand(“small pizza”); setBorder(BorderFactory.createLineBorder (Color.blue, 2)); } class JButtonOrder extends JButton implements Command { public JButtonOrder(String caption) { super(caption); } Polymorphic behavior is performed with the execute() method defined in the Command pattern interface to finalize the user selections. With the Command pattern, additional execute() method implementations could be defined later to add behaviors needed to perform operations for your application because opera- tions are decoupled from objects that invariably know which operations need to be executed when invoked: public void execute() { String s = “Name: (empty)”; tree = new JTree(root); DefaultMutableTreeNode items; if (!textField.getText().equals(“”)) s = textField.getText(); items = new DefaultMutableTreeNode(s); root.add(items); s = “Size: None selected”; if (largePizzaButton.isSelected()) s = “Size: Large pizza”; else if (mediumPizzaButton.isSelected()) s = “Size: Medium pizza”; else if (smallPizzaButton.isSelected()) s = “Size: Small pizza”; items.add(new DefaultMutableTreeNode(s)); if (anchoviesCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“anchovies”)); if (mushroomsCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“mushrooms”)); if (onionsCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“onions”)); if (greenpeppersCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“peppers”)); if (sardinesCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“sardines”)); if (pepperoniCheckBox.isSelected()) items.add(new DefaultMutableTreeNode(“pepperoni”)); scrollPane.getViewport().add( tree ); tree.expandRow(0); results.add(scrollPane); } } 212 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_777106 ch04.qxp 11/28/06 10:43 PM Page 212 In the following code, the Command pattern is revealed in all its glory to dictate behavior associated with the All Toppings button. When the user clicks that button in the user display, the program knows that it must invoke the execute() method here to enable all of the checkbox components without explicitly stating so. During run time, the application retrieves the proper object reference so the execute() method associated with that reference will be called: class JButtonAllToppings extends JButton implements Command { public JButtonAllToppings(String caption) { super(caption); } public void execute() { anchoviesCheckBox.setSelected(true); mushroomsCheckBox.setSelected(true); onionsCheckBox.setSelected(true); greenpeppersCheckBox.setSelected(true); sardinesCheckBox.setSelected(true); pepperoniCheckBox.setSelected(true); } } public interface Command { public void execute(); } Action events are monitored in the code that follows, in the actionPerformed method, to determine pizza dimension selections from the size radio buttons or to execute the Command pattern interface refer- ence based on the user selection: public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(“large pizza”)) { logger.info(“Large pizza. Mama mia.”); mediumPizzaButton.setSelected(false); smallPizzaButton.setSelected(false); } else if (e.getActionCommand().equals(“medium pizza”)) { logger.info(“Want a drink with that? Big or Large?”); largePizzaButton.setSelected(false); smallPizzaButton.setSelected(false); } else if (e.getActionCommand().equals(“small pizza”)) { logger.info(“Take your pizza and go you cheapa-skate!”); largePizzaButton.setSelected(false); mediumPizzaButton.setSelected(false); } else { Command obj = (Command)e.getSource(); obj.execute(); } } public static void main(String args[]) { JFrame frame = new JFrame(“GroupLayoutPanel”); frame.addWindowListener(new WindowAdapter() { 213 Chapter 4: Developing Effective User Interfaces with JFC 09_777106 ch04.qxp 11/28/06 10:43 PM Page 213 public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.getContentPane().add(new GroupLayoutPanel(), BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } } Figure 4-16 represents a sample visualization of the pizza delivery placement application. In it, the user has placed selections for desirable toppings and size needs. Both the Order and All Toppings buttons implement the Command pattern interface so specific behaviors can be invoked when selected to call proper execute() method implementations. With the GroupLayout manager, arrangements occur both sequentially and in parallel to form hierarchi- cal presentations. Components arranged in parallel are stacked on top of one another along a common axis, whereas sequentially arranged components are placed after one another. Each dimension is defined independently and can operate without consideration to the other dimensions. The only deficiency asso- ciated with GroupLayout usage is that each component needs to be defined twice in the layout during implementation. Figure 4-16 Mustang Release Desktop Enhancements This chapter addresses a few of the new Java 6 SE Mustang features, namely system attribute collection, splash screen inclusion, and AWT modifications that are part of new modality modes. Improved drag- and-drop support and JTable sorting were shown in earlier sections of this chapter. 214 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_777106 ch04.qxp 11/28/06 10:43 PM Page 214 The following table outlines the four new AWT modality models introduced with the Java Mustang release. Modal Type Description Mode-less Does not block any other window while it’s rendered on the user display. Document-modal Blocks all windows from the same document with the excep- tion of those windows from its child hierarchy. Application-modal Blocks all windows from the same application with the exception of those windows from its child hierarchy. Toolkit-modal Blocks all windows from the same toolkit with the exception of those toolkits from its child hierarchy. The following example demonstrates the mode-less type of dialog creation, which means that the dia- log box does not block any other window rendered on the user display. The intent of this new modality inclusion is to scope dialog box displays so they cannot block operations from one another during pro- gram operations. The new Tray feature provides a shortcut capability that allows users to quickly invoke their applica- tions for deployment from the desktop tray. Figure 4-17 is deployed when the desktop icon is clicked. Along with the system tray integration, this application demonstrates the inclusion of several new capa- bilities included in the Mustang release, specifically a splash screen pop-up, new Modal APIs, the ability to obtain file system attributes, perform authentication operations upon invocation, and to append Java components to a tabbed display. Figure 4-17 This code segment is kicked off when the user clicks the icon in the desktop tray. New Modal capabilities are demonstrated with the Frame and Dialog components. The new Dialog class allows developers to limit a dialog’s blocking capability when rendered. This feature circumvents previous versions of Java that blocked input to other top-level windows that were part of an application and were not created with the dialog box as its parent. Now dialog boxes can have a null parent that limits the scope of a dia- log box’s modality: package tray; import java.awt.*; import java.awt.datatransfer.*; import java.io.*; import java.sql.*; 215 Chapter 4: Developing Effective User Interfaces with JFC 09_777106 ch04.qxp 11/28/06 10:43 PM Page 215 import java.util.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.event.*; public class TrayDemo { private static Frame frame; private Font labelFont = new Font(“Arial”, 18, Font.PLAIN); private Dialog dialog = new Dialog(frame, “Modeless Dialog”); private Dialog dialog2 = new Dialog(frame, “Document-modal Dialog”, Dialog.ModalityType.DOCUMENT_MODAL); private JPanel tab, tab2; private JLabel[] label = { new JLabel(“Question 1”), new JLabel(“Question 2”), new JLabel(“Question3”) }; private JTabbedPane tabbedPane; private Dialog dialogConsole = new Dialog(frame, “Modeless Dialog”); private static Vector<String> v = new Vector<String>(); private JTextField urlTextfield = new JTextField(30); private JTextField emailTextfield = new JTextField(30); private JButton btnBrowser = new JButton(); private JButton btnEmail = new JButton(); private String username = “”, password =””; Once the TrayDemo constructor attempts to invoke the splash screen pop-up by executing the get SpashScreen() method from the SplashScreen class, a check is performed to ensure that the system tray can be placed on the system desktop. Passage through this check will allow the application to retrieve an icon and place it in the system tray so users can invoke the application with the new desktop icon. A MouseListener class is initialized and instantiated so the application can be popped up when a mouse click event on the desktop icon is detected: public TrayDemo() { final TrayIcon trayIcon; final SplashScreen splash = SplashScreen.getSplashScreen(); if (splash == null) { System.out.println(“SplashScreen.getSplashScreen() returned null”); } if (SystemTray.isSupported()) { SystemTray tray = SystemTray.getSystemTray(); Image image = Toolkit.getDefaultToolkit().getImage(“tray.gif”); MouseListener mouseListener = new MouseListener() { public void mouseClicked(MouseEvent e) { System.out.println(“Tray Icon - Mouse clicked!”); frame = new Frame(“SDK 6 - Modal implementation”); JTextComponent textComp = createTextComponent(); textComp.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(“Text”), BorderFactory.createEmptyBorder(5,5,5,5)), 216 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_777106 ch04.qxp 11/28/06 10:43 PM Page 216 [...]... its state to files Java provides a couple of built-in mechanisms for saving or serializing data to disk The two major APIs in the JDK for persisting application data to disk are the Java Serialization API for generic serialization and the XMLEncoder/Decoder API for serializing JavaBean components This chapter looks at the Java Serialization API, the XMLEncoder/Decoder API, and the Java API for XML Binding... enables an acknowledgment radio button when the user moves the scroll pane knob to the bottom of the license viewer: package com.wizard; import import import import import java. awt.*; java. awt.event.*; javax.swing.*; javax.swing.border.*; java. util.logging.Logger; public class OrangeState extends State { private static Logger log = Logger.getLogger(“OrangeState”); private JPanel panelOrange; static private... based on those standards such as XMLEncoder/Decoder Other tools that utilize JavaBeans conventions are object-relational-mapping tools, which allow the developer to map Java objects to a database Most of Java s third-party serialization tools require classes to use JavaBeans conventions It is just good practice and design 240 Chapter 5: Persisting Your Application Using Files foreground (instance of... toolsWindowPosition java. awt.Point 1 -… -backgroundColor, foregroundColor java. awt.Color -… 2 Figure 5-2 Configuration is the root object It uses classes from java. awt to represent colors and points In the object graph shown in Figure 5-3, you can see that an instance of configuration also contains references to instances of java. awt.Color and java. awt.Point When you persist the information in a Configuration... point in time You will design Configuration using the JavaBeans architecture (getXXX and setXXX for all properties in your class) The application itself will read the configuration settings from this class and appropriately apply them throughout the application It is typical to use JavaBeans conventions to store data in Javabased data models Using the JavaBeans standard allows the designer to use many... on the GUI display (see Figure 4- 19) 225 Part II: A Broad Understanding of Java APIs, Tools, and Techniques Figure 4- 19 The InstallationWizard application implements two JPanel components, componentPanel and buttonPanel, to display the individual Swing visualizations for user input and the buttons used for previous/next operations, respectively: // [InstallationWizard .java] // package name and import... How exactly do Java applications store their data model in memory? Because Java is an object-oriented language, most applications have a set of data classes (which is the application’s data model) Instances of these data classes reside in memory and the viewer and controller components (the UI) of the application interact with them to produce the functionality of the application Any Java class that... Figure 4- 18 demonstrates a new Mustang enhancement to allows GUI developers to append Java components to a tab display Previously, users were only allowed to implement icons and text items to a tab The following sample display allows users to answer Yes or No for questions on the first two tabbed panes from drop-down menus and to select answers from checkboxes on the last tabbed component Figure 4- 18... fields of a particular class? Java s reflection mechanism allows the dynamic ability to find out the fields and field values of any class, whether those fields are marked public or private Thankfully, the Java Serialization API takes care of all these details for you, and it is easy to serialize object instances to disk It is important to note that the file format used by the Java Serialization API is... disk It is important to note that the file format used by the Java Serialization API is a special binary file format developed specifically for Java Serialization and therefore not human-readable It is an efficient format, but also specific to Java Key Classes The Java Serialization API hides most of the complexity required to save object graphs to disk (such as circular references and multiple references . tray; import java. awt.*; import java. awt.datatransfer.*; import java. io.*; import java. sql.*; 215 Chapter 4: Developing Effective User Interfaces with JFC 09_7771 06 ch 04. qxp 11/28/ 06 10 :43 PM Page. in earlier sections of this chapter. 2 14 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 09_7771 06 ch 04. qxp 11/28/ 06 10 :43 PM Page 2 14 The following table outlines the four. based on the user’s navigations. 207 Chapter 4: Developing Effective User Interfaces with JFC 09_7771 06 ch 04. qxp 11/28/ 06 10 :43 PM Page 207 Figure 4- 14 GroupLayout The GroupLayout manager is a