QA@IT

JCombobox(プルダウン表示時)からクリックで隣のコントロールへのフォーカス移動

3631 PV

みなさまご教示下さい。

Windows8.1+Java7環境での動作についてです。

JComboBoxでドロップダウンリスト(ポップアップメニュー)を表示させた状態で、
となりに配置してあるJTextFieldにマウスクリックでフォーカス移動してようとしても、
ドロップダウンリスト(ポップアップメニュー)が閉じるだけで、フォーカス移動してくれません。

Java1.5環境では、ドロップダウンリスト(ポップアップメニュー)が閉じ、フォーカス移動も行なわれます。
Java7でも同様な動きにしたいと思っているのですが、原因の特定、対処方法等ありますでしょうか?

恐れ入りますが、みなさまご教示下さい。よろしくお願い致します。

追記:

以下のようにLookAndFeelの設定の行うと当事象が発生します。
行わない場合、Windows8.1+Java7でも当事象は発生しません。

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

回答

当方Windows7+Java7u67ですが質問者さんがおっしゃるようにL&Fを設定すると再現しました。
L&Fを決めるクラスはcom.sun.java.swing.plaf.windows.WindowsLookAndFeelでした。
ちなみにmotifやnimbusでも同様の振る舞いのようで、質問者さんがお望みの振る舞いをするのはデフォルトのmetalだけのようです。

素人っぽい確認ですが試しにWindowsのネイティブアプリケーションの一つであるメモ帳のフォントダイアログを開いてコンボボックスの動作を試すと同様の動作をすることから「これが今時のWindowsのsystem L&Fです」と言われると「そういうものかな」と納得できる気がしました。

このフォーカスの問題の対応策についていえばL&Fをデフォルトのmetalにするのが一番簡単ですがmetalに変更することで他のUIの振る舞いが希望とは違ってしまうこともあり得ます。なんらかの事情でL&FをmetalにしたくないならWindowsLookAndFeelでのComboBoxのUIオブジェクト(com.sun.java.swing.plaf.windows.WindowsComboBoxUI)などを調べて振る舞いを変える方法を探るか画面が比較的簡単であればfocusEventなどのイベント処理で対処療法的な工夫を考えることになると思います。ただ、自分にとってはL&Fのデフォルト動作を変えるというのは適切な方法を見つけ出すのに時間がかかりすぎるので具体的方法については他の方にお譲りします。補足情報のみしかなくてすみません。

編集 履歴 (0)

KSwordOfHast様
argius様

いろいろとありがとうございました。

やはり、L&Fをmetalにはできない状況ですので、
focusEvent等で制御できないか調べてみたいと思います。

また、ComboBoxのUIををmetalにして試してみたいと思います。

編集 履歴 (0)

argius様

申し訳ありません。私の環境ですがWindows8.1+Java7でした。
情報が足らず申し訳ありません。

編集 履歴 (0)
  • こちらでもWindows8.1+Java7で試しましたが、再現しませんでした。
    他に、ブラウザー上で実行しているとか、どのようにレイアウトしているとか、再現条件はありませんか?
    -
  • 何度も申し訳ありません。

    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    LookAndFeelの設定を行うと今回の事象になるようです。
    行わない場合、Windows8.1でも当事象は発生しませんでした。
    JavaバージョンというよりはOSの違いになるのでしょうか?


    -
  • 再現させることができました。ありがとうございます。
    Java6でも発生しました。Java5では確かに起きませんね。これはJava6からWindowsLookAndFeelの挙動が変わったってことなんでしょうね。具体的な対応方法は、KSwordOfHastさんが書かれているようことをやってみるしかないと思います。お役に立てなくてすみません。
    -

Windows7+Java7u60のappletviewerで、下記のJAppletJComboBoxを使ったサンプルで確認しましたが、再現しませんでした。
Windows8.1+Java7u67(64bit)でも再現しませんでした。

再現させるには、他にどんな条件が要りますか?

import javax.swing.*;

public final class Sample extends JApplet {

    @Override
    public void init() {
        super.init();
        JPanel p = new JPanel();
        add(p);
        p.add(new JComboBox(new String[]{"foo", "bar", "baz"}));
        p.add(new JTextField(30));
    }

}

編集 履歴 (2)
ウォッチ

この質問への回答やコメントをメールでお知らせします。