0

SSCCEを作りました。Windows の Look&Feel である必要があることに注意してください。

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 がアイドル状態になるわけではありません。

4

1 に答える 1

2

getRootPane()デフォルトボタン-これはバグですか?

  • @GuillaumePoletのコメントに記載されているものではありません

  • ただし、FocusInWindowと追加のActionListenerを備えたENTERJComponentは、すべてのJButton JComponentに対して、押されたキーを消費できるため、KeyBindingsを使用する傾向があります。

  • フォーカスはによって管理可能です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)では、フォーカスされていないJavaウィンドウ(すべての標準L&F)でマウスイベントが許可され、ButtonModelに追加されたChangeListenerからリスナーになることができます

  • WinXPでは動作しません

焦点を当てた

ここに画像の説明を入力してください

ここに画像の説明を入力してください

un_fosusedが同じイベントを発生させる

ここに画像の説明を入力してください

編集

JDK7_011でコンパイルされたWin7で、青色のJButton(Javaウィンドウにフォーカス)が点滅します。

  • 2番目の期間に青色で点滅

ここに画像の説明を入力してください

ここに画像の説明を入力してください

于 2013-03-21T14:19:13.427 に答える