4

Mac OS X では異なるように見える JTextField.requestFocus() の動作に問題があります。

これが私の状況です。JList と JTextField を含むダイアログがあります。ユーザーはブール式をテキスト フィールドに書き込む必要があり、リストには式に入力される可能性のあるすべての変数の名前が含まれています。リストから変数をクリックした後、ユーザーは引き続き式を入力する必要があるため、プログラムは JTextField.requestFocus() を呼び出します。このようにして、たとえば、リストから「pvalue」をクリックしてから「< 0.05」と入力できます。その間にテキストフィールドをクリックする必要はありません。

これはすべて私の開発マシン (Linux) では正常に動作しますが、Mac ユーザーから、リストをクリックするとテキスト フィールド内のすべてのテキストが実際に選択され、以前に入力したものを誤って上書きしやすくなるというバグ レポートがありました。

これは Mac のルック アンド フィールに問題があるのではないかと考えました。いくつか検索したところ、この問題に関連していると思われる Mac ルック アンド フィールの「Quaqua.TextComponent.autoSelect」プロパティが実際にあるようです。http://www.randelshofer.ch/quaqua/guide/jtextcomponent.html

私の一般的な質問は次のとおりです。

  • この問題の回避策を提案できますか?

範囲が広すぎる場合は、これらのサブ質問への回答がすでに大きな助けになります。

  • 考えられる解決策は、プロパティ「Quaqua.TextComponent.autoSelect」を変更することです。それ、どうやったら出来るの?
  • 「Quaqua」が何であるかさえわかりません。カスタマイズされたルックアンドフィールのようです。Mac OS X のデフォルトのルック アンド フィールは何ですか? Quaqua.TextComponent.autoSelect に似たプロパティはありますか?
  • 単一のコンポーネント インスタンスのみのルック アンド フィールを微調整する可能性はありますか? もしそうなら、どのように?
  • このバグを実際に確認できるように、私の Linux 開発マシンで Mac のルック アンド フィールを設定することはできますか (上記はすべて勘と疑いに基づいています)。もしそうなら、どのように?
4

8 に答える 8

5

これはMac OSのバグのようです。JTextField は、キーボードのタブ サイクリングによってフォーカスを取得すると、その内容を選択します。挿入ポイントがテキストの途中にある場合、挿入ポイントは残り、テキスト全体は選択されません。

回避策として、この動作を次のようにオーバーライドできます。私にとっては問題なく動作します。

textfield.setCaret(new DefaultCaret()).

詳細については、これこれを参照してください。

于 2013-06-14T08:02:08.513 に答える
2

JList回避策は、変数名を挿入する をフォーカス不能にすることです (私はこれをテストしていません) 。そうすれば、リスト内の項目をクリックしたときにフォーカスがテキスト フィールドに残ります。setRequestEnabled(false)で使用することをお勧めしますJList。これにより、タブで移動してもフォーカス可能ですが、マウスでクリックしてもフォーカスされません。

于 2010-01-18T05:22:28.263 に答える
2

古い質問に追加して申し訳ありませんが、この問題に遭遇し、次のコードを使用しました。これは前の例よりも少し完全なようです:

// JTextField linkedText
final int
  startBefore = linkedText.getSelectionStart(),
  endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!
SwingUtilities.invokeLater(new Runnable()
{
  public void run()
  {
    linkedText.setSelectionStart(startBefore);
    linkedText.setSelectionEnd(endBefore);
  }
});

これは、現在のカーソル位置または選択を保護するために表示されます。(注: このコードは、イベント ディスパッチ スレッドで既に実行されている必要がありますが、invokeLater が必要でないと機能しません。)

私は「is Mac」機能を持っているので、そのためのテスト内でこれを行いましたが、おそらくすべてのプラットフォームでそれを行っても害はありません.

于 2011-01-07T17:25:15.887 に答える
2

