📄 s03.htm
字号:
与其他的轻量Swing组件一样,JSlider也通过UIManager获得UI代表。在3.2.6节中介绍了UIManager.getUI()实例化一个UI代表的方式:这里知道UIManager.getUI()返回一个UI代表就够了。<br> 表3-2示出了在JComponent类中定义的、与组件的UI代表有关的方法(注:JComponent类是所有轻量Swing组件的超类,参见第4章“JComponent类”)。<br> 所有的轻量Swing组件都继承表3-2所列的方法,以设置和获得它们的UI代表。其中updateUI方法更新UI代表以便与当前的界面样式匹配。getUIClassID方法返回一个表示组件的UI代表类的字符串,该方法还用于对UI代表实例化,参见3.2.6节中有关创建UI代表的介绍。<br> <b>表3-2 JComponent的UI代表方法</b><br> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br> 方法 描述 <br> ─────────────────────────────────<br> <UI>getUI() 返回对一个组件的UI代表的一个引用 <br> ─────────────────────────────────<br> void setUI(<UI>) 设置一个组件的UI代表<br> ─────────────────────────────────<br> void updateUI() 为当前的界面样式更新一个组件的UI代表<br> ─────────────────────────────────<br> String getUIClassID() 返回一个字符串,该字符串是这个UI代表的类名<br> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br> ①<UI>=UI代表类名,例如,ButtonUI、LabelUI等等。 <br> 表3-2中的<UI>指一个组件的UI代表的类名。例如,JButton以如下方式定义表3-2所列的前两种方法:<br> ButtonUI getUI()<br> void setUI(ButtonUI ui)<br> UI代表的类名可以通过从组件的类名中去掉“J”并添加上一个“UI”来获得。例如,JButton的UI代表的类名是ButtonUI,JSlider的UI代表类名则是SliderUI。<br> UI代表类名表示的是javax.swing.plaf包中的抽象类。例如,一个按钮的UI代表的全称类名是抽象的javax.swing.plaf.ButtonUI。<br> javax.swing.plaf包还包括抽象的ComponentUI类,该类为所有的UI代表定义基本行为。ComponentUI类是javax.swing.plaf中抽象UI代表类的超类。例如,ButtonUI和SliderUI,以及所有其他的javax.swing.plaf UI类都扩展javax.swing.plaf.ComponentUI。<br> Javax.swing.plaf.basic包提供实现Swing界面样式的通用部分的类。javax.swing.plaf.basic包的UI代表提供缺省绘制功能和一些事件处理行为,它们可以在需要时用与界面样式有关的类来重载。<br> 图3-11示出了BasicSliderUI类的类图。<br> 滑杆的UI代表跟踪与滑杆的外观有关的属性。滑杆UI代表还为缺省事件处理行为使用了许多监听器。<br> BasicSliderUI类被MetalSliderUI、WindowsSliderUI和MotifSliderUI等与界面样式有关的滑杆UI类扩展。<br> 与“模型”中对模型的介绍一样,下面对UI代表的讨论将通过考察UI代表的案例,从静态认识转移到动态认识。 </p> <p> <b>3.2.6 组件UI的案例</b></p> <p> 为了理解UI代表是怎样与它们的组件一起工作的,有必要了解两个关键案例:绘制UI代表,把UI代表安装到一个组件中。<br> 1.绘制UI代表<br> 图3-12所示的流程图显示了在Swing按钮绘制时(注:有关绘制Swing轻量组件更详细的情况,请参见4.3节“绘制JComponent“。)所发生的事件序列。图3-12中示出的序列对所有的轻量组件都是类似的。JButton.paintComponent()为这个按钮的UI代表调用updage方法。BasicButtonUI.paint()方法绘制这个组件,这个按钮然后绘制该按钮的边框和这个组件的子组件。<br> 如图3-12所示,JLabel、JButton等组件类与它们的UI代表一起共同完成绘制任务。UI代表负责绘制组件本身,组件类负责绘制组件的边框和组件的子组件(注:大多数组件没有子组件)。 <br> 2.安装一个UI代表<br> 图3-13图解说明了把一个UI代表插入一个组件时发生的事件序列。<br> 从JButton构造方法中激活JButton.updateUI()。与其他轻量Swing组件的updateUI方法一样,JButton.updateUI()从UI管理器获得它的UI代表。这个按钮把一个对它本身的引用传递给UIManager.getUI():<br> //From JButton.java<br> public void updateUI(){<br> setUI((Button) UIManager.getUI(this));<br> }<br> UIManager.getUI()使用UIDefault的一个实例,并调用UIDefaults.getUI()来创建UI代表。<br> //From UIManager.java<br> public static ComponentUI getUI(JComponent target){<br> ...<br> ComponentUI ui=null;<br> ...<br> if(ui==null){<br> ui=getDefaults().getUI(target);<br> }<br> return ui;<br> }<br> UIDefaults.getUI()是所有动作发生的地方,包括实例化UI代表。下面列出了UIDefaluts.getUI方法:<br> //From UIDefaults.java:<br> public ComponentUI getUI(JComponent target){<br> ClassLoader uiClassLoader=<br> target.getClass().getClassLoader();<br> Class uiClass=getUIClass (target.getUIClass(),<br> uiClassLoader);<br> object uiObject = null;<br> if(uiClass==null){<br> getUIError("no ComponentUI class for: "+target);<br> }<br> else{<br> try{<br> Method m=(Method) get(uiClass);<br> if(m==null){<br> Class acClass=javax.swing.JComponent.class;<br> m=uiClass.getMethod(" createUI",<br> new Class[]{acClass})<br> put(uiClass,m);<br> }<br> uiObject = m.invoke(null,new object[]{target});<br> }<br> catch (NoSuchMethodException e){<br> getUIError(" static createUI() method not"+<br> " found in"+ uiClass);<br> }<br> catch(Exception e){<br> getUIError(" createUI() failed for"+ target +<br> " "+e);<br> }<br> }<br> return(ComponentUI) uiObject;<br> }<br> UIDefaults.getUI()必须能够实例化任何类型的UI代表。例如,如果当前的界面样式是Java的界面样式,则必须为滑杆实例化MetalSliderUI实例;如果当前的界面样式是Windows的界面样式,则必须为滑杆实例化WindowsSliderUI实例,等等。另外,UIDefaults.getUI()还必须能够实例化那些将开发出来的UI代表实例。显然,用new语句来实例化UI代表不是一个可行的选择。<br> 为了实例化任何类型的UI代表,UIDefaults.getUI()使用了Java的反射功能。UIDefaults.getUI()以一个对组件的引用(UI代表就是为这个组件的而创建的)作为参数。再用这个组件来获得对这个UI代表类的引用。<br> 有了UI代表类,再把反射功能用于获得对UI代表的static createUI方法的一个引用,然后再用Method.invoke()来调用这个方法(用这个组件作为参数)。所有UI代表实现一个 static createUI方法,该方法返回一个对UI代表的引用。下面介绍有关createUI方法的更多信息。</p> <p> 1、ComponentUI类<br> swing.plaf包中的ComponentUI类是所有SwingUI代表的抽象基类。UI代表不维护对组件的引用,反之,ComponentUI类的方法接受一个对JComponent的引用作为参数这样,一个UI代表可以被多个组件所共享。在JComponent上操作的共享对象是Swing的一个中心主题,例如,边框和图标设计成以一种类似的方式共享(参见第5章“边框,图标和动作”)</p> <p></p> <p> </p> <p> </p> <p> </p> <p><br> <br> ----<br> <a href="#" onclick=window.open("s03_t14.htm","s03_t14","width=300,height=170,toolbar=0,status=0,location=0,menubar=0,resizable=1") language=javaScript>图3-14</a> 一个定制的界面样式<br> ---- <br> 例3-4 列出了图3-14所示的小应用程序的完整代码。</p> <p align="center"> <b>例3-4 一个定制的UI代表</b></p> <hr size="1" noshade> import javax.swing.*;<br> import javax.swing.border.*;<br> import javax.swing.plaf.basic.*;<br> import java.awt.*;<br> import java.awt.event.*; <p>public class Test extends JApplet {<br> private String s = new String();</p> <p> public void init() {<br> Container contentPane = getContentPane();<br> JButton button = new JButton(new ImageIcon(this.getClass().getResource("punch.gif")));</p> <p> button.setUI(new PopOutButtonUI());<br> contentPane.setLayout(new FlowLayout());<br> contentPane.add(button);</p> <p> button.addActionListener(new ActionListener() {<br> public void actionPerformed(ActionEvent e) {<br> showStatus(s += '+');<br> }<br> });<br> }<br> }<br> class PopOutButtonUI extends BasicButtonUI { <br> public void installUI(JComponent c) {<br> AbstractButton button = (AbstractButton)c;<br> Border border = button.getBorder();</p> <p> ImageIcon icon = (ImageIcon)button.getIcon();<br> int iconW = icon.getIconWidth();<br> int iconH = icon.getIconHeight();</p> <p> Image scaled = icon.getImage().getScaledInstance(<br> iconW + (iconW/3),<br> iconH + (iconH/3),<br> Image.SCALE_SMOOTH);</p> <p> c.putClientProperty("oldBorder", border);<br> c.setBorder(null);</p> <p> button.setRolloverIcon(new ImageIcon(scaled));<br> installListeners(button);<br> }<br> public void uninstallUI(JComponent c) {<br> Border border = (Border)c.getClientProperty("oldBorder");</p> <p> c.putClientProperty("oldBorder", null);<br> c.setBorder(border);<br> uninstallListeners((AbstractButton)c);<br> }<br> public Dimension getPreferredSize(JComponent c) {<br> Dimension ps = super.getPreferredSize(c);</p> <p> ps.width += ps.width/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -