2016-07-24 3 views
0

이 코드는 퀴즈 게임을위한 간단한 엔진입니다. 아이디어는 답변이 JButton에 표시된다는 것입니다. 이렇게하려면 모든 것을 삭제하고 다시 칠하는 새로 고침 메서드를 설치해야했습니다. 이 메서드가 호출 될 때마다 점점 느려지는 것 같습니다. 약 10 번의 버튼 클릭 후에 응답이 느려지고 프로그램을 수동으로 종료해야하므로 속도가 느려집니다.단추를 여러 번 클릭하면 작은 스윙 응용 프로그램이 충돌 함

감사

package mainPackage; 

import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

public class MainGame{ 
    static JFrame frame; 
    static WindowComp w; 

    public static void main(String[] args) { 
     frame = new JFrame("Game"); 
     w = new WindowComp(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(300, 300); 
     frame.setVisible(true); 
     frame.setResizable(true); 

     WindowComp.setAnswers("start", "start", "start", "start"); 
     WindowComp.refreshAll(w, frame); 

     WindowComp.setAnswers("final", "final", "final", "final"); 
     WindowComp.refreshAll(w, frame); 
    } 
} 

public class WindowComp extends JComponent implements ActionListener { 
    static JButton [] buttons = new JButton[4]; 
    static JLabel question = new JLabel("default"); 

    public WindowComp(){ 
     setAnswers("default", "default", "default", "default"); 
    } 

    public void paintComponent(Graphics g){ 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == buttons[0]){ 
      setQuestion("button 1"); 
     } 
     if(e.getSource() == buttons[1]){ 
      setQuestion("button 2"); 
     } 
     if(e.getSource() == buttons[2]){ 
      setQuestion("button 3"); 
     } 
     if(e.getSource() == buttons[3]){ 
      setQuestion("button 4"); 
     } 
     refreshAll(MainGame.w, MainGame.frame); 
    } 

    public void addAll(){ 
     setLayout(new FlowLayout()); 
     buttons[0].addActionListener(this); 
     buttons[1].addActionListener(this); 
     buttons[2].addActionListener(this); 
     buttons[3].addActionListener(this); 
     add(buttons[0]); 
     add(buttons[1]); 
     add(buttons[2]); 
     add(buttons[3]); 
     add(question); 
    } 

    public static void setAnswers(String ans1, String ans2, String ans3,String ans4){ 
     buttons[0] = new JButton("Answer 1 : " + ans1); 
     buttons[1] = new JButton("Answer 2 : " + ans2); 
     buttons[2] = new JButton("Answer 3 : " + ans3); 
     buttons[3] = new JButton("Answer 4 : " + ans4); 
    } 

    public static void setQuestion(String q){ 
     question = new JLabel("Question: " + q); 
    } 

    public static void refreshAll(WindowComp w, JFrame frame){ 
     w.removeAll(); 
     w.addAll(); 
     w.revalidate(); 
     frame.add(w); 
    } 
} 
+1

[카드 레이아웃] (http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)을 사용하지 않는 이유는 제거 할 필요가 없기 때문입니다. -> 추가 -> 자신의 재확인. 시도해보십시오 – Frakcool

+0

@krzyk (당신이 이것을 볼 수 있기를 바랍니다) : 이것은 올바른 대답이었을 것입니다. 여기서 최소한 언급 할 가치가 있습니다 :'refreshAll'를 호출 할 때마다 액션 리스너를 버튼에 추가 할 수 있습니다. 몇 번의 클릭 후 버튼에는 수십 개의 액션 리스너가 있습니다. Ths는 약간 물건을 망칠 수 있습니다. 그럼에도 불구하고 전반적인 접근 방식이 최선이 아니므로 고려해야합니다. Frakcool이 제안한대로'CardLayout'을 제안했습니다. – Marco13

+0

청취자의 수가 기하 급수적으로 증가합니다. 방금 해봤 어. – mszymborski

답변

1

좋아요, 주석에 설명 된대로 너무 많은 ActionListeners를 추가하면 설명 된 문제가 발생합니다.

다음은 몇 가지 조언을 제공해 드리겠습니다.

우선, 버튼 텍스트를 변경할 때마다 new 키워드를 사용할 필요가 없습니다. 가비지 수집은 사용되지 않는 버튼을 제거하지만, 가비지 수집을 호출하지 않는 setTest(String)을 통해 버튼의 텍스트를 업데이트하는 대신 새로운 버튼을 원하는 이유는 무엇입니까?

