【问题标题】:Java: How do I pass variables from JButton ActionListener to main class?Java:如何将变量从 JButton ActionListener 传递到主类?
【发布时间】:2013-06-03 11:21:45
【问题描述】:

我正在尝试制作一个程序,该程序在单击按钮时生成一个随机数,然后将输出显示在屏幕上。但是,我不能将保存随机数的变量传递给带有 JLabel 的类,以便它可以在该类中使用。我编写了一个尽可能简单的程序来演示:

import java.awt.BorderLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

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

public class Main{
    public static void main(String[] args){

    JFrame mainFrame = new JFrame("Experiment");
    mainFrame.setSize(500,500);
    mainFrame.setVisible(true);

    Panel panel = new Panel();
    mainFrame.getContentPane().add(panel);

    JLabel output = new JLabel("This is where the result from the num variable in the numGenerator class would go"); 
    panel.add(output); 

    JButton numGenerator = new JButton("Generate Number");
    panel.add(numGenerator);
    numGenerator.addActionListener(new numGenerator());

    }

static class numGenerator implements ActionListener{
    public void ActionPerfomed (ActionEvent e){

        int num; //This is the variable I want to be passed to the
                 //Main class so it can be displayed in the "output" Jlabel.

        Random dice = new Random();
        num = dice.nextInt(3);

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
}
}

我在网上看到了其他帮助来创建类的对象,然后在你希望变量所在的类中使用它,但在这种情况下我无法让它工作。

【问题讨论】:

  • 所有都标记为static,你不会有太多的运气......
  • ActionPerformed 不是 actionPerformed。

标签: java swing


【解决方案1】:

您可以使用多种方法来完成此操作...

你可以...

numGenerator 提供一个类、实例变量以直接访问...

public class Main{
    public static void main(String[] args){
        new Main();
    }

    // This variable will be visible to the inner class numGenerator
    private JLabel output;

    public Main() {
        JFrame mainFrame = new JFrame("Experiment");
        mainFrame.setSize(500,500);
        mainFrame.setVisible(true);

        Panel panel = new Panel();
        mainFrame.getContentPane().add(panel);

        output = new JLabel("This is where the result from the num variable in the numGenerator class would go"); 
        panel.add(output); 

        JButton numGenerator = new JButton("Generate Number");
        panel.add(numGenerator);
        numGenerator.addActionListener(new numGenerator());
    }

    public class numGenerator implements ActionListener{
        public void actionPerformed(ActionEvent e){

            Random dice = new Random();
            int num = dice.nextInt(3);
            output.setText(Integer.toString(num));

        }
    }
}

这将您的操作与您的标签紧密结合在一起,从而降低了代码的可重用性...

你可以...

将要更改的标签的引用传递给numGenerator...

public class Main{
    public static void main(String[] args){
        new Main();
    }

    public Main() {
        JFrame mainFrame = new JFrame("Experiment");
        mainFrame.setSize(500,500);
        mainFrame.setVisible(true);

        Panel panel = new Panel();
        mainFrame.getContentPane().add(panel);

        JLabel output = new JLabel("This is where the result from the num variable in the numGenerator class would go"); 
        panel.add(output); 

        JButton numGenerator = new JButton("Generate Number");
        panel.add(numGenerator);
        numGenerator.addActionListener(new numGenerator(output));
    }

    public class numGenerator implements ActionListener{
        private JLabel label;

        public numGenerator(JLabel label) {
            this.label = label;
        }

        public void actionPerformed(ActionEvent e){

            Random dice = new Random();
            int num = dice.nextInt(3);
            if (label != null) {
                label.setText(Integer.toString(num));
            }

        }
    }
}

这使得numGenerator 更可重用,因为它不依赖于JLabel 的单个实例

你可以...

使用Observer style pattern 可以告诉感兴趣的一方正在生成一个新号码...

public class Main{
    public static void main(String[] args){
        new Main();
    }

