Java:监听器子类不会更改超类按钮

时间:2013-06-30 03:34:35

标签: java swing listener subclass

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

我以某种方式设法编写了骨架,但是当我必须实现监听器时我陷入困境:如果我创建一个实现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; import java.util.Collections;

    public class Answersv2 {     public ArrayList Answer_list = new ArrayList();     public int int1;     public int int2;     String 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并启动程序。

  3. 现在......我创建了一个QuizV2的StartListener子类,以使按钮能够从QuizV2的main中创建的答案对象中读取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.");
    
                }
    
            }
    

    然而,似乎我做错了,因为它打印'boo',但它不会改变标签文本。我想避免使用

    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);
        }
        }
    

1 个答案:

答案 0 :(得分:2)

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程序,设置相关的摆动组件......

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();
            }
        });
    }
}

不要试图在复杂程序中解决问题。相反,将问题外推到一个新程序中,并解决新程序中的问题。

相关问题