2012-04-20 35 views
2

MVCアーキテクチャパターンを使用して簡単なJava Swingアプリケーションを構築しようとしています。私が行ったことは、自分のビューにユーザーインターフェイスコンポーネントを(プライベートとして)作成し、コンポーネントを返すパブリックメソッドを持つことです。これらのメソッドはコントローラによって呼び出され、イベント/アクションリスナのメソッドを記述することができます。以下のサンプル例です。Java Swing FocusListenerのMVC実装

ビュー:

private JButton btnAdd; 

    public JButton getBtnAdd(){ 
     return btnAdd; 
    } 

コントロール:

myGuiFrame gui = new myGuiFrame(); 


     //on add button clicked 
    gui.getBtnAdd().addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      //calls to model 
     } 
    }); 

は、この実装は正しいですか?

もしそうなら、私はFocusListenersに問題があります。私のビューでFocusListenerを作成すると、focusLostメソッドとfocusGainedメソッドがビュー内に作成されます。

private FocusListener l; 

someComponent.addFocusListener(l); 

     l = new FocusListener() { 

      @Override 
      public void focusLost(FocusEvent e) { 
       // TODO Auto-generated method stub 
      } 

      @Override 
      public void focusGained(FocusEvent e) { 
       // TODO Auto-generated method stub 

      } 
     }; 

すべてのイベントハンドラを私のコントローラに入れたいです。私の質問は...私は/私のコントローラからfocusLostとfocusGainedメソッドを呼び出す/宣言することができる方法はありますか?私は私のコントローラでそれを定義することができるように、パブリックとしてのFocusListenerを定義しようとした:

ビュー:

public FocusListener l; 
public someComponentType someComponent; 

コントローラ:

gui.l = new FocusListener() { 
    @Override 
    public void focusLost(FocusEvent e) { 
     // TODO Auto-generated method stub 

} 

@Override 
public void focusGained(FocusEvent e) { 
    // TODO Auto-generated method stub 
    gui.someComponent.addFocusListener(gui.l); 

    } 

}。

ただし、これは機能しません。

コントローラからFocusEventsを処理することはできますか?

編集:

おっと、私の悪い。ロビンが何をしているのか全く分かりませんでした。 FocusListenerを明示的にどこかに定義させすぎてしまった。シンプル:

