ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 在自定义Swing组件中使用自定义UI

在自定义Swing组件中使用自定义UI

原创 Linux操作系统 作者:hawkx 时间:2010-06-09 19:08:47 0 删除 编辑
    我们知道,Swing组件使用了MVC模式,个人以为,MVC模式确实很好,就是太复杂了点。另外很头痛的就是,不知道是我理解有误,还是我没搞明白,或是Swing的设计人员的想法比较特别,当要开发一个自己的Swing组件时,对于UI的处理比较特别,困扰了我很长时间。下面概述一下如何在自定义组件中使用自定义UI。

public class JCustomComponent extends JComponent{
  private final static String uiClassID = "CustomComponentUI";

  //在静态域中向UIManager注册UI,之后才能用UIManager.getUI方法取得UI。
  static {
    UIManager.put(uiClassID, "com.test.CustomComponentUI");
  }

  //初始化组件时调用updateUI
  public JCustomComponent() {
    updateUI();
  }

  //按照Swing文档中的要求,应该定义getUI方法,其实也可以不定义
  public CustomComponentUI getUI() {
    return (CustomComponentUI) ui;
  }

  //按照Swing文档中的要求,应该定义setUI方法,其实也可以不定义
  public void setUI(CustomComponentUI ui) {
    if (this.ui != ui) {
      super.setUI(ui);
      repaint();
    }
  }

  //覆盖父类的getUIClassID,此方法会被UIManager调用。
  @Override
  public String getUIClassID() {
    return uiClassID;
  }

  //覆盖的updateUI方法,更新组件UI,如果此组件中有子组件,应该一并在此更新
  @Override
  public void updateUI() {
    setUI((CustomComponentUI)UIManager.getUI(this));
  }
}

public class CustomComponentUI extends ComponentUI {
  protected static CustomComponentUI customUI = new CustomComponentUI();
  private final static CustomComponentUI SAFE_BASIC_CUSTOM_UI = new CustomComponentUI();

  //必须定义此方法,UIManager通过反射技术调用此方法创建UI对像
  public static CustomComponentUI createUI(JComponent c) {
    //这里是抄BasicLabelUI的,注意,对于复杂的组件,
    //最好不要在createUI方法中返回静态UI对像,而应该创建新的UI对像
    if (System.getSecurityManager() != null) {
      return SAFE_BASIC_CUSTOM_UI;
    } else {
      return customUI;
    }
  }

  @Override
  public void installUI(JComponent c) {
    //在这里进行初始化工作,比如注册监听器
  }

  @Override
  public void uninstallUI(JComponent c) {
    //在这里进行清理工作,比如移除监听器
  }

  @Override
  public void paint(Graphics g, JComponent c) {
    //在这里绘制组件
    g.drawString("A custom component.", 10, 10);
  }
}


有两个地方让我很是不解和郁闷:
一、JComponent类没有调用updateUI方法,所以必须自行在构造方法中调用updateUI,真是奇怪了,既然在基类中定义了updateUI方法,并且文档中也指出子类必须覆盖updateUI方法,为什么基类竟然没有调用updateUI?

二、为什么使用反射来调用createUI方法,虽然我想不出更好的办法,但是使用反射实在不是一种正规的作法。如果不定义createUI方法,并不会产生逻辑错误,却会产生一个运行期错误,而且不能捕捉,软件也能运行,真是郁闷死个人。

这只是关于使用自定义UI的一个概述,其实不使用这种办法,而直接在updateUI方法中设置UI也是可以的,使用这种办法是因为它更符合Swing的框架,便于扩展。

如有不足和谬误,欢迎指正!

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/634491/viewspace-664818/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 修复硬盘
全部评论

注册时间:2008-01-17

  • 博文量
    37
  • 访问量
    128121