【问题标题】:Java - Is this use of a class to edit a label bad practice?Java - 这是使用类来编辑标签的坏习惯吗?
【发布时间】:2012-02-18 00:12:14
【问题描述】:

我正在构建一个更大的程序,并且我尝试了几种方法(所有这些方法都有效),但我目前喜欢这种方法,尽管我不知道它的某些方面是否代表糟糕的编程习惯.本例中使用的代码只是为了让大家理解这个想法,而无需粘贴整个代码。

这段代码(粘贴在下面)创建了一个带有标签的新 ClassMain 对象和一个编辑标签的静态方法。 ClassEditor 从 ClassMain 实例化,返回一个按钮。

现在我想知道这是否是不好的做法,我在按钮上有一个操作,当单击该按钮时,会调用 ClassMain 中的静态方法并将标签设置为随机数。我想知道这是否是不好的做法的原因是因为我实际上并没有从 ClassMain 对象的直接实例化中调用该方法,我只是这样做:ClassMain.setLabel("");。而且我不完全确定这叫什么。我有一个 ClassMain 实例化,但如果我有多个,它还能工作吗?那么如何通过这种方式而不是使用引用变量来编辑已创建对象的各个方面呢?如果我有多个课程会产生问题吗?

对不起,如果这些问题是漫无边际的,很难准确地问出来。我提供了下面的代码,所以你可以看到我在说什么。

PS:关于是否会出现多个 ClassMain 对象的问题,我创建了另一个,两个窗口中的两个按钮只更新了一个标签。为什么是这样?这是否意味着如果用于一个实例化不是不好的做法,但如果用于更多则不好?我希望有人可以帮助我解决这些问题!

ClassMain:

import java.awt.GridLayout;

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


public class ClassMain extends JFrame {

    private static JLabel l;

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

    public ClassMain() {
        super("This is my app");
        setSize(450,80);
        setLayout(new GridLayout(0,2));
        l = new JLabel("Hi");

        ClassEditor ce = new ClassEditor();

        add(l);
        add(ce.getButton());

        setVisible(true);
    }

    public static void setLabel(String stringA) {
        l.setText(stringA);
    }

}

类编辑器:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;


public class ClassEditor implements ActionListener {

    public ClassEditor() {
        ClassMain.setLabel("Click the button for a random number!");
    } 

    public JButton getButton() {
        JButton b = new JButton("Click me!");
        b.addActionListener(this);
        return b;
    }

    public void actionPerformed(ActionEvent arg0) {
        int i = (int) (Math.random()*10);
        ClassMain.setLabel("Random Number: "+i);
    }

}

非常感谢任何可以帮助我的人,非常感谢。只是尝试学习和理解好的做法以及它们为什么起作用。

【问题讨论】:

  • 这很好,因为您只有一个标签。相反,您可以考虑只使用 CalssMain.getLabel().setText(text); 之类的东西返回标签本身。

标签: java swing class instantiation


【解决方案1】:

我可能不会使用静态方法和变量,而只是像这样重写它(我还更改了名称 - 一个好的做法是以每个人都知道其含义的方式命名所有内容):

ClassMain:

import java.awt.GridLayout;

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


public class ClassMain extends JFrame {

    private JLabel label;

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

    public ClassMain() {
        super("This is my app");
        setSize(450,80);
        setLayout(new GridLayout(0,2));
        label = new JLabel("Hi");

        ClassEditor classEditor = new ClassEditor(this);

        add(label);
        add(classEditor.getButton());

        setVisible(true);
    }

    public void setLabel(String text) {
        label.setText(text);
    }

}

类编辑器:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;


public class ClassEditor implements ActionListener {

    private ClassMain classMain;

    public ClassEditor(ClassMain classMain) {
        this.classMain = classMain;
        classMain.setLabel("Click the button for a random number!");
    } 

    public JButton getButton() {
        JButton button = new JButton("Click me!");
        button.addActionListener(this);
        return button;
    }

    public void actionPerformed(ActionEvent event) {
        int i = (int) (Math.random()*10);
        classMain.setLabel("Random Number: "+i);
    }

}

【讨论】:

    【解决方案2】:

    虽然这可行,但它的一个大问题是 ClassEditor 与 ClassMain 紧密耦合,即它不能重复用于任何其他目的。

    最好在其构造函数中将 JButton 传递给编辑器类。

    这种松散耦合使您的代码更简单、更容易修改、更容易重用和更容易测试。

    public class ClassEditor implements ActionListener {
    
        JButton button;
    
        public ClassEditor(JButton b) {
            button = b;
            button.setLabel("Click the button for a random number!");
        } 
    
        public void actionPerformed(ActionEvent arg0) {
            int i = (int) (Math.random()*10);
            button.setLabel("Random Number: "+i);
        }
    }
    

    另一种常见的模式是使用匿名监听器:

    final JButton button = new JButton();
    button.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            button.setLabel("Boo!");
        }
    });
    

    【讨论】:

      【解决方案3】:

      两个实例都更新了相同的标签,因为您将其设为静态变量。这意味着您的主类的任何实例都将引用相同的 jlabel 对象。我花了很长时间才真正理解静力学是如何工作的。我的 Swing 应用程序中到处都有静态变量。

      【讨论】:

      • 令人困惑的东西,但很好的解释。所以因为是静态的,所以是指原来的JLabel Object?
      • 是的。它基本上是一个全局变量,这可能是解释它的最佳方式。我在这个概念上挣扎了一段时间。对我来说最好的例子是一个计数器变量。假设您的 ClassMain 中有一个 int 计数器,每次构造函数创建一个新对象时都将其加 1。然后您可以调用 ClassMain.getCounter() 来查找 ClassMain 总共创建了多少个对象。如果变量不是静态的,那么每次你得到 counter 的值时,它只会是 1 而不是全局计数。
      • 这可能是个愚蠢的问题,但是为什么 ClassMain 类的下一个实例化中的下一个 JLabel 不更新,只有第一个?
      • 这根本不是一个愚蠢的问题,它实际上是一个非常好的问题。如果不查看所有代码,很难判断。也许在您的操作执行方法中放置一个 System.out.println() 以确保它像您认为的那样为每个按钮调用该方法。我总是对静态变量存储在内存中的位置以及其他实例如何知道除非它们在同一个 JVM 上区域感到困惑。我理解服务器上的概念,但独立应用程序,如果静态是主类的一部分,我会感到困惑。
      • 那么,从你的角度来看,我的方式是解决这种糟糕的编程习惯吗?
      猜你喜欢
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 1970-01-01
      相关资源
      最近更新 更多