2009-07-24 3 views
2

私のJava GUIコードに問題があるようですが、なぜ動作しないのかわかりません。スイングコンポーネントとawtイベントに関する問題

パネルまたはフレームでマウスをクリックしたときに、何が起こる必要があるのはパネルだけです。これは単なるテストなので、このコードは別のGUIコンポーネント用に実装されますが、最初にこの機能を実装したいのですが - ポップアップメニューが表示され、フォーカスはテキストフィールドに設定する必要があります。ユーザがEnterを押すか、テキストフィールドのフォーカスが失われたら、ポップアップメニューを非表示にしてテキストを空白にするか、必要なものにリセットします。

だから、これは私が書いたものである:

public class Test { 
    private final JFrame frame = new JFrame(); 
    private final JPanel panel = new JPanel(); 
    private final JPopupMenu menu = new JPopupMenu(); 
    private final JTextField field = new JTextField(); 
    private final Obj obj; 

    //... constructor goes here 

    public void test(){ 
     frame.setSize(new Dimension(200,200)); 
     field.setColumns(10); 
     field.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent arg0) { 
       obj.method(field.getText()); 
       menu.setVisible(false); 
       field.setText(""); 
      } 
     }); 
     field.addFocusListener(new FocusListener() { 
      public void focusLost(FocusEvent e) { 
       menu.setVisible(false); 
       field.setText(""); 
      } 

      //... focus gained event goes here 
     }); 
     panel.addMouseListener(new MouseListener() { 
      public void mouseClicked(MouseEvent e) { 
       menu.setLocation(e.getX(), e.getY()); 
       menu.setVisible(true); 
       field.requestFocusInWindow(); 
      } 

      //... other mouse events go here 
     }); 

     menu.add(field); 
     frame.getContentPane().add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

コードで、私がクリックした後、メニューが自動的に右に隠してここに書かれているよう。それはちょうど画面上で短く点滅し、私は何もしないで隠す。

menu.setVisible(false)の出現を除外するようにコードを変更すると、テキストフィールドには決して焦点が当てられません。

これはJPopupMenuの悪用によるものですか?どこが間違っていますか?

また、私はメインまたはObjを省略しました。彼らは別のファイルにあり、この問題の重要性はほとんどありません。 Obj.method()は何もせず、mainはTestのコンストラクタとtest()メソッドだけを呼び出します。

+0

ポップアップメニューの目的は何ですか? – user101884

+0

私は、あなたがポップアップメニューにテキストフィールドを持っているのは間違いです。このアプローチの背景には何がありますか?おそらく、これを達成するための別の方法があります... – basszero

答えて

2

このコードは、あなたはそれが仕事をしたい方法(うまくいけば、あなたは匿名クラスの使用に従って動作するはずです:

:ときに我々は、セットアップポップアップメニューを注目すべき重要な事柄である

public class Test { 

public static void main(String[] args) { 
    Test test = new Test(); 
    test.test(); 
} 

private JFrame frame; 
private JPanel panel; 
private JPopupMenu menu; 
private JTextField field; 

public Test() { 
    frame = new JFrame(); 
    frame.setSize(new Dimension(200, 200)); 
    frame.getContentPane().add(getPanel()); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

private JPanel getPanel() { 
    if (panel == null) { 
     panel = new JPanel(); 
     panel.setComponentPopupMenu(getMenu()); 
     panel.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       menu.show(panel, e.getX(), e.getY()); 
      } 
     }); 
    } 
    return panel; 
} 

private JPopupMenu getMenu() { 
    if (menu == null) { 
     menu = new JPopupMenu() { 

      @Override 
      public void setVisible(boolean visible) { 
       super.setVisible(visible); 
       if (visible) { 
        getField().requestFocus(); 
       } 
      } 
     }; 
     menu.add(getField()); 
    } 
    return menu; 
} 

