概述Swing核心组件
创始人
2024-04-17 04:51:10
0

UI Delegate

如果说模型接口是最编写自定义组件最重要的部分,那么UI delegate则是最复杂的部分。主要问题在于:如何编写绘制逻辑使得他在所有的look and feels上都一致?有时,除非你编写每个look and feels所对应的UI delegate(像 SwingX project 就是通过这种方式),否则是无法实现的。但是,在某些情况下你会发现你可以通过组装现有的Swing核心组件来达到这种仿真的效果,在后面的部分,UI delegates代码将要注意那些平台相关的设置比如说颜色,字体和抗锯齿。


在"  Enhancing Swing Applications" 一文中,作者描述了通过的继承定义好的look and feels的简单UI delegate实现的样板代码。以install*和unstall*方法开始,如果你不打算使用他们,第三方的look and feel 可能会在基本的功能基础上增加一些额外的功能(举个例子来说,在slider上增加鼠标滚轮滚动功能)


在我们这个例子中,我们可以看到这个自定义组件包含一个slider和一组labels(包括图标和文本),由于所有的 JComponent都是容器类,我们可以轻松地通过在我们的installComponents方法中增加JSlider和JLabel(每个 label是一个选项control point)组件来达到这种仿真的虚拟界面效果(别忘了在uninstallComponents方法中移除他们)。通过重用Swing核心组件的方式,我们的自定义组件能够使其在swing核心LAF和第三方LAF下都保持一致。


当我们增加附属组件时,为了在创建和缩放时定位这些附属组件,我们需要实现自定义的LayoutManager。这是一个非常简单的工作(甚至有点乏味):这些range在右侧纵向并排排列,相邻的range则根据其自身的weight值拥有相应空间的垂直区域,滑标则占有全部垂直空间,***个和***一个选项(control points)作为slider的起点和终点。


注意这个特殊的实现非常的困难并且几乎不可能使用单一的UI delegate来完成,举例来说,一些LAFs使用了native Api 来绘制各自的控制(像滑标的滑道与滑块)。一些第三方的LAF可能不遵循UIManager中的设置而是提供自己的颜色和自定义的Api


现在回到我们的实现(使用JSlider),我们现在面临一个有趣的问题:滑标可以通过设置snapToTicks的值来决定是否自动对齐到最近的滑块刻度。这个行为控制通过在BasicSliderUI delegate中安装mouse montion监听器实现。我们要怎么做?其中一个选择是移除这个监听器并且安装上我们所提供的实现。另一个方法是提供自定义的 BoundedRangeModel实现,当设置非关联的range时修改它的值(value)。***种方法并非***-你无法信赖其他LAF下特殊的 SliderUI delegate实现逻辑,有的实现甚至不会去调用父类的方法。第二种方法稍微好一点,不过我们选择另一种方法实现,原因稍后说明。


我们的实现对这些附属组件使用类似树/表的单元格渲染模式(Cell renderer),slider只是用来渲染并且不获取任何事件(参考CellRendererPane)。这能使我们从LAF绘图和鼠标自定义事件中获益。在我们这个特殊的例子中,如果用户在slider滑块外点击鼠标。我们通过直接设置相应的range的值 (value)来代替原本的向鼠标点击方向滚动一个”块”,这就是我们为什么不使用前面提到的第二种方法的原因:我们自定义的鼠标监听器转换鼠标点击转换相应的range(相邻的或非关联的)并且设置他们的值,一旦这个唯一的监听器被安装到组件上(指这个CellRendererPane,而这个 slider 只是一个”橡皮图章”),我们可以保证没有其他的监听器阻碍我们的代码。

组件布局


倘若我们使用单元格渲染面板,我们需要覆盖掉它的paint方法来绘制真正的滑块。我们并没有绘制那些选项标签因为他是这个组件“真正的”子组件,注意滑块的绘制在一个单独的方法中完成,这样可以允许第三方的LAF只覆盖的这个滑块的绘制逻辑而不是改变整个绘制逻辑。

  1. @Override  
  2. publicvoidpaint(Graphicsg,JComponentc){  
  3. super.paint(g,c);  
  4. this.paintSlider(g);  
  5. }  
  6.  
  7. protectedvoidpaintSlider(Graphicsg){  
  8. RectanglesliderBounds=sliderRendererPane.getBounds();  
  9. this.sliderRendererPane.paintComponent(g,this.slider,  
  10. this.flexiSlider,sliderBounds.x,sliderBounds.y,  
  11. sliderBounds.width,sliderBounds.height,true);  


测试应用程序

现在我们拥有了一个完整的自定义滑标组件,是时候该测试它了。这个测试应用程序创建了一个滑标,它包含一些相邻的和非关联的range,并为其注册了改变监听器(change listener)。一旦发生改变事件,我们计算图标的尺寸比例并绘制它(该图标使用Tango Desktop Project的SVG-to-Java2D converte来转换,具体参考  Transcoding SVG to Pure Java2D code一文)。

选择不同值的运行效果


显示了在不同look and feels下的滑标,从左到右,这些 LAF为:Windows (core), Metal (core), Motif (core), Liquid (third party), 和 Napkin (third party).如你所见,这个新组件提供了和当前所设置的LAF一致的外观。

在不同look and feel 下的自定义滑标


现在要何去何从?阅读Swing核心组件的代码。下载并学习开源组件的源代码(像SwingX 或Flamingo),然后开始构造你自己梦想中组件吧!

【编辑推荐】

  1. Swing应用程序处理函数
  2. 浅谈SwingWorker的使用
  3. AWT,SWT和Swing的布局管理器与Look And Feel机制
  4. 概述SWT采用AWT和Swing的一些优点
  5. Swing组件的paint方法的处理流程

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...