2014-04-18 2 views
1

Java 프로그램에서 여러 액션 리스너를 구현하는 데 문제가 있습니다. 이 프로그램은 기본 GUI로 기본 기능을 수행하는 계산기입니다. 내 연구에서 나는 액션 청취자가 다른 클래스로 가야한다는 것을 알았다. 나는 네 개의 액션 리스너로 구성된 프로그램을 구성했다.하지만 "serializable 클래스 ClearListener가 long 타입의 정적 final serialVersionUID 필드를 선언하지 않는다"는 각 액션 리스너에 대한 경고와 함께 프로그램을 실행할 때마다 계속 끔찍한 오류가 발생한다. 이것에 대한 도움은 크게 감사 할 것입니다.Java에서 Multiple ActionListeners 구현

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 


public class GUICalc extends JPanel { 

    private static final long serialVersionUID = 1L; 

    JButton[] numberButtons; 
    JButton[] upButtons; 

    JTextField field; 
    double num1; 

    double num2; 

    double ans; 
    int op; 

    DigitalListener listener1 = new DigitalListener(); 
    OperatorListener listener2 = new OperatorListener(); 
    ClearListener listerner3 = new ClearListener(); 
    EqualsListener listerner4 = new EqualsListener(); 

    // 0 = gridx 1 gridy 2 gridwidth 3 gridheight 
    private int[][] numConstraints = new int[][] { 
      {0, 4, 1, 1}, 
      {0, 1, 1, 1}, 
      {1, 1, 1, 1}, 
      {2, 1, 1, 1}, 
      {0, 2, 1, 1}, 
      {1, 2, 1, 1}, 
      {2, 2, 1, 1}, 
      {0, 3, 1, 1}, 
      {1, 3, 1, 1}, 
      {2, 3, 1, 1}, 
    }; 

    private int[][] upConstraints = new int[][] { 
      {1, 4, 1, 1}, 
      {3, 4, 1, 1}, 
      {3, 3, 1, 1}, 
      {3, 2, 1, 1}, 
      {3, 1, 1, 1}, 
      {0, 5, 4, 1}, 
      {2, 4, 1, 1}, 
    }; 

