超级链接和启动浏览器
许多程序都会在 “about” 对话框中呈现超级链接。单击超级链接时,程序将启动默认浏览器,并为用户打开应用程序的网站。我想 “about” 对话框中的超级链接是可以用类来描述的,所以我创建了一个
DE>AboutBox (JFrame frame, String centerMode) { super (frame, "AboutBox", true /* modal */); // Create a pane that presents this dialog box's text. Surround the pane // with a 5-pixel empty border. Pane pane = new Pane (5); pane.setPreferredSize (new Dimension (250, 100)); // Create a title with a drop shadow for the pane. Font font = new Font ("Verdana", Font.BOLD, 32); Pane.TextNode tn = pane.new TextNode ("About Box", font, Color.blue, Pane.TextNode.CENTERX, Pane.TextNode.CENTERY, Color.black); pane.add (tn); // Create a link for the pane. font = new Font ("Verdana", Font.BOLD, 12); tn = pane.new TextNode ("Jeff Friesen", font, Color.blue, Pane.TextNode.CENTERX, 80, null, "http://www.javajeff.mb.ca", Color.red); pane.add (tn); // Add pane to the center region of the dialog box's content pane. getContentPane ().add (pane); // Create a button for disposing the dialog box. final JButton btnOk = new JButton ("Ok"); btnOk.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent e) { dispose (); } }); // Add button via an intermediate panel that causes button to be laid // out at its preferred size to the south region of the dialog box's // content pane. getContentPane ().add (new JPanel () {{ add (btnOk); }}, BorderLayout.SOUTH); // Resize all components to their preferred sizes. pack (); // Center the dialog box with respect to the frame window or the screen. setLocationRelativeTo (centerMode.equals ("W") ? frame : null); } DE>
DE>Pane (int borderSize) { // Create a solid color border that both surrounds and is part of the // this component. Select the panel background color that is appropriate // to this look and feel. setBorder (new MatteBorder (borderSize, borderSize, borderSize, borderSize, UIManager.getColor ("Panel.background"))); } DE>
该组件将文字存储为
DE>text DE> 指定要绘制的文字 DE>font DE> 指定要使用的字体 DE>font DE> 指定要使用的文字颜色 DE>x DE> 指定第一个字符的起始列 DE>y DE> 指定每个字符基线所在的行
第二简单的构造函数是:
DE>TextNode (String text, Font font, Color color, int x, int y, Color shadowColor, String url, Color activeLinkColor) { this.text = text; this.font = font; this.color = color; this.x = x; this.y = y; this.shadowColor = shadowColor; this.url = url; this.activeLinkColor = activeLinkColor; if (url != null) { addMouseListener (new MouseAdapter () { public void mousePressed (MouseEvent e) { int mx = e.getX (); int my = e.getY (); if (mx >= TextNode.this.x && mx < TextNode.this.x+width && my > TextNode.this.y-height && my <= TextNode.this.y) { active = false; repaint (); } } public void mouseReleased (MouseEvent e) { int mx = e.getX (); int my = e.getY (); if (mx >= TextNode.this.x && mx < TextNode.this.x+width && my > TextNode.this.y-height && my <= TextNode.this.y) { active = true; repaint (); Launcher. launchBrowser (TextNode.this.url); } } }); addMouseMotionListener (new MouseMotionListener () { public void mouseMoved (MouseEvent e) { int mx = e.getX (); int my = e.getY (); if (mx >= TextNode.this.x && mx < TextNode.this.x+width && my > TextNode.this.y-height && my <= TextNode.this.y) { if (!active) { active = true; repaint (); } } else { if (active) { active = false; repaint (); } } } public void mouseDragged (MouseEvent e) { } }); } } DE>
保存参数后,该构造函数会在 Pane 中注册一个鼠标监听器(假设
DE>class Launcher { static void launchBrowser (String url) { try { // Identify the operating system. String os = System.getProperty ("os.name"); // Launch browser with URL if Windows. Otherwise, just output the url // to the standard output device. if (os.startsWith ("Windows")) Runtime.getRuntime () .exec ("rundll32 url.dll,FileProtocolHandler " + url); else System.out.println (url); } catch (IOException e) { System.err.println ("unable to launch browser"); } } } DE>
DE>public void paintComponent (Graphics g) { // Prevent jagged text. ((Graphics2D) g).setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Because the border is part of the panel, we need to make sure that we // don't draw over it. Insets insets = getInsets (); // Paint everything but the border white. g.setColor (Color.white); g.fillRect (insets.left, insets.top, getWidth ()-insets.left-insets.right, getHeight ()-insets.top-insets.bottom); // Render all nodes. Iterator iter = nodes.iterator (); while (iter.hasNext ()) { TextNode tn = (TextNode) iter.next (); tn.render (g, insets); } } DE>
每个文本节点都是由
DE>void render (Graphics g, Insets insets) { g.setFont (font); Dimension d = strDim (g, text); width = (int) d.width; height = (int) d.height; // Always drop the drop shadow (if specified) first. if (shadowColor != null) { g.setColor (shadowColor); if (x == CENTERX) x = (getWidth ()-d.width)/2; if (y == CENTERY) y = insets.top+(getHeight ()-insets.bottom-insets.top)/2; // Draw the drop shadow. g.drawString (text, x+SHADOW_OFFSET, y+SHADOW_OFFSET); } // If the text is not a link, active can never be true -- the mouse // listeners are not installed. g.setColor ((active) ? activeLinkColor: color); // If a drop shadow was drawn, x and y will never equal CENTERX and // CENTERY (respectively). This is okay because x and y must contain // the same values as specified when drawing the drop shadow. if (x == CENTERX) x = (getWidth ()-d.width)/2; if (y == CENTERY) y = insets.top+(getHeight ()-insets.bottom-insets.top)/2; // Draw the text. g.drawString (text, x, y); } DE>
图 2 当鼠标指针移动到文本上时,超级链接的文本变成了红色。单击可查看大图。
状态栏
许多应用程序都会呈现状态栏,以显示程序的名称和版本、相应于菜单的帮助文字、当前时间以及一些其他信息。由于状态栏如此有用,您可能认为 Java 包含了一个
图 3. 状态栏中当前菜单项的帮助文字
图 3 显示了一个由
列表 3. StatBar.java
DE>// StatBar.java imp ort java.awt.*; imp ort java.awt.event.*; imp ort javax.swing.*; imp ort javax.swing.event.*; public class StatBar extends JFrame { // The status label serves as this application's status bar. A description // of the currently highlighted menu/item appears on the status bar. JLabel status; // The default text appears on the status bar at program startup, and when // no other menu/item text appears. String defaultStatusText = "Welcome to StatBar 1.0!"; // The MenuItem helper class conveniently organizes the menu items for each // of the File and Edit menus. This organization reduces the amount of // source co de that appears in the StatBar() constructor, which hopefully // makes it easier to study the constructor, and facilitates adding extra // menu items in the future. class MenuItem { String label; // menu text ActionListener al; String desc; // menu description for status bar MenuItem (String label, ActionListener al, String desc) { this.label = label; this.al = al; this.desc = desc; } } // Construct StatBar's GUI and indirectly start AWT helper threads. public StatBar (String title) { // Pass application title to superclass, so that it appears on the title // bar. super (title); // When the user initiates a close operation from the System menu or by // clicking the tiny x window on a Microsoft Windows' window title bar, // terminate this application. setDefaultCloseOperation (EXIT_ON_CLOSE); // Construct the application's menu bar. JMenuBar mb = new JMenuBar (); // Create a menu listener shared by all menus on the menu bar. This menu // listener either displays default text or menu-specific text on the // status bar. MenuListener menul; menul = new MenuListener () { public void menuCanceled (MenuEvent e) { } public void menuDeselected (MenuEvent e) { status.setText (defaultStatusText); } public void menuSelected (MenuEvent e) { JMenu m = (JMenu) e.getSource (); status.setText (m.getActionCommand ()); } }; // Create a mouse listener shared by all menu items on all menus. This // mouse listener displays menu-item specific text on the status bar // whenever the mouse pointer enters the menu item. It displays default // text when the mouse pointer exits a menu item. MouseListener statusl = new MouseAdapter () { public void mouseEntered (MouseEvent e) { JMenuItem mi = (JMenuItem) e.getSource (); status.setText (mi.getActionCommand ()); } public void mouseExited (MouseEvent e) { status.setText (defaultStatusText); } }; // The first menu to appear on the menu bar is File. The user invokes // menu items on this menu to open, save, and print documents, and to // terminate the application. JMenu menuFile = new JMenu ("File"); menuFile.addMenuListener (menul); menuFile.setActionCommand ("Open document, save changes, print document " + "and terminate StatBar."); // Create a listener for each menu item on the File menu. ActionListener openl; openl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Open listener invoked."); } }; ActionListener saveasl; saveasl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Save as listener invoked."); } }; ActionListener savel; savel = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Save listener invoked."); } }; ActionListener printl; printl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Print listener invoked."); } }; ActionListener exitl; exitl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.exit (0); } }; // Identify menu items to be installed on the File menu. MenuItem [] itemsFile = { new MenuItem ("Open...", openl, "Open a document."), new MenuItem ("Save", savel, "Save changes to current document."), new MenuItem ("Save as...", saveasl, "Save current document to new " + "document."), new MenuItem ("Print...", printl, "Print current document."), new MenuItem (null, null, null), new MenuItem ("Exit", exitl, "Terminate StatBar.") }; // Install all of the previous menu items on the File menu. for (int i = 0; i < itemsFile.length; i++) { if (itemsFile [i].label == null) { menuFile.addSeparator (); continue; } JMenuItem mi = new JMenuItem (itemsFile [i].label); mi.addActionListener (itemsFile [i].al); mi.setActionCommand (itemsFile [i].desc); mi.addMouseListener (statusl); menuFile.add (mi); } // Add the file menu to the menu bar. mb.add (menuFile); // The second menu to appear on the menu bar is Edit. The user invokes // menu items on this menu to undo any changes and perform copy/cut/paste // operations on the current document. JMenu menuEdit = new JMenu ("Edit"); menuEdit.addMenuListener (menul); menuEdit.setActionCommand ("Perform various editing tasks and undo " + "changes."); // Create a listener for each menu item on the Edit menu. ActionListener undol; undol = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Undo listener invoked."); } }; ActionListener copyl; copyl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Copy listener invoked."); } }; ActionListener cutl; cutl = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Cut listener invoked."); } }; ActionListener pastel; pastel = new ActionListener () { public void actionPerformed (ActionEvent e) { System.out.println ("Paste listener invoked."); } }; // Identify menu items to be installed on the Edit menu. MenuItem [] itemsEdit = { new MenuItem ("Undo", undol, "Restore document."), new MenuItem (null, null, null), new MenuItem ("Copy", copyl, "Copy text to clipboard."), new MenuItem ("Cut", cutl, "Cut text to clipboard."), new MenuItem ("Paste", pastel, "Paste text from clipboard.") }; // Install all of the previous menu items on the Edit menu. for (int i = 0; i < itemsEdit.length; i++) { if (itemsEdit [i].label == null) { menuEdit.addSeparator (); continue; } JMenuItem mi = new JMenuItem (itemsEdit [i].label); mi.addActionListener (itemsEdit [i].al); mi.setActionCommand (itemsEdit [i].desc); mi.addMouseListener (statusl); menuEdit.add (mi); } // Add the edit menu to the menu bar. mb.add (menuEdit); // Install StatBar's menu bar. setJMenuBar (mb); // Create a status bar for displaying help text associated with the menus // and their items. status = new JLabel (defaultStatusText); status.setBorder (BorderFactory.createEtchedBorder ()); // Add the status bar to the bottom of the application's contentpane. getContentPane ().add (status, BorderLayout.SOUTH); // Establish a suitable initial size for displaying a document. setSize (450, 300); // Display GUI and start GUI processing. setVisible (true); } // Application entry point. public static void main (String [] args) { // Create the application's GUI and start the application. new StatBar ("StatBar"); } } DE>
在使用默认状态栏文字创建了
注意 |
---|
如果不希望状态栏显示任何默认文字,则需要至少输入一个空格来代替文字。如果使用空字符串 ( |
每个侦听程序都依赖于