デフォルトの動作を変更するには、UI コンポーネントを初期化する前にシステム プロパティを false に設定します。System.setProperty("Quaqua.TextComponent.autoSelect", "false");単一のコンポーネントを変更するには、JTextField#putClientProperty("Quaqua.TextComponent.autoSelect", Boolean.FALSE);.

その他の MacOS L&F 固有のプロパティは、次の場所にあります。

Quaqua ルック アンド フィール - ユーザー ガイド

于 2009-10-09T13:05:05.820 に答える
1

JavaDocsを調べてみると、requestFocus()「動作がプラットフォームに依存しているため、お勧めできません」と気づきました。requestFocusInWindow()代わりにを使用して、同じ問題が発生するかどうかを確認する必要があります。

requestFocusInWindowは、Java1.4で導入されたFocusサブシステムの一部です。

apple.lafちなみに、デフォルトのApple Look and Feelには、名前空間に少なくとも1つのプロパティがあります。apple.laf.useScreenMenuBar

編集:Sunによると、MacintoshのルックアンドフィールはMacでのみ利用可能です。

于 2009-10-09T15:22:36.853 に答える
1

を使用することrequestFocusInWindow()は実際には推奨されrequestFocus()ていますが、Mac でも同じ問題のある動作が発生します (たとえば、テキスト フィールド全体が強調表示されます)。

私が取り組んだ回避策の 1 つは、フォーカスを要求した後にカーソル位置を明示的に設定することでした。

JTextField.requestFocusInWindow();
JTextField.setCaretPosition(JTextField.getDocument().getLength() - 1);

「-1」が必要であることに注意してください。そうしないと、フィールド全体が引き続き強調表示されます。

このソリューションがプラットフォームに依存しないかどうか知りたいです。これは、望ましい Linux または Windows の動作を台無しにしますか?

于 2009-10-10T23:31:34.863 に答える
0

フィールドがフォーカスされると、Mac はテキスト フィールドの内容を選択します。フォーカス変更イベントをリッスンすると、テキスト フィールドの状態を復元できます。

// JTextField linkedText
// Cache the state of the JTextField prior to requesting focus
final int
  startBefore = linkedText.getSelectionStart(),
  endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!

// Use a focus listener to listen for the focus change and then
// reset the selected text to protect the cursor position
linkedText.addFocusListener ( new FocusListener()
{
    public void focusGained( FocusEvent event ) {
        linkedText.setSelectionStart( startBefore );
        linkedText.setSelectionEnd( endBefore );
    }

    public void focusLost( FocusEvent event ) {
        // do nothing
    }
} );
于 2013-10-08T16:05:13.570 に答える
0

アイデアを共有していただきありがとうございます。Windows システムでは問題がなかった Java アプリケーションでも同じ問題が発生しましたが、Mac OS X Yosemite では入力を変更できませんでした。フォーカスは JTextField にとどまりません。このスレッドのおかげで、問題を解決できました。

ボタンと入力ボックスのルック アンド フィールを変更すると、フォーカスが維持され、再度入力できるようになります。フレームのリセットは、標準の Mac OS の外観のままです。

これは、Java メイン メソッドで使用するコードです。メインメソッドの try-catch コードを超えて問題を解決したい場合。

public class Venster extends JFrame {

    public static void main(String[] args) {

        //Change L&F for mac
        //Mac JTextField Bug Fix
        try {
            // Set cross-platform Java L&F (also called "Metal")
            UIManager.setLookAndFeel(
                    UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (UnsupportedLookAndFeelException e) {
            System.out.println("L&F not supported" + e.getMessage());

        } catch (ClassNotFoundException e) {
            System.out.println("Fout: " + e.getMessage());
        } catch (InstantiationException e) {
            System.out.println("Fout: " + e.getMessage());
        } catch (IllegalAccessException e) {
            System.out.println("Fout: " + e.getMessage());
        }

        //The app
        JFrame frame = new JFrame();
        frame.setSize(1000, 520);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("10 More Bullets by Frank Peters");
        frame.setContentPane(new SpeelVeld());
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);    //start app in center
    }
}

ソース: http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

于 2014-12-23T10:14:10.790 に答える