1

長い間潜んでいた私の最初の投稿。カーンアカデミーが合計、減算などの無限モードを削除したため、計算スキルを訓練するためのJavaプログラムを作成しようとしています.

どうにかしてスケルトンを作成できましたが、リスナーを実装する必要があるときに行き詰まりました。ActionListener を実装するクラスを作成すると、すべてが機能します。しかし、ActionListener を実装するサブクラスを使用しようとすると、コードが壊れます。 理由を知りたいです。

私は3つのクラスを持っています。

  1. 質問: 2 つのランダムな int を生成します

    public class Question {
    public int rand1;
    public int rand2;
        public Question (){
        rand1 = (int) (100 +(Math.random()*900)); // to be sure I have at least 3 digits. See AnswerV2.generate()
        rand2 = (int) (100 + (Math.random()*900));
        }
    

    }

  2. Answersv2: 質問から 2 つのランダムな int を取得し、それらを合計し、数字を切り替えて 3 つの異なる回答を作成し、正しい回答を追加してそれらをシャッフルします。

    import java.util.ArrayList; import javax.swing.JButton; java.util.Collections をインポートします。

    public class Answersv2 { public ArrayList Answer_list = new ArrayList(); public int int1; public int int2; 文字列 uno;

    public Answersv2 (int a, int b) {
        int1 = a;
        int2 = b;
    }
    public void generate (){
        StringBuilder due = new StringBuilder();
        StringBuilder tre = new StringBuilder();
        StringBuilder quattro = new StringBuilder();
    
        uno = Integer.toString(int1+int2); // create the string version of int1+int2
        ArrayList <Character> first_answer = new ArrayList<Character>(); // create an arraylist of char to store the chars
        for (char c : uno.toCharArray()) {
        first_answer.add(c); 
        }
    
        Collections.swap(first_answer,first_answer.size()-2,first_answer.size()-1); // switch tens with units
        for (char c : first_answer) {
            due.append(c);
        }
        String dueString = due.toString();
    
        Collections.swap(first_answer,first_answer.size()-3,first_answer.size()-2); // switchs hundres with tens
        for (char c : first_answer) {
            tre.append(c);
        }
        String treString = tre.toString();
    
        Collections.swap(first_answer,first_answer.size()-2,first_answer.size()-1); // switch tens with units
        for (char c : first_answer) {
            quattro.append(c);
        }
        String quattroString = quattro.toString();
    
        add(uno,dueString,treString,quattroString);
    }
    public void add (String one,String two,String three,String four){
        Answer_list.add(one);
        Answer_list.add(two);
        Answer_list.add(three);
        Answer_list.add(four);
        shuffle();
    }
    public void shuffle() {
        Collections.shuffle(Answer_list);
    
    }
    
    public void stampa (){ // command code line version to test the program, ignore this
    System.out.println("--------------------------------");
    System.out.println(int1 + " + " + int2 + " = : ");
    System.out.println("A " + Answer_list.get(0));
    System.out.println("B " + Answer_list.get(1));
    System.out.println("C " + Answer_list.get(2));
    System.out.println("D " + Answer_list.get(3));
    }
    public class CoolButton extends JButton{
        public CoolButton(String answer) {
        setText(answer);
        }
        public boolean checkme() { // method to check if the button pressed was the one with the right answer. I still haven't implemented this properly, ignore this too
        if (getText() == uno) {
        return true;
        } else {
        return false;
        }
    }
    }
    }
    

    3 QuizV2: GUI を作成し、プログラムを起動します。

さて... QuizV2 のメインで作成された回答オブジェクトから 4 つの回答を読み取ることができるボタンを作成し、それを使用して setText() やラベル テキストなどを変更できるようにするために、QuizV2 の StartListener サブクラスを作成しました。

サブクラスを含むコード (Quizv2) は次のとおりです。

import java.util.ArrayList;
import java.util.Collections;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;


