1

我需要创建一些 JSpinner 控件,我可以在其中检测按钮按下,同时使用当前的外观和感觉。我发现我可以很容易地做到这一点,如下所示:

class CustomSpinnerUI extends BasicSpinnerUI {
    @Override
    protected Component createNextButton() {
        // Add custom ActionListener.
    }

    @Override
    protected Component createPreviousButton() {
        // Add custom ActionListener.
    }
}

问题是这样做我最终得到了一个看起来很讨厌的微调器,它与我的 UI 的其余部分使用不同的外观和感觉。我目前正在使用Nimbus,但我需要支持不同的 L&F 配置。

我考虑过可能设置某种动态代理,但找不到任何合适Spinner的接口让我能够做到这一点。

谁能想到解决问题的方法?我想我要么需要在ActionListeners没有子类化的情况下按下按钮BasicSpinnerUI,要么想办法让我CustomSpinnerUI使用正确的 L&F。

编辑:“默认外观”->“当前外观”。

4

1 回答 1

5

对(公认的)问题“如何访问按钮以挂接自定义 actionListener”的一个肮脏的技术答案是循环通过微调器的子项并将侦听器添加到按钮中,由其名称标识:

    JSpinner spinner = new JSpinner();
    Action action = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            LOG.info("button " + ((Component) e.getSource()).getName());
        }
    };
    for (Component child : spinner.getComponents()) {
        if ("Spinner.nextButton".equals(child.getName())) {
            ((JButton) child).addActionListener(action);
        }
        if ("Spinner.previousButton".equals(child.getName())) {
            ((JButton) child).addActionListener(action);
        }
    }
  • 这很脏,因为它依赖于 LAF 可能会或可能不会尊重的未记录实施细节:Metal、Nimbus 会;赢了(我认为这是一个疏忽,但那是另一回事:-)
  • 这只是技术性的,因为从最近对该问题的评论来看,真正的问题似乎在其他地方
于 2011-10-06T12:21:54.500 回答