1

我潜伏了很长时间后的第一篇文章。我正在尝试编写一个 java 程序来训练我的计算技能,因为可汗学院取消了求和、减法等永无止境的模式。

我以某种方式设法编写了框架,但是当我必须实现侦听器时我陷入了困境:如果我创建一个实现 ActionListener 的类,一切正常。但是当我尝试使用实现 ActionListener 的子类时,代码会中断。 我想弄清楚为什么。

我有3节课。

  1. 问题:生成2个随机整数

    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:从 Question 中取出 2 个随机整数,对它们求和,创建 3 个不同的答案切换数字,添加正确答案并将它们随机排列。

    导入 java.util.ArrayList;导入 javax.swing.JButton;导入 java.util.Collections;

    公共类 Answersv2 { public ArrayList Answer_list = new ArrayList(); 公共int int1;公共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 的 StartListener 子类,以使按钮能够从 QuizV2 主中创建的答案对象中读取 4 个答案,并将其用于 setText() 并更改标签文本等。

这是带有子类的代码(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两天就写不出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 回答