public class Quizv2{
    public MyLabel label = new MyLabel("Click Start");
    JButton button = new JButton("Start");
    Answersv2 pinolo;
    Question domanda;
    Answersv2.CoolButton button1;
    Answersv2.CoolButton button2;
    Answersv2.CoolButton button3;
    Answersv2.CoolButton button4;

public static void main (String [] args) {
    Quizv2 quiz = new Quizv2();
    quiz.go();  
}
    public void go () {
    Question domanda = new Question();
    Answersv2 pinolo = new Answersv2(domanda.rand1,domanda.rand2);
    pinolo.generate();


    button1 = pinolo.new CoolButton(pinolo.Answer_list.get(0));
    button1.setAlignmentX(Component.CENTER_ALIGNMENT);
    button2 = pinolo.new CoolButton(pinolo.Answer_list.get(1));
    button2.setAlignmentX(Component.CENTER_ALIGNMENT);
    button3 = pinolo.new CoolButton(pinolo.Answer_list.get(2));
    button3.setAlignmentX(Component.CENTER_ALIGNMENT);
    button4 = pinolo.new CoolButton(pinolo.Answer_list.get(3));
    button4.setAlignmentX(Component.CENTER_ALIGNMENT);

    JFrame frame = new JFrame("SPI trainer - Sum");
    JPanel panel = new JPanel();


    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    int R = (int) (Math.random( )*256);
    int G = (int)(Math.random( )*256);
    int B= (int)(Math.random( )*256);
    Color randomColor = new Color(R, G, B);
    label.setForeground(randomColor);
    panel.add(label);


    button.setAlignmentX(Component.CENTER_ALIGNMENT);
    panel.add(button);
    ActionListener doGreeting = new StartListener();
    button.addActionListener(doGreeting );

    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    panel.add(button1);
    panel.add(button2);
    panel.add(button3);
    panel.add(button4);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER,panel);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER,panel);
    frame.setSize(300,300);
    frame.setVisible(true);
    frame.setLocationRelativeTo( null );

    }
    }
    class StartListener extends Quizv2 implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("boo");

            label.setLabelText("The button text changed.");

            }

        }

ただし、「ブー」と出力されるため、何か間違っているようですが、ラベルのテキストは変更されません。使用は避けたい

class StartListener extends Quizv2 implements ActionListener {
        public void actionPerformed(ActionEvent e) {
                        if (buttony == e.getSource()) {
                           label.setLabelText( domanda.rand1 + " + " + domanda.rand2 + " = : ????");
                       button1.setVisible(true);
                       button2.setVisible(true);
                       button3.setVisible(true);
                       button4.setVisible(true);
                       button.setVisible(false);
                            .....
                            .....
                        else if (buttonx == e.getSource())
                        ....

            }

        }

どのボタンが押されたかを把握して、プログラムがどのコードブロックを実行するかを知るためです。その後、サブクラスを使用しないようにしましたが、すべてうまくいきました。これがコードです(Quizv2)

import java.util.ArrayList;
import java.util.Collections;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;


public class Quizv2 implements ActionListener{
    public MyLabel label = new MyLabel("Click Start");
    JButton button = new JButton("Start");
    Answersv2 pinolo;
    Question domanda;
    Answersv2.CoolButton button1;
    Answersv2.CoolButton button2;
    Answersv2.CoolButton button3;
    Answersv2.CoolButton button4;

public static void main (String [] args) {
    Quizv2 quiz = new Quizv2();
    quiz.go();  
}
    public void go () {
    domanda = new Question();
    pinolo = new Answersv2(domanda.rand1,domanda.rand2);
    pinolo.generate();

    button1 = pinolo.new CoolButton(pinolo.Answer_list.get(0));
    button1.setAlignmentX(Component.CENTER_ALIGNMENT);
    button2 = pinolo.new CoolButton(pinolo.Answer_list.get(1));
    button2.setAlignmentX(Component.CENTER_ALIGNMENT);
    button3 = pinolo.new CoolButton(pinolo.Answer_list.get(2));
    button3.setAlignmentX(Component.CENTER_ALIGNMENT);
    button4 = pinolo.new CoolButton(pinolo.Answer_list.get(3));
    button4.setAlignmentX(Component.CENTER_ALIGNMENT);

    JFrame frame = new JFrame("SPI trainer - Sum");
    JPanel panel = new JPanel();


    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    int R = (int) (Math.random( )*256);
    int G = (int)(Math.random( )*256);
    int B= (int)(Math.random( )*256);
    Color randomColor = new Color(R, G, B);
    label.setForeground(randomColor); // Little bit of color
    panel.add(label);


    button.setAlignmentX(Component.CENTER_ALIGNMENT);
    panel.add(button);
    button.addActionListener(this);

    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    panel.add(button1);
    button1.setVisible(false);
    panel.add(button2);
    button2.setVisible(false);
    panel.add(button3);
    button3.setVisible(false);
    panel.add(button4);
    button4.setVisible(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER,panel);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(BorderLayout.CENTER,panel);
    frame.setSize(300,300);
    frame.setVisible(true);
    frame.setLocationRelativeTo( null );

    }
public void actionPerformed(ActionEvent e) {
        label.setLabelText( domanda.rand1 + " + " + domanda.rand2 + " = : ????");
        button1.setVisible(true);
        button2.setVisible(true);
        button3.setVisible(true);
        button4.setVisible(true);
        button.setVisible(false);
    }
    }
4

1 に答える 1

3

1) このプログラムをしばらく脇に置くことをお勧めします。あなたは多くの基本的なエラーを犯しているので、コンパイルするものをどうやって手に入れたのかわかりません。そして、あなたのコードは迷路のようです。これは、プログラムが現時点であなたの能力に対して複雑すぎることを示しています。

