4

我有一个 Swing 应用程序,其中包含一个主框架和一些其他表单。我需要实现一种通用方法来为任何表单上的所有按钮设置手形光标。

这类似于我们在网页上使用 css ( input[type=button] { cursor:pointer; })

4

2 回答 2

6

如果您想动态地和/或在特定表单上更改光标,那么像@Madprogrammer 建议的那样走树是一种方法。

只是为了好玩(并再次炫耀SwingX :) - 如果您想全局安装该光标然后不关心,请安装一个 ui-delegate 来处理它。在 SwingX 中,它就像实现和插入自定义按钮插件一样简单。副作用与其他答案相同(尽管无法解决)。通常的缺点(在安装自定义 ui 代理时总是如此)是需要为所有 LAF 子类化和插件代理。

public class ButtonCursorAddon extends AbstractComponentAddon {

    /**
     * @param name
     */
    protected ButtonCursorAddon() {
        super("RolloverCursor");
    }

    @Override
    protected void addBasicDefaults(LookAndFeelAddons addon,
            DefaultsList defaults) {
        UIManager.getDefaults().remove("ButtonUI");
        defaults.add("ButtonUI", "org.jdesktop.swingx.plaf.ButtonCursorAddon$BasicButtonCursorUI");
    }

    @Override
    protected void addMetalDefaults(LookAndFeelAddons addon,
            DefaultsList defaults) {
        UIManager.getDefaults().remove("ButtonUI");
        defaults.add("ButtonUI", "org.jdesktop.swingx.plaf.ButtonCursorAddon$MetalButtonCursorUI");
    }

    @Override
    protected void addWindowsDefaults(LookAndFeelAddons addon,
            DefaultsList defaults) {
        UIManager.getDefaults().remove("ButtonUI");
        defaults.add("ButtonUI", "org.jdesktop.swingx.plaf.ButtonCursorAddon$WindowsButtonCursorUI");
    }


    @Override
    protected void addNimbusDefaults(LookAndFeelAddons addon,
            DefaultsList defaults) {
        UIManager.getDefaults().remove("ButtonUI");
        defaults.add("ButtonUI", "org.jdesktop.swingx.plaf.ButtonCursorAddon$SynthButtonCursorUI");
    }


    public static class BasicButtonCursorUI extends BasicButtonUI {

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

        @Override
        protected BasicButtonListener createButtonListener(AbstractButton b) {
            return new BasicHyperlinkListener(b);
        }

    }

    public static class SynthButtonCursorUI extends SynthButtonUI {

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

        @Override
        protected BasicButtonListener createButtonListener(AbstractButton b) {
            return new BasicHyperlinkListener(b);
        }

    }

    public static class MetalButtonCursorUI extends MetalButtonUI {

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

        @Override
        protected BasicButtonListener createButtonListener(AbstractButton b) {
            return new BasicHyperlinkListener(b);
        }

    }

    public static class WindowsButtonCursorUI extends WindowsButtonUI {

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

        @Override
        protected BasicButtonListener createButtonListener(AbstractButton b) {
            return new BasicHyperlinkListener(b);
        }

    }

}

// usage: plug-in once in your application code (before creating any buttons)
static {
    LookAndFeelAddons.contribute(new ButtonCursorAddon());
}

我收到此错误: UIDefaults.getUI() failed: no ComponentUI class

对我有用 - 在向 UIManager 注册 ui 类时,它需要完全限定的类名来实例化委托:

// here the ButtonCursorUI is in package
// org.jdesktop.swingx.plaf
defaults.add("ButtonUI", "org.jdesktop.swingx.plaf.ButtonCursorAddon$WindowsButtonCursorUI");
// in another package that would be
defaults.add("ButtonUI", myPackageName + ".ButtonCursorAddon$WindowsButtonCursorUI");

通常,您将在 some.plaf 的 LAF 特定子包中拥有不同的代表(而不是在插件本身中)但是,这是一个示例 :-)

于 2012-08-18T09:45:03.673 回答
5

基本上,你必须走容器和子容器......

不过要小心,你会惊讶于什么是按钮

public static void setButtonCursor(JComponent component, Cursor cursor) {

    for (Component comp : component.getComponents()) {

        if (comp instanceof JButton) {

            comp.setCursor(cursor);

        } else if (comp instanceof JComponent) {

            setButtonCursor((JComponent)comp, cursor);

        }

    }

}

JComboBox这具有进入s (以及其他组件)并更改其下拉按钮的光标的良好副作用,所以要小心;)

于 2012-08-18T05:41:27.240 回答