2011-12-08 6 views
1

私は、FrameLayoutとJFrameを中心に様々なJPanelを設定したFrameを持っています。スイング:フォーカスコンポーネント

第1パネルでは、第1コンポーネント、つまりボタンに焦点を当てています。しかし、他のパネルやコンポーネントに焦点を当てることはできません。必要なパネルを設定する一方で、私は次のコードを使用し

public void SetMainPanel(String panel) { 
    activePanel = panel; 
    SetFontSize(); 
    cards.show(mainPanel, panel); 
    mainPanel.revalidate(); 
    mainPanel.repaint(); 
    mainPanel.requestFocusInWindow(); 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      mainPanel.grabFocus(); 
      mainPanel.getComponent(0).requestFocus(); 
     } 
    }); 
    //mainPanel.getComponent(0).requestFocusInWindow(); 
} 

をしかし、私はパネルまたはその第一のコンポーネントにフォーカスを取得することはできません。どのように設定パネルに焦点を合わせ、第1のコンポーネントに焦点を当てることができますか?最後に、各パネルに焦点を当てるために、FocusPolicy、Manager、Keyboard ....のいずれかが優れています。パネルには、すべてのボタンまたはテーブルとボタンがあります。この3種類のパネルがあります。 ところで、cardLayoutに追加されたパネルはフォーカス可能です。

任意のアイデア....

EDIT:mKorbelによって示されるように、コードが編集されています。ほとんどの場合で

+0

に近づくのです。 &setFocusTraversalPolicyProvider(true);テーブルとボタンのパネルを持つパネルの場合、テーブルからボタンのパネルにフォーカスを移すにはどうすればよいですか? – Tvd

+0

Java命名規則を覚えておいてください。 – kleopatra

答えて

2

(1コンテナ内Focus_Cycleがある)私は、コード

EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      mainPanel.getComponent(0).grabFocus(); 
      mainPanel.getComponent(0).requestFocus(); 
      // or mainPanel.getComponent(0).requestFocusInWindow(); 
     } 
    }); 
+0

mainPanel.getComponent(0).grabFocus();を使用することはできません。 - それは利用できません。私はmainPanel.grabFocus()を与えることができます。 mainPanel.getcomponent(0).requestFocus()。それで私は2回目のTAbを押して第1の構成要素に焦点を当てる。 – Tvd

+0

問題ありません。私は 'grabFocus()'を使う必要は全くなく、常に 'requestFocusInWindow()'を使っていました。 – Mot

+0

@Mike L.しかし、私は(@camickr)コードを見ることをお勧めします... – mKorbel

4

を次のためにあなたがに集中配置するパネルにいるComponentListenerを追加し、componentShown()イベントを処理することができるはず作品あなたが望むコンポーネントは何でも。

またはCard Layout Focusは、デフォルトでこの機能を提供するためにCardLayoutを拡張しています。

+0

素敵な回避策+1 – mKorbel

+0

@camickr、カードレイアウトフォーカスは私を助けていません。私はmainPanelにComponentShownイベントを追加しました。レイアウトはcardPAnelであり、他のPanelにも表示されています。 grabFocus()&getComponent(0).requestFocusInWindow();を追加しました。両方のイベントにしかし、それはとにかく状態を変えない。事実、componentShownイベントは、いずれのパネルでも一度も発生しません。 – Tvd

+0

@TVD、私はcomponentShown()がうまくいくかもしれないことを示唆しました。もしそうでなければ、私は働いていると知っている第二のアプローチをしました。 – camickr

1

Arrgg ...ロブはそれにもかかわらず、これを追加する:-)ケースを扱うための素晴らしいすぐに使用できるクラスを持つことが知られている必要があり、基礎を強調する

ベースの問題が焦点転送が完全になるということです着目しているコンポーネントが階層から削除されると混乱します(新しいカードを表示するときに発生します)。この場合、転送は手動で処理する必要があります。 Robのソリューションは健全で、基本的にこれと同じです。どちらも、card.transferFocusメッセージングによってフォーカス転送をトリガ:子(または全くフォーカス可能)

  • はデフォルトのメカニズムによって処理されるように、タイミング/キューイングの問題を残しがない場合requestFocusの利点は

    • 安全二つあります

    はここで最低限のコードスニペットは、すべてのパネルがsetFocusCycleRoot(true)を持っている

    final CardLayout layout = new CardLayout(); 
        final JComponent main = new JPanel(layout); 
        Action action = new AbstractAction("toggle cards") { 
    
         @Override 
         public void actionPerformed(ActionEvent e) { 
          layout.next(main); 
          Component visibleChild = main.getComponent(0).isVisible() ? 
            main.getComponent(0) : main.getComponent(1); 
          visibleChild.transferFocus();   
         } 
        }; 
        main.getActionMap().put("nextCard", action); 
        main.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 
         .put(KeyStroke.getKeyStroke("F2"), "nextCard"); 
        JComponent first = new JPanel(); 
        first.add(new JTextField(20)); 
        first.add(new JButton("dummy on first")); 
    
        JComponent second = new JPanel(); 
        second.add(new JTextField("I'm on the second")); 
        second.add(new JButton("me on second, too")); 
    
        main.add(first, "one"); 
        main.add(second, "two");