2016-07-24 2 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)でボタン上のテキストを更新するだけでなく、新しいボタンが必要なのはなぜですか?

最後に、より多くのコンストラクタを使用しようとすると、実際にコンストラクタを呼び出すときに必要なものすべて(この場合はatleast、一般的には)を作成できます。たとえば、コンストラクタ内のすべての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には、常にボタンに追加しますが削除されることはありませんということです。クイックフィックスは、それらを削除する方法を記述するために、次のようになります。その後、

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

そして、あなたの「refreshAll()」でそれを呼び出す:

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

...すでに指摘したように、これはではありませんこれを行う最善の方法ですが、もはやそれは遅れません。

関連する問題