gui.getTextFieldEmployeeCode().addFocusListener(new FocusListener() { 

     @Override 
     public void focusLost(FocusEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void focusGained(FocusEvent e) { 
      // TODO Auto-generated method stub 
      System.out.println("YES!!!"); 
     } 
    }); 

コントローラでは、Iかかわらず、非常にどのように素敵な牛逝ってしまったそれについてのように、私はそれを行うために計画的にうまく動作します。好奇心の念から、スイングアプリケーションにMVCを実装する標準的な、あるいは広く受け入れられている方法がありますか?

+2

[sscce](http://www.sscce.org)を追加してください。 – user1329572

+1

AFAIK、 'button.addActionListener(...);'は、ControllerではなくViewの一部です。この関数の引数として渡したものは、 'button.addActionListener(new ButtonController())のようなコントローラクラスです。 ; '、' FocusListener'を実装する 'ButtonController'クラスの中に、これら2つのメソッド' focusGained(...)/ focusLost(...)があります) ' –

+0

あなたの' ActionListener'と 'FocusListener'の違いはわかりません。使用可能なゲッターを使用して、コントローラーに 'ActionListener'を作成して追加します。 FocusListenerに同じアプローチを使用してみませんか? – Robin

答えて

5

あなたが理解している限り、これはあなたのやり方です。より良いことに、私は匿名クラスを好む、彼らはカプセル化の概念を尊重する。ここでは、これを把握することができるか見て、このコードに手を試してみてください。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class View 
{ 
    private JButton focusButton; 
    private JButton spareButton; 

    private void createAndDisplayGUI() 
    { 
     JFrame frame = new JFrame("VIEW"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); 

     focusButton = new JButton("GAINED/LOST"); 
     focusButton.addFocusListener(new ButtonController(this)); 

     spareButton = new JButton("SPARE"); 
     spareButton.setOpaque(true); 
     spareButton.addActionListener(new ButtonController(this)); 
     spareButton.addFocusListener(new ButtonController(this)); 

     contentPane.add(focusButton); 
     contentPane.add(spareButton); 

     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public JButton getFocusButton() 
    { 
     return focusButton; 
    } 

    public JButton getSpareButton() 
    { 
     return spareButton; 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new View().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

class ButtonController implements FocusListener, ActionListener 
{ 
    private View view; 
    private JButton focusButton; 
    private JButton spareButton; 

    public ButtonController(View v) 
    { 
     view = v; 
     focusButton = view.getFocusButton(); 
     spareButton = view.getSpareButton(); 
    } 

    public void actionPerformed(ActionEvent ae) 
    { 
     JButton button = (JButton) ae.getSource(); 

     if (button == spareButton) 
     { 
      spareButton.setBackground(Color.BLUE); 
      focusButton.setEnabled(true); 
     } 
    } 

    public void focusGained(FocusEvent fe) 
    { 
     JButton button = (JButton) fe.getSource(); 

     if (button == focusButton) 
     { 
      focusButton.setEnabled(true); 
     } 
     else if (button == spareButton) 
     { 
      spareButton.setBackground(Color.WHITE); 
     } 
    } 

    public void focusLost(FocusEvent fe) 
    { 
     JButton button = (JButton) fe.getSource(); 

     if (button == focusButton) 
     { 
      focusButton.setEnabled(false); 
     } 
     else if (button == spareButton) 
     { 
      spareButton.setBackground(Color.DARK_GRAY.darker()); 
     } 
    } 
} 

別のアプローチ、あなたがgetters/settersによってイライラや周りの参照を送る感じる場合は、次のように(のための簡単な回避策を1つの内部クラスを定義することです前の例):

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class View 
{ 
    private JButton focusButton; 
    private JButton spareButton; 

    private void createAndDisplayGUI() 
    { 
     JFrame frame = new JFrame("VIEW"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); 

     focusButton = new JButton("GAINED/LOST"); 
     focusButton.addFocusListener(new ButtonController()); 

     spareButton = new JButton("SPARE"); 
     spareButton.setOpaque(true); 
     spareButton.addActionListener(new ButtonController()); 
     spareButton.addFocusListener(new ButtonController()); 

     contentPane.add(focusButton); 
     contentPane.add(spareButton); 

     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private class ButtonController implements FocusListener, ActionListener 
    { 

     public void actionPerformed(ActionEvent ae) 
     { 
      JButton button = (JButton) ae.getSource(); 

      if (button == spareButton) 
      { 
       spareButton.setBackground(Color.BLUE); 
       focusButton.setEnabled(true); 
      } 
     } 

     public void focusGained(FocusEvent fe) 
     { 
      JButton button = (JButton) fe.getSource(); 

      if (button == focusButton) 
       focusButton.setEnabled(true); 
      else if (button == spareButton) 
       spareButton.setBackground(Color.WHITE); 
     } 

     public void focusLost(FocusEvent fe) 
     { 
      JButton button = (JButton) fe.getSource(); 

      if (button == focusButton) 
       focusButton.setEnabled(false); 
      else if (button == spareButton) 
       spareButton.setBackground(Color.DARK_GRAY.darker()); 
     } 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new View().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 
+0

まだそれを通過し、テストします。まあ、速かった。どうもありがとう!もちろん、私はWindowBuilder(Eclipseプラグイン)を使用してGUIを構築しています。私が交渉した以上のものを複雑にするかもしれない。 – greatkalu

+0

@ user1295681:あなたは大歓迎であり、スマートにしています:-) –

+0

@ nIcE cOw:既存のコードを修正するために私が行ったことを編集した質問を参照してください。もう一度ありがとうございます:) – greatkalu

関連する問題