    public GUICalc() { 
     setPreferredSize(new Dimension(666, 666)); //width & heigth 

     GridBagLayout layout; // used to be private 
     GridBagConstraints gbc; // used to be private 

     layout = new GridBagLayout(); 
     layout.columnWidths = new int[] {60, 60, 60, 60}; 
     layout.rowHeights = new int[] {60, 60, 60, 60, 60, 60}; 
     setLayout(layout); 

     gbc = new GridBagConstraints(); 

      numberButtons = new JButton[10]; 

      numberButtons[0] = new JButton("0"); 
      numberButtons[1] = new JButton("1"); 
      numberButtons[2] = new JButton("2"); 
      numberButtons[3] = new JButton("3"); 
      numberButtons[4] = new JButton("4"); 
      numberButtons[5] = new JButton("5"); 
      numberButtons[6] = new JButton("6"); 
      numberButtons[7] = new JButton("7"); 
      numberButtons[8] = new JButton("8"); 
      numberButtons[9] = new JButton("9"); 

      for(int i = 0; i < numberButtons.length; i++){ 
       gbc.gridx = numConstraints[i][0]; 
       gbc.gridy = numConstraints[i][1]; 
       gbc.gridwidth = numConstraints[i][2]; 
       gbc.gridheight = numConstraints[1][3]; 
       gbc.fill = GridBagConstraints.BOTH; 
       gbc.insets = new Insets(2, 2, 2, 2); 
       numberButtons[i].addActionListener(listener1); 
       add(numberButtons[i], gbc); 
       } 

     upButtons = new JButton[7]; 

     upButtons[0] = new JButton("."); 
     upButtons[1] = new JButton("/"); 
     upButtons[2] = new JButton("*"); 
     upButtons[3] = new JButton("-"); 
     upButtons[4] = new JButton("+"); 
     upButtons[5] = new JButton("="); 
     upButtons[6] = new JButton("C"); 

      gbc.gridx = upConstraints[0][0]; 
      gbc.gridy = upConstraints[0][1]; 
      gbc.gridwidth = upConstraints[0][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[0].addActionListener(listener2); 
      add(upButtons[0], gbc); 

      gbc.gridx = upConstraints[1][0]; 
      gbc.gridy = upConstraints[1][1]; 
      gbc.gridwidth = upConstraints[1][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[1].addActionListener(listener2); 
      add(upButtons[1], gbc); 

      gbc.gridx = upConstraints[2][0]; 
      gbc.gridy = upConstraints[2][1]; 
      gbc.gridwidth = upConstraints[2][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[2].addActionListener(listener2); 
      add(upButtons[2], gbc); 

      gbc.gridx = upConstraints[3][0]; 
      gbc.gridy = upConstraints[3][1]; 
      gbc.gridwidth = upConstraints[3][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[3].addActionListener(listener2); 
      add(upButtons[3], gbc); 

      gbc.gridx = upConstraints[4][0]; 
      gbc.gridy = upConstraints[4][1]; 
      gbc.gridwidth = upConstraints[4][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[4].addActionListener(listener2); 
      add(upButtons[4], gbc); 

      gbc.gridx = upConstraints[5][0]; 
      gbc.gridy = upConstraints[5][1]; 
      gbc.gridwidth = upConstraints[5][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[5].addActionListener(listerner4); 
      add(upButtons[5], gbc); 

      gbc.gridx = upConstraints[6][0]; 
      gbc.gridy = upConstraints[6][1]; 
      gbc.gridwidth = upConstraints[6][2]; 
      gbc.gridheight = upConstraints[1][3]; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      upButtons[6].addActionListener(listerner3); 
      add(upButtons[6], gbc); 

     field = new JTextField(); 
     field.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
     field.setEditable(false); 
     field.setFont(new Font("Arial",Font.PLAIN, 24)); 
     field.setText(null); 

     gbc.gridx = 0; 
     gbc.gridy = 0; 
     gbc.gridwidth = 4; 
     gbc.gridheight = 1; 

     add(field, gbc); 

    } 


    public static void main(String [] args){ 
     JFrame frame = new JFrame("Calculator"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.setLayout(new BorderLayout()); 
     frame.add(new GUICalc(), BorderLayout.CENTER); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true);  

    } 

} 

class DigitalListener extends GUICalc implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == numberButtons[0]){ 
      field.setText(field.getText() + 0); 
      } 
      if(e.getSource() == numberButtons[1]){ 
      field.setText(field.getText() + 1); 
      } 
      if(e.getSource() == numberButtons[2]){ 
      field.setText(field.getText() + 2); 
      } 
      if(e.getSource() == numberButtons[3]){ 
      field.setText(field.getText() + 3); 
      } 
      if(e.getSource() == numberButtons[4]){ 
      field.setText(field.getText() + 4); 
      } 
      if(e.getSource() == numberButtons[5]){ 
      field.setText(field.getText() + 5); 
      } 
      if(e.getSource() == numberButtons[6]){ 
      field.setText(field.getText() + 6); 
      } 
      if(e.getSource() == numberButtons[7]){ 
      field.setText(field.getText() + 7); 
      } 
      if(e.getSource() == numberButtons[8]){ 
      field.setText(field.getText() + 8); 
      } 
      if(e.getSource() == numberButtons[9]){ 
      field.setText(field.getText() + 9); 
      } 
      if(e.getSource() == upButtons[0] && !field.getText().contains(".")) { 
       field.setText(field.getText() + "."); 
      } 
    } 
} 

class OperatorListener extends GUICalc implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e){ 
     if(e.getSource() == upButtons[1]) { 
      num1 = Integer.parseInt(field.getText()); 
      op = 4; 
      field.setText(""); 
     } 

     if(e.getSource() == upButtons[2]) { 
      num1 = Integer.parseInt(field.getText()); 
      op = 3; 
      field.setText(""); 
     } 
     if(e.getSource() == upButtons[3]) { 
      num1 = Integer.parseInt(field.getText()); 
      op = 2; 
      field.setText(""); 
     } 
     if(e.getSource() == upButtons[4]) { 
      num1 = Integer.parseInt(field.getText()); 
      op = 1; 
      field.setText(""); 
     } 
    } 
} 

class ClearListener extends GUICalc implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == upButtons[6]) { 
      field.setText("0.0"); 
     } 
    } 
} 

class EqualsListener extends GUICalc implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == upButtons[5]) { 
      num2 = Integer.parseInt(field.getText()); 

      if(op == 1){ 
       ans = num1 + num2; 
      } else if(op == 2){ 
       ans = num1 - num2; 

      } else if(op == 3){ 
       ans = num1 * num2; 
      } else if(op == 4){ 
       ans = num1/num2; 
      } 

      op = 0; 
      field.setText("" + ans); 
     } 
    } 
} 
+0

