如何确定自定义组件的正确UI实现

时间:2013-07-22 22:35:57

标签: java swing custom-component jcomponent uimanager

我正在使用自己的自定义UI创建自定义组件。问题How to create a custom Swing Component为开发组件提供了一个很好的开端,但我找不到将自定义组件与其UI连接的好方法。

How to Write a Custom Swing Component中的代码很好,但JFlexiSlider.updateUI的实施难以对用户界面BasicFlexiSliderUI进行编码:

public void updateUI() {
    if (UIManager.get(getUIClassID()) != null) {
        setUI((FlexiSliderUI) UIManager.getUI(this));
    } else {
        setUI(new BasicFlexiSliderUI());
    }
}

标准Swing组件实现updateUI以直接从UIManager.get(this)设置UI。从UIClassID到实际实现的映射在BasicLookAndFeel和子类中。

就我而言,在我不想创建新外观的地方,我会在哪里设置从UIClassID到实际实现的默认映射?它似乎应该在组件类之外,但它需要在第一次使用自定义组件之前添加到UIDefaults对象。

2 个答案:

答案 0 :(得分:3)

重要的合作者:

  • 必须报告唯一uiClassID(在getUIClassID中)
  • 的自定义组件
  • 自定义ui委托
  • 在实例化组件之前,UIManager是将自定义uiClassId映射到ui委托类(它应该用于自定义组件)的地方

代码如下:

/**
 * The custom component
 */
public class Block extends JComponent {

    private final static String ID = "BlockUI";

    public Block(Color color) {
        // configure
        setBackground(color);
        // install ui
        updateUI();
    }


    @Override
    public void updateUI() {
        // ask the ui manager for an appropriate ui and set it
        setUI(UIManager.getUI(this));
    }

    /**
     * Implemented to return a unique component class identifier
     */
    @Override
    public String getUIClassID() {
        return ID;
    }

}

/**
 * For each supported LAF, a laf-specific implementation
 */
public class BasicBlockUI extends ComponentUI {

    public static ComponentUI createUI(JComponent c) {
        return new BasicBlockUI();
    }

    @Override
    public void paint(Graphics g, JComponent c) {
        g.setColor(c.getBackground());
        g.fillRect(10,10, c.getWidth()- 20, c.getHeight()-20);
    }

}

// usage

//let the ui manager know of our component
// the value must be the fully qualified classname
UIManager.put("BlockUI", "org.jdesktop.swingx.plaf.BasicBlockUI");

JXFrame frame = new JXFrame("custom box", true);
Block block = new Block(Color.RED);
frame.add(block);
frame.setSize(200, 200);
frame.setVisible(true);

如果您想支持多个LAF,可能需要了解最新的QA which illustrates the SwingX插件自定义组件机制。

答案 1 :(得分:0)

您可以使用setUI设置组件的用户界面。