(swing读书笔记)Swing Look And Feel(3)
By cszhao1980
六.UIResource
UIResource是个空接口,它的目的是为标识一种身份,即是否为UI Resource for L&F。
考虑这样一种情况:
(1) 使用setForeground(Color),设置了前景颜色;
(2) 改变程序的L&F——此时,前景颜色是否也跟着改变呢?
答案很简单,如果设置的颜色属于UIResource,则跟着改变。否则,不变。
Swing定义了一系列的UIResource class,如下图所示:
设置UIResource的例子代码如下:
button.setForeground(new ColorUIResource(c));
七.MultiLookAndFeel
所谓Multilookandfeel,是指可以在“主UI”的基础上,添加若干“附属UI”(Auxiliary UI),如下图所示:
MetalButtonUI为主UI,负责绘制组件;
而附属UI有两个:一个用来发声,一个为盲人提供盲文——这显然只是个例子,屏幕上的盲文被盲人是无法识别的。
正如这个例子所显示的那样,实现MultiLookAndFeel的主要目的,是将accessible interfaces集成进来——当然,也可以使用附属UI来实现其他的效果。
一般来讲,附属UI不进行绘制操作,它的paint()、update()方法多为空操作,如下例所示:
// StdOutLookAndFeel.java // import javax.swing.*; import javax.swing.plaf.*;
public class StdOutLookAndFeel extends LookAndFeel {
// A few simple informational methods
public String getName( ) { return "Standard Output"; } public String getID( ) { return "StdOut"; } public String getDescription( ) { return "The Standard Output Look and Feel"; } public boolean isNativeLookAndFeel( ) { return false; } public boolean isSupportedLookAndFeel( ) { return true; }
// Our only default is the UI delegate for buttons.
public UIDefaults getDefaults( ) { UIDefaults table = new UIDefaults( );
table.put("ButtonUI", "StdOutButtonUI");
// In order to function, we'd also need lines here to define UI delegates // extending each of the following classes: CheckBoxUI, ComboBoxUI, // DesktopIconUI, FileChooserUI, InternalFrameUI, LabelUI, // PopupMenuSeparatorUI, ProgressBarUI, RadioButtonUI, ScrollBarUI, // ScrollPaneUI, SeparatorUI, SliderUI, SplitPaneUI, TabbedPaneUI, // TextFieldUI, ToggleButtonUI, ToolBarUI, ToolTipUI, TreeUI, and RootPaneUI.
return table; } } public class StdOutButtonUI extends ButtonUI {
// Use a single instance of this class for all buttons. private static StdOutButtonUI instance;
private AccessListener listener = new AccessListener( );
// Return the single instance. If this is the first time, we create the // instance in this method too. public static ComponentUI createUI(JComponent c) { if (instance == null) { instance = new StdOutButtonUI( ); } return instance; }
// Add a focus listener so we know when the buttons have focus. public void installUI(JComponent c) { JButton button = (JButton)c; button.addFocusListener(listener); }
// Remove the focus listener. public void uninstallUI(JComponent c) { JButton button = (JButton)c; button.removeFocusListener(listener); }
// Empty paint and update methods. An empty update( ) is critical! public void paint(Graphics g, JComponent c) { }
public void update(Graphics g, JComponent c) { }
public Insets getDefaultMargin(AbstractButton b) { return null; // Not called since we're auxiliary }
// A focus listener. A real L&F would want to do a lot more. class AccessListener extends FocusAdapter {
// We print some accessibility info when we get focus. public void focusGained(FocusEvent ev) { JButton b = (JButton)ev.getComponent( ); AccessibleContext access = b.getAccessibleContext( ); System.out.print("Focus gained by a "); System.out.print(access.getAccessibleRole( ).toDisplayString( )); System.out.print(" named "); System.out.println(access.getAccessibleName( )); System.out.print("Description: "); System.out.println(access.getAccessibleDescription( )); } // We print some accessibility info when we lose focus. public void focusLost(FocusEvent ev) { JButton b = (JButton)ev.getComponent( ); AccessibleContext access = b.getAccessibleContext( ); System.out.println("Focus leaving " + access.getAccessibleName( )); } } } |
使用UIManager.addAuxiliaryLookAndFeel( new StdOutLookAndFeel ())方法,就可以将附属UI,添加到当前的L&F之中。
【注】:JDK 1.4提供了Auditory Cues,可以在不添加附属UI的情况下,提供auditory。