'JButton.setActionCommand (String)'을 사용하여 액션 리스너에게 메시지를 보낸다. actionPerformed에서'if (e.getActionCommand(). equals (String))'를 사용하여 메시지를 확인하십시오. 설정에 따라 추가 및 제거하지 않는 한 많은 actionListener를 사용하지 않는 것이 좋습니다. serialUID 문제는 ClearListener 및/또는 GUICalc를 사용하여 JFrame/스윙 구성 요소를 확장했다고 제안합니다. 필드를 만듭니다. '개인 최종 long serialUID = 1L'. 나는 메모리를 없애기 위해 오타가있을 것이지만 일반적인 과정은 옳다. – Aarowaim

+0

'Serializable 클래스 ClearListener는 long 형의 static final serialVersionUID 필드를 선언하지 않습니다. 이것은 경고가 아니며 오류입니다. – Braj

+0

예, 사과하겠다고 경고하는 텍스트를 변경했습니다. – YellowSoloCup

답변

1

대부분의 아마 당신이 Exception in thread "main" java.lang.StackOverflowError

이 방법으로 수행지고있다 :

class OperatorListener implements ActionListener { 

    private GUICalc guiCalc; 
    public OperatorListener(GUICalc guiCalc){ 
     this.guiCalc=guiCalc; 
    } 
    // use guiCalc to refer the values 
    ... 
} 

GUICalc.java

OperatorListener listener2 = new OperatorListener(this); 

사용자 정의 리스너의 모든 유형을 위해 같은 일을 할.


개체간에 주기적 종속성을 만들었습니다.

GUICalcOperatorListener

public class GUICalc extends JPanel { 
    ... 

    OperatorListener listener2 = new OperatorListener(); 
    ... 

}

OperatorListener 지금 GUICalc 슈퍼 클래스 개체가 종속성을 만들려고 구축하려고 할 때마다 GUICalc 클래스

class OperatorListener extends GUICalc implements ActionListener {...} 

을 확장하고 포함 하위 01과 같은 클래스 객체하지만 이제 하위 클래스 객체는 수퍼 클래스 객체가 생성 될 때까지 생성 될 수 없습니다. 첫 번째 대답은 이미 인정했지만

+0

도움 주셔서 대단히 감사합니다! 어떤 이유로 10 진수 버튼이 작동을 멈췄지만 빠른 픽스가 될 것이라고 확신합니다! – YellowSoloCup

+0

내가 그것을 들여다 보도록 노력합시다. 내가 다시 올게. – Braj

+0

지금 나는 그것을 알아 냈다, 그것은 잘못된 행동 청취자에 있었다. 완전히 나쁘다. – YellowSoloCup

1

는 몇 가지 힌트 :

"액션 청취자가 다른 클래스에 있어야한다"고 권장 올바른 것입니다. 다만, 복수의 ActionListener를 1 개의 클래스에 임의로 조합 할 필요는 없습니다. 가능한 경우도 가능하지만 어떤 경우에는 실현 가능할 수도 있지만 귀하의 경우와 같이 사용 사례에 더 적합한 솔루션이 있습니다.

이렇게하면 코드를 간소화하는 데 도움이 될 수 있습니다. (만약 내가 정리해야한다면 GridBagLayout과이 numConstraints 배열로 시작할 것입니다 - 나는 이것이 끔찍하다고 생각합니다 -하지만 이것은 다른 이야기입니다 ...).

private ActionListener createActionListener(final String string) 
{ 
    return new ActionListener() 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      field.setText(field.getText() + string); 
     } 
    }; 
} 

그런 다음이 청취자의 인스턴스를 생성하고 버튼에 추가 할 수 있습니다 :

for(int i = 0; i < numberButtons.length; i++) 
{ 
    ... 
    numberButtons[i].addActionListener(
     createActionListener(String.valueOf(i))); 
} 

(당신이 수도 그주의 특히,이 같은 익명의 ActionListener를 생성하는 방법을 만들 수 심지어는 numberButtons 배열을 인스턴스 변수로 최상의 경우에 저장할 필요가 없습니다 ...)

유사한 개념을 조작 버튼에 적용 할 수 있습니다.일반적으로, 나는 대략 다음과 같이 하나 개의 버튼에 특정 메서드 호출을 "연결"익명의 청취자를 사용하는 것이 좋습니다로 고려 :

많은 경우를 들어
someButton.addActionListener(new ActionListener() 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     doSomething(); 
    } 
}); 

, 그것은 훨씬 더 도움이 Action을 사용하는 것입니다 (http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html 참조), 이벤트 소스 또는 동작 명령을 검사하는 ActionListener과 달리 개념적으로는 유사합니다.

+0

감사합니다. 필자는 자바 프로그래밍에 익숙하지 않으며 숙련 된 프로그래머들 덕분에 대단히 도움이된다. – YellowSoloCup