Java - это использование класса для редактирования метки, плохая практика? - PullRequest
1 голос
/ 18 февраля 2012

Я создаю гораздо более крупную программу, и я попробовал несколько методов (все из которых работают), но мне нравится этот метод в настоящее время, хотя я не знаю, представляют ли некоторые его аспекты плохую практику программирования , Код, используемый в этом примере, просто для того, чтобы передать идею, не вставляя весь код.

Этот код (вставленный ниже) создает новый объект 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);
    }

}

ClassEditor:

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

}

Большое спасибо всем, кто может мне помочь, очень признателен. Просто пытаюсь узнать и понять хорошие практики и почему они работают.

Ответы [ 3 ]

4 голосов
/ 18 февраля 2012

Я, вероятно, не стал бы использовать статические методы и переменные, а просто переписал бы их так (я также изменил имена - хорошая практика, чтобы все было названо так, чтобы все знали, что это значит):

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

}

ClassEditor:

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

}
3 голосов
/ 18 февраля 2012

Хотя это работает, у него есть большая проблема, что 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!");
    }
});
1 голос
/ 18 февраля 2012

Оба экземпляра обновили одну и ту же метку, поскольку вы сделали ее статической переменной. Это означает, что любой экземпляр вашего основного класса будет ссылаться на один и тот же объект jlabel. Мне потребовалось много времени, чтобы по-настоящему понять, как работает статика. В моем приложении Swing везде были статические переменные.

...