마지막으로 생성자를 더 많이 사용하려고하면 생성자를 호출 할 때 실제로 필요한 모든 작업을 수행 할 수 있습니다.이 경우에는 일반적으로 사용하지 않습니다. 예를 들어, 생성자에서 모든 JButton을 생성하고 버튼에 모든 리스너를 추가 할 수 있습니다 (아래에서 몇 가지 코드를 제공 할 것입니다).

약간의 코드를 다시 작성했지만, 사용자의 코드와 기능이 동일하지 않지만 충돌하지는 않습니다.

package de; 

import javax.swing.JFrame; 

public class MainGame{ 
static JFrame frame; 
static WindowComp w; 
public static void main(String[] args) { 
    frame = new JFrame("Game"); 
    w = new WindowComp(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(300, 300); 
    frame.add(w); 
    frame.setVisible(true); 
    frame.setResizable(true); 
    /*WindowComp.setAnswers("start", "start", "start", "start"); 
    WindowComp.refreshAll(w, frame); 

    WindowComp.setAnswers("final", "final", "final", "final"); 
    WindowComp.refreshAll(w, frame);*/ 
} 

} 




package de; 

import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

@SuppressWarnings("serial") 
public class WindowComp extends JComponent implements ActionListener { 

static JButton [] buttons; 
static JLabel question; 

public WindowComp(){ 
    question = new JLabel("default"); 
    buttons = new JButton[4]; 
    setLayout(new FlowLayout()); 
    buttons[0] = new JButton("Answer 1 : " + "default"); 
    buttons[1] = new JButton("Answer 2 : " + "default"); 
    buttons[2] = new JButton("Answer 3 : " + "default"); 
    buttons[3] = new JButton("Answer 4 : " + "default"); 

    buttons[0].addActionListener(this); 
    buttons[1].addActionListener(this); 
    buttons[2].addActionListener(this); 
    buttons[3].addActionListener(this); 
    addAll(); 

} 


@Override 
public void actionPerformed(ActionEvent e) { 
    if(e.getSource() == buttons[0]){ 
     setQuestion("button 1"); 
     setAnswers("start", "start", "start", "start"); 
    } 
    if(e.getSource() == buttons[1]){ 
     setQuestion("button 2"); 
     setAnswers("final", "final", "final", "final"); 
    } 
    if(e.getSource() == buttons[2]){ 
     setQuestion("button 3"); 
    } 
    if(e.getSource() == buttons[3]){ 
     setQuestion("button 4"); 
    } 
    //refreshAll(MainGame.w, MainGame.frame); 

} 
public void addAll(){ 

    add(buttons[0]); 
    add(buttons[1]); 
    add(buttons[2]); 
    add(buttons[3]); 
    add(question); 

} 



public static void setAnswers(String ans1, String ans2, String ans3,String ans4){ 
    buttons[0].setText("Answer 1 : " + ans1); 
    buttons[1].setText("Answer 2 : " + ans2); 
    buttons[2].setText("Answer 3 : " + ans3); 
    buttons[3].setText("Answer 4 : " + ans4); 

} 

public static void setQuestion(String q){ 
    question.setText("Question: " + q); 
} 

public static void refreshAll(WindowComp w, JFrame frame){ 
    w.removeAll(); 
    w.addAll(); 
    w.revalidate(); 
    frame.add(w); 

} 

}

편집 : 지금까지 현재 코드가 간다, 함수 refreshAll(WindowComp w, JFrame frame) 현재를 호출하기위한 필요가 없기 때문에, 더 이상 호출되지 않습니다. 호출없이 프로그램을 테스트 한 후이 편집으로 주석 처리했습니다.

+0

repaint()를 호출해야합니까? 단추 텍스트를 변경하려면? –

+0

테스트 한 결과 repaint()를 호출 할 필요가 없습니다. –

+0

감사합니다! 이것은 위대한 작품. –

0

귀하의 문제는 ActionListener를 항상 버튼에 추가되었지만 제거되지 않습니다 것입니다. ") (refreshAll"

public void removeActionListeners(){ 
     buttons[0].removeActionListener(this); 
     buttons[1].removeActionListener(this); 
     buttons[2].removeActionListener(this); 
     buttons[3].removeActionListener(this); 
} 

을 그리고 다음에 전화 : 빠른 수정을 제거하는 방법을 작성하는 것입니다 지적

이미이 하지
public static void refreshAll(WindowComp w, JFrame frame){ 
     w.removeActionListeners(); 
     w.removeAll(); 
     w.addAll(); 
     w.revalidate(); 
     frame.add(w); 
} 

입니다 ...이 작업을 수행하는 가장 좋은 방법이지만 더 이상 지연되지는 않습니다.

관련 문제