getRootPane()默认按钮 - 这是一个错误吗?

时间:2013-03-21 12:57:21

标签: java swing jbutton defaultbutton

我做了一个SSCCE。请注意,它必须是Windows外观和感觉。

import java.awt.*;
import javax.swing.*;

public class DefaultButtonBug {
private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";

public static void main(String[] args) {

    try {
        UIManager.setLookAndFeel(LAF_WINDOWS);
    } catch (Exception ex) {
        System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
        System.exit(1);
    }

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            JPanel content = new JPanel();
            JButton defaultButton = new JButton("Default");

            content.add(defaultButton);

            JFrame frame = new JFrame();

            frame.getRootPane().setDefaultButton(defaultButton);
            frame.setContentPane(content);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);                
        }
    });
}
}
  • 启动此
  • 按钮应该是聚焦的。如果没有,请单击它。
  • 点击任何其他窗口,以确保当前窗口失去焦点
  • 即使此窗口没有焦点,该按钮也会保持蓝色色调的动画效果!

按钮'脉冲'动画是标准Java L& F中没有的。

注意当此按钮不再是默认按钮(删除代码中的相应行)时,窗口失去焦点后按钮将变为灰色,并且没有任何动画。

我的问题是:这被认为是一个错误吗?因为当窗口隐藏在另一个窗口后面时,这使得EDT继续做东西而不是空闲(我做了一些分析)。事实上,这最让我烦恼的是:隐藏窗口不会让EDT闲置。

1 个答案:

答案 0 :(得分:2)

  

getRootPane()默认按钮 - 这是一个错误吗?

  • 不像@Guillaume Polet

  • 的评论中所述
  • 但我倾向于使用KeyBindings,因为任何带有FocusInWindow的JComponents和添加的ActionListener都可以消耗() ENTER 键,对于所有JButtons JComponents

  • 焦点可以通过getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)

  • 进行管理
  • 通知(Win OS)JButton也在KeyBindings中实现了TAB作为加速器。

来自代码

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class DefaultButtonBug {

    private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(LAF_WINDOWS);
        } catch (Exception ex) {
            System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
            System.exit(1);
        }
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JPanel content = new JPanel();
                JButton focusedButton1 = new JButton("Focused");
                focusedButton1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("Focused pressed");
                    }
                });
                content.add(focusedButton1);
                final JButton defaultButton2 = new JButton("Default");
                defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
                defaultButton2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("Default pressed");
                    }
                });
                defaultButton2.getModel().addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        ButtonModel model = (ButtonModel) e.getSource();
                        if (model.isRollover()) {
                            defaultButton2.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
                        } else {
                            defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
                        }
                    }
                });
                content.add(defaultButton2);
                JFrame frame = new JFrame();
                frame.getRootPane().setDefaultButton(defaultButton2);
                frame.getRootPane().getInputMap(
                        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)
                        .put(KeyStroke.getKeyStroke("ENTER"), "clickButton");
                frame.getRootPane().getActionMap().put("clickButton", new AbstractAction() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        defaultButton2.doClick();
                    }
                });
                frame.getRootPane().setDefaultButton(defaultButton2);
                frame.setContentPane(content);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

当天的学习项目

    Win7 / 8(Java6 / 7)上的
  • 允许在un_focused Java窗口上进行鼠标事件(对于所有标准L& F),可以将ChangeListener的监听器添加到ButtonModel

  • 不适用于WinXP

专注

enter image description here

enter image description here

un_fosused触发相同的事件a

enter image description here

修改

在用JDK7_011编译的Win7中的

闪烁JButton(专注于Java窗口),带有蓝色

  • 第二期闪烁蓝色

enter image description here

enter image description here