2012-04-20 3 views
2

MVC 아키텍처 패턴을 사용하여 간단한 Java Swing 응용 프로그램을 작성하려고합니다. 내가 한 일은 내 뷰에서 사용자 인터페이스 구성 요소를 (비공개로) 생성하고 구성 요소를 반환하는 public 메서드를 사용하는 것입니다. 이 메소드들은 컨트롤러에 의해 호출되며,이를 통해 이벤트/액션 리스너를위한 메소드를 작성할 수 있습니다. 다음은 샘플 예제입니다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 

      } 
     }; 

내 컨트롤러에 모든 이벤트 처리기를 넣기를 원합니다. 내 질문은 ... 내가 호출 할 수/포커스를 선언 할 수있는 방법이 있습니까? 내 컨트롤러에서 Lost 및 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!!!"); 
     } 
    }); 

컨트롤러에서 내가 비록 아주 좋은 방법 소 사라 그것에 대해처럼, 나는 그것을 할 계획 방식으로 잘 작동합니다. 호기심에서, 스윙 앱에 MVC를 구현하는 표준 또는 널리 받아 들여지는 방식이 있습니까?

+2

[sscce] (http://www.sscce.org)를 포함하여 더 빨리 도움을 받으십시오. – user1329572

+1

AFAIK,'button.addActionListener (...);'는 Controller가 아닌 View의 일부이며, 이제는 그 함수에 인수로 전달한 내용이'button.addActionListener (new ButtonController())와 같은 컨트롤러 클래스입니다. ;','FocusListener'를 구현 한'ButtonController' 클래스 안에는이 두 메소드'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에 의해 자극을 느끼고 주변에 대한 참조를 보내는, (간단한 해결 방법은 다음과 같이 하나 개의 내부 클래스를 정의하는 경우 이전 예 :

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