2) あなたの投稿は、デバッグ スキルを向上させる必要があることも示しています。質問するときは、約 20 行を超えるコードを投稿しないでください。問題を約 20 行のコードに減らすことは、デバッグ スキルを向上させる練習になります。投稿したコードの 90% は、問題とは無関係です。たとえば、Answerv2 クラス全体を次のように縮小できます。

public class Answersv2 { 
    public ArrayList<String> Answer_list = new ArrayList<String>(); 

    public Answersv2 () {
        Answer_list.add("300", "150", "160", "170");
    }
}

コードがこれらの文字列を計算する方法が、ボタンをクリックしてもラベルのテキストを変更できない理由に関連していると本当に思いますか? 実際、Answerv2 クラス全体は無関係です。

プログラムに含めることができるコードの行数は、デバッグ スキルに比例します。Java を学習してから 2 日後に 500 行のプログラムを作成することはできません。また、Swing プログラムを作成すると多くの可動部分が追加されるため、静的メソッド内の非静的変数にアクセスしようとしないなど、Swing を試す前に基本をしっかりと把握する必要があります。

継承の問題など、一部のコードで問題が発生した場合は、新しいプログラムを開始して実験してください。新しいプログラムをできるだけ単純にします。

1)関連するswingコンポーネントをセットアップする基本的なSwingプログラムを作成します...

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

class MyGui {
    protected JLabel label = new JLabel("Hello");
    protected JButton button = new JButton("Click me");

    public MyGui() {
        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(300, 100, 500, 300);

        JPanel panel = new JPanel();
        panel.add(label);
        panel.add(button);

        Container cpane = frame.getContentPane();
        cpane.add(panel);

        frame.setVisible(true);
    }

}

public class SwingProg {
    private static void createAndShowGUI() {
        new MyGui();
    }

    public static void main(String[] args) {
         javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    } }

2) 同じクラスで動作する actionPerformed() メソッドを取得します。

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

class MyGui implements ActionListener {  //********
    protected JLabel label = new JLabel("Hello");
    protected JButton button = new JButton("Click me");

    public MyGui() {
        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(300, 100, 500, 300);


        JPanel panel = new JPanel();
        panel.add(label);
        button.addActionListener(this);  //**********
        panel.add(button);

        Container cpane = frame.getContentPane();
        cpane.add(panel);

        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {   //**************
        System.out.println("boo");
        label.setText("The button was clicked!");
    }

}

public class SwingProg {
    private static void createAndShowGUI() {
        new MyGui();
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

3) MyGui から継承して、actionPerformed メソッドを子クラスに入れてみます。さて、それを機能させる方法を理解することはできません。少なくとも、投稿する簡単な例があります。

ボタンの問題は、サブクラスの actionPerformed() メソッドがボタンのリスナーになるように指定していないことです。問題の解決策は次のとおりです。

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

class MyGui {
    protected JLabel label = new JLabel("Hello");
    protected JButton button = new JButton("Click me");

    public MyGui() {
        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(300, 100, 500, 300);

        JPanel panel = new JPanel();
        panel.add(label);
        panel.add(button);

        Container cpane = frame.getContentPane();
        cpane.add(panel);

        frame.setVisible(true);
    }
}


class StartListener extends MyGui implements ActionListener {
    public StartListener(){
        super();
        button.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("boo");
        label.setText("The button text changed.");
    }
}

public class SwingProg {
    private static void createAndShowGUI() {
        new StartListener();
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

複雑なプログラムの途中で問題を解決しようとしないでください。代わりに、問題を新しいプログラムに外挿し、新しいプログラムで問題を解決してください。

于 2013-06-30T07:05:59.397 に答える