    public Main() {
        JFrame mainFrame = new JFrame("Experiment");
        mainFrame.setSize(500,500);
        mainFrame.setVisible(true);

        Panel panel = new Panel();
        mainFrame.getContentPane().add(panel);

        final JLabel output = new JLabel("This is where the result from the num variable in the numGenerator class would go"); 
        panel.add(output); 

        JButton numGenerator = new JButton("Generate Number");
        panel.add(numGenerator);
        numGenerator.addActionListener(new numGenerator(new NumberGeneratorListener() {
            public void numberGenerated(int number) {
                output.setText(Integer.toString(number));
            }
        }));
    }

    public interface NumberGeneratorListener {
        public void numberGenerated(int number);
    }

    public class numGenerator implements ActionListener{
        private NumberGeneratorListener listener;

        public numGenerator(NumberGeneratorListener listener) {
            this.listener = listener;
        }

        public void actionPerformed(ActionEvent e){

            Random dice = new Random();
            int num = dice.nextInt(3);
            if (listener != null) {
                listener.numberGenerated(num);
            }

        }
    }
}

这不仅将numGenerator 与代码的其余部分解耦,因为它不依赖于代码的任何其他部分,它使得它非常可重用,因为它不关心数字的去向或方式使用,这取决于观察者/听众来决定......

旁注...

您可能还想通读一遍...

【讨论】:

  • 感谢帮助,但第一种方法没有更新字符串来表示变量号,第二种方法在主类中出现错误,提示:“嵌套类型 Main 无法隐藏封闭type.",并且第三种方法也没有像第一种方法那样更改 JLabel。你知道是什么原因造成的吗?
  • 主要问题是我复制了您的代码并且没有通过编译器运行它。您错误地命名了 actionPerformed 方法 (ActionPerfomed)。我现在已经通过编译器运行它并更新了示例并对其进行了测试
  • 非常感谢! 3号是一个救生员!你对我这样的菜鸟很有帮助。 :)
  • 所有的菜鸟,只是我们中的一些人有更多的经验;)
【解决方案2】:

首先,如果你想访问 JLabel 必须在 LEVEL CLASS 声明中或在 actionListener 中通过参数传递,导致你的标签引用只存在于主上下文中。

public class Main{
    public static void main(String[] args){

    JFrame mainFrame = new JFrame("Experiment");
    mainFrame.setSize(500,500);
    mainFrame.setVisible(true);

    Panel panel = new Panel();
    mainFrame.getContentPane().add(panel);

    JLabel output = new JLabel("This is where the result from the num variable in the numGenerator class would go"); 
    panel.add(output); 

    JButton numGenerator = new JButton("Generate Number");
    panel.add(numGenerator);
    numGenerator.addActionListener(new NumGenerator(output));

    }

private class NumGenerator implements ActionListener{
    private final JLabel label;

     public NumGenerator(final JLabel label){
         this.label=label;       
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        int num; 
        Random dice = new Random();
        num = dice.nextInt(3);
        label.setText(num); 
    }
}
}

或者你可以做这样的事情

public class Main{
    //if u want to hold all at class level properties but u really only interested in JLabel
 private JFrame mainFrame;
 private JPanel panel;
 private JLabel label;
 private JButton numGenerator;

//add Constructor
public Main(){
  mainFrame = new JFrame("Experiment");
  mainFrame.setSize(500,500);
  mainFrame.setVisible(true);

panel = new JPanel();
mainFrame.getContentPane().add(panel);
output = new JLabel(); 
panel.add(output); 

numGenerator = new JButton("Generate Number");
panel.add(numGenerator);
numGenerator.addActionListener(new NumGenerator(output));

}

public static void main(String[] args){
  /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
             new Main().mainFrame.setVisible(true);
        }
    });


}

private class NumGenerator implements ActionListener{

   @Override
    public void actionPerformed(ActionEvent arg0) {
        int num; 
        Random dice = new Random();
        num = dice.nextInt(3);
        label.setText(num); // now u have access
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2012-02-07
    • 2013-06-30
    • 2023-02-02
    • 2018-09-09
    • 2013-02-25
    • 1970-01-01
    相关资源
    最近更新 更多