【问题标题】:My Java swing button doesn't work我的 Java swing 按钮不起作用
【发布时间】:2015-02-10 17:36:28
【问题描述】:

我一直在制作一个战舰程序,我一直在尝试使用 GUI,但它不想工作。理论上它应该工作的方式是GUI启动,它将一个问题输出到一个框(有效),然后计算机等待并且不执行任何操作,直到您在回答问题的答案后按下按钮。问题是,我的方法一直等到您单击按钮以获取文本字段中的数据时才执行任何操作。我写了一段类似的代码来演示我的问题。

Test.java(主类)

package taest;
import javax.swing.*;

public class Test {
    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                @SuppressWarnings("unused")
                JFrame frame = new Frame();
            }
        });
        Frame.display.setText(getButtonClick());
        }
    public static String getButtonClick(){
        while(true){
            if (Frame.hasClicked){
                break;
            }
        }
        return Frame.text.getText();
    }
}

Frame.java(框架类) 打包测试;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Frame extends JFrame{
    JFrame panel = new JFrame("Something");
    public static JTextArea text = new JTextArea();
    JButton button = new JButton("Click");
    public static JTextField display = new JTextField("NOthing");
    static boolean hasClicked = false;
    static String storage = "";

    public Frame(){
        setLayout(new BorderLayout());
        setSize(400,400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                hasClicked = true;
                storage = text.getText();
            }

        });

        Container c = getContentPane();
        c.add(display, BorderLayout.CENTER);
        c.add(text, BorderLayout.PAGE_START);
        c.add(button, BorderLayout.PAGE_END);

        setVisible(true);
    }
}

【问题讨论】:

  • static 不是类间通信的机制,在 GUI 环境中尤其无用。
  • 您考虑使用Observer Pattern

标签: java swing user-interface awt jbutton


【解决方案1】:
  • 静态不是你的朋友,它的使用应该受到很大的限制。它绝不应该用于提供对类字段的“轻松”访问以进行类间通信
  • 您需要颠覆这个概念,并可能使用某种Observer Pattern。这是你有一个班级正在“观察”你的另一个班级的变化的地方。当发生变化时,观察类通知观察类该变化。这将责任解耦,因为被观察类不应该只关心通知相关方发生的事情

作为一个非常原始的例子......

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Test {

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

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                @SuppressWarnings("unused")
                JFrame frame = new Frame(new ViewController() {
                    @Override
                    public void messageChanged(View view, String msg) {
                        view.appendLog(msg);
                    }
                });
            }
        });
    }

    public interface ViewController {

        public void messageChanged(View view, String msg);

    }

    public interface View {

        public void appendLog(String log);

    }

    public class Frame extends JFrame implements View {

//      JFrame panel = new JFrame("Something");
        private JTextArea text = new JTextArea(5, 5);
        private JButton button = new JButton("Click");
        private JTextField display = new JTextField("NOthing");
        private String storage = "";

        private ViewController viewController;

        public Frame(ViewController controller) {
            this.viewController = controller;
            setLayout(new BorderLayout());
            setSize(400, 400);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    storage = text.getText();
                    viewController.messageChanged(Frame.this, storage);
                }

            });

            System.out.println("display = " + display.hashCode());
            System.out.println("text = " + text.hashCode());

            Container c = getContentPane();
            c.add(display, BorderLayout.CENTER);
            c.add(text, BorderLayout.PAGE_START);
            c.add(button, BorderLayout.PAGE_END);

            setVisible(true);
        }

        @Override
        public void appendLog(String log) {
            display.setText(log);
        }
    }

}

你也应该在Model–view–controller的概念内成为farmiluar

【讨论】:

    【解决方案2】:

    你把事情搞混了,

    首先,类和对象之间的区别。类是对象的蓝图,因此类的示例是Car。然而,此类对象的蓝图对该类的特定实例的状态一无所知,假设您以 100 km/u 的速度行驶,那么您有一个 Carinstance 来存储它正在以 100 公里/小时的速度行驶。蓝图是类,对象是实例。

    所以,public class Car 为汽车制定了蓝图,new Car() 制定了该蓝图的特定实例,您可以在其中存储运行时信息。

    现在有一种方法可以告诉 Java 事物属于蓝图,静态的。如果变量是静态的,它会附加到蓝图。所以为了跟上汽车的类比,汽车的静态变量可以是它的轴距,这是在编译时定义的(或在创建时在汽车类比中)。

    回到你的问题,你正在混合类和对象,你想要做的是有一个 BattleshipWindow 其中存在实例。在此 BattleshipWindow 中,可以使用new 创建一个实例,然后可以更改其属性。

    可能不是您想要的答案,但我希望您现在了解类和对象之间的区别,这将帮助您解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      • 2012-01-15
      • 2020-12-13
      • 1970-01-01
      • 2016-05-25
      相关资源
      最近更新 更多