private JTextField getField() { 
    if (field == null) { 
     field = new JTextField(); 
     field.setColumns(10); 
     field.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       getMenu().setVisible(false); 
      } 
     }); 
    } 
    return field; 
} 

public void test() { 
    frame.setVisible(true); 
} 
} 

panel.setComponentPopupMenu(getMenu()); 
panel.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mouseClicked(MouseEvent event) { 
     getMenu().show(getPanel(), event.getX(), event.getY()); 
    } 
}); 

ポップアップメニューが表示されているときにテキストフィールドのフォーカスを要求する方法は、フォーカスを要求してウィンドウにフォーカスがないテキストフィールドで実現されます。 :

menu = new JPopupMenu() { 
    @Override 
    public void setVisible(boolean visible) { 
     super.setVisible(visible); 
     if (visible) { 
      getField().requestFocus(); 
     } 
    } 
}; 

そして最後にテキストフィールドがポップアップメニュー退け方法:

field.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     getMenu().setVisible(false); 
    } 
}); 
1

これを行うには、getComponentPopupMenuをオーバーライドしてJPopupMenuを返す必要があります。これはあなたが望むように正確に処理する必要があります。フォーカスなどを許可します。

EDIT:これは継承の方がはるかに優れていますが、厳密には必要ありません。

Public JPopupMenu getComponentPopupMenu() { 
    return getMenu(); 
} 

ああ、あなたはそれが、任意のマウスクリックで表示ポップアップメニューの上にマウスリスナー、およびコール・ショーを追加したい場合:任意のマウスクリックでそれを表示します

public void processMouseEvent(MouseEvent e) { 
    popup.show(this, e.getX(), e.getY()); 
} 

を。

か、別のオプションあなたは(processMouseEventを呼び出す)マウスリスナーを持っていて、唯一の右クリックで呼び出したい場合は次のとおりです。

public void processMouseEvent(MouseEvent e) { 
    if (e.isPopupTrigger()) { 
     popup.show(this, e.getX(), e.getY()); 
    } 
} 

マウスリスナーは、次のようになります。

panel.addMouseListener(new MouseAdapter() { 
    mouseClicked(MouseEvent e) { 
     processMouseEvent(e); 
    } 
} 
+0

私は私の質問を更新しますが、私がしたのは、setVisibleを変更して表示し、フォーカスが自動的にテキストフィールドに移動しないことを除いて動作します。 これはもはやtho ...感謝を隠すことはありません。 – Victor

+0

右の場合、getPopupMenuを使用するか、popup.show(...)を実行すると、フォーカスはSwingによって処理され、その動作は無料で取得されます。 – aperkins

+0

これをもっと明確にするためにいくつかの要素を追加しました。マウスリスナーはmouseEventメソッドを呼び出します。ここでも、popup.showを使用すると、基になるフレームワークがフォーカスを処理します。 – aperkins

0

あなたがポップアップを表示すると、それはフォーカスを持っているはずです(それはおそらくそれをつかむでしょう)。

これはおそらく、これは メニューが表示され、フォーカスを取得することです。

次のコマンドでは、フォーカスをテキストフィールドにトラバースします。ポップアップにはフォーカスがないので、フォーカスのないポップアップは役に立たないので、再び隠れる。

+0

実際に意味をなさないのは、私がfield.requestFocusInWindow()を持っていても、自分のコードにmenu.setVisible(false)があるときだけ隠れるからです。 – Victor

1

を私は自動的に表示するのMouseListenerを追加setComponentPopupMenu()提案した方法の使用を通じて発見してることを指摘したいと思います指定されたPopupMenuは、右クリックイベントを消費します。
if(e.isPopupTrigger())構造内にあるものは、イベントが消費されるため右クリックでは決して実行されません。

本質的に私の質問で指定された動作はpanel.setComponentPopupMenu(getMenu())を追加するだけですが、mouseClickedだけでなく、すべての右クリックイベントを消費しているという事実は非常に制限されています。

関連する問題