使用自定义JComponents扩展现有的Swing外观

时间:2014-04-22 07:52:51

标签: java swing custom-component look-and-feel uimanager

我正在编写一个自定义JComponent,对于不同的外观和感觉应该看起来不同。我打算至少为ComponentUiWindowsLookAndFeelMetalLookAndFeel提供不同的MotifLookAndFeel课程。

现在,虽然这项任务看起来很简单,但我无法找到如何使用自定义ComponentUi类轻松扩展现有外观。

如何针对不同的外观和感觉注册正确的ComponentUi?这有可能吗?如果没有,为不同的外观和感觉编写自定义组件的首选方法是什么?


更具体一点,目前我在我的自定义组件中覆盖JComponent#updateUI以设置不同的ComponentUi个实例:

@Override
public void updateUI() {
    LookAndFeel feel = UIManager.getLookAndFeel();
    if (feel instanceof WindowsLookAndFeel) {
        setUI(MyWindowsCustomUi.createUI(this));
    } else if (feel instanceof MotifLookAndFeel) {
        setUI(MyMotivCustomUi.createUI(this));
    } else if (feel instanceof MetalLookAndFeel) {
        setUI(MyMetalCustomUi.createUI(this));
    } else{
        setUI(MyBasicCustomUi.createUI(this));
    }
}

但这种做法似乎完全打败了外观和感觉的目的和用处。我希望能够将其更改为以下内容:

public void updateUI() {
    setUI((MyCustomUi)UIManager.getUI(this));
}

这应该为当前的外观设置正确的MyCustomUi子类。

我知道,我可以通过创建每个支持的LookAndFeel的自定义子类来轻松实现这一点,该子类在例如{0}期间注册相应的ComponentUiBasicLookAndFeel#initComponentDefaults(UIDefaults) - 但这不是我想做的事。

1 个答案:

答案 0 :(得分:4)

如果你想要或不想 - 你 以某种方式用UIManager注册你的自定义UI,它怎么知道它们; - )

您不需要的是受支持的LAF的自定义子类:您可以手动注册它们(并在更改LAF时更新注册,也就是说您需要在UIManager上使用propertyChangeListener在这种情况下通知。)

假设JCustom的classID为“CustomUI”,并且ui实现遵循通常的约定(即BasicCustomUI,WindowsCustomUI ......),注册将类似于:

 String prefix = UIManager.getLookAndFeel().getID();
 UIManager.getLookAndFeelDefaults().put("CustomUI", myUIPackage + "." + prefix + CustomUI);

请注意,自定义ui需要一个静态createUI,它返回一个ui实例:

 public static ComponentUI createUI(JComponent comp) {
     return new BasicCustomUI(); 
 }

并且组件需要发布其uiClassID,查找并设置其ui:

@Override
public String getUIClassID() {
    return "CustomUI";
}

@Override
public void updateUI() {
    setUI(UIManager.getUI(this));
}

使用SwingX的好处是提供自动注册自定义组件的基础结构。你需要一个额外的类 - CustomAddon - 它提供了每个LAF配置,而自定义组件必须贡献这个插件:

// in JCustom

static {
    LookAndFeelAddons.contribute(new CustomAddon());
}

// in CustomAddon

@Override
protected void addBasicDefaults(LookAndFeelAddons addon, DefaultsList defaults) {
    super.addBasicDefaults(addon, defaults);
    defaults.add("CustomUI",
            "mypackage.BasicCustomUI");
}

@Override
protected void addMacDefaults(LookAndFeelAddons addon, DefaultsList defaults) {
    super.addMacDefaults(addon, defaults);
    defaults.add("CustomUI",
            "mypackage.MacCustomUI");
}

//... similar methods for all supported LAFs
相关问题