Java - 我的 Action 事件不起作用

标签 java swing user-interface jframe

我正在学习 Java 和 Swing,但我的 JButton 不起作用。

import javax.swing.JFrame;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Programma {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }

        catch (Exception e){
            e.printStackTrace();
        }


        JFrame frame = new JFrame("DIG");
        JPanel panel = new JPanel();
        JButton button = new JButton("Click Me");

        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        button.setBounds(100, 100, 130, 35);

        panel.add(button);
        frame.add(panel);

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub

                JLabel label = new JLabel("Hello World");
                label.setVisible(true);
                panel.add(label);

            }
        });

    }
}
  1. 框架和按钮是可见的,当我点击它时,标签不会出现。我该如何解决这个问题?

  2. 我是在其他组件(如 JPanel、JButton 等)之前写这个,还是在代码末尾写这个:

    frame.setVisible(true);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

有什么区别?

顺便说一句,button.setBounds(100, 100, 130, 35) 也不起作用。

最佳答案

我在您的代码中发现了一些问题:

  1. button.setBounds(100, 100, 130, 35); 该行将被忽略,您不应手动确定组件的位置。参见 Null layout is evilWhy is it frowned upon to use a null layout in swing?虽然您没有使用空布局,但解释了为什么您不应该手动确定组件的位置。

  2. 您在 main 方法中运行程序中的所有内容,以后很难维护。

  3. 您在将所有元素添加到其中之前调用 frame.setVisible(true),这会导致随机问题。

  4. 您没有在 Event Dispatch Thread (EDT) 上运行您的程序,您可以通过使用以下代码启动您的程序来解决此问题,该代码将其放置在 EDT 中。建议这样做,因为 Swing 不是线程安全的。

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Your constructor here
            }
        });
    }
    
  5. 您正在使用 setSize(...) 设置 JFrame 的大小,而是调用 frame.pack()并覆盖 JPanelgetPreferredSize() 方法。


说完以上,你需要调用revalidate()repaint()在您的 ActionListener 上,以便您的程序绘制其新状态。

此程序遵循上述所有建议并产生以下输出(单击按钮之前和单击按钮 3 次之后),我故意不让图像太大,使 GUI 更短(200 x 200 而不是 400 x 400)

enter image description here enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Programma {

    private JFrame frame;
    private JPanel panel;
    private JButton button;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Programma().createAndShowGui();
            }
        });
    }

    public void createAndShowGui() {
        frame = new JFrame("DIG");
        panel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 400);
            }
        };
        button = new JButton("Click Me");

        panel.add(button);

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JLabel label = new JLabel("Hello World");
                panel.add(label);

                panel.revalidate();
                panel.repaint();
            }
        });

        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Do i write this before the other componente like JPanel,JButton... or do i write this at the end of code ?

frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

What is the difference ?

虽然我根据建议回答了这个问题,但不同之处在于,如果您在将所有元素添加到框架之前调用 setVisible,那么您会发现自己遇到了一些组件不存在的随机问题直到您将鼠标移到它们上方(或它们应该在的位置)之前,它们都是可见的。 frame.pack()setVisible 应该是程序中最后调用的,frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);可以放在开头也可以放在结尾,不影响,但我更喜欢放在结尾。

button.setBounds(100, 100, 130, 35); doesn't work too.

嗯,那是因为你使用的是 layout manager (这是制作 GUI 的正确方法)而不是 null-layout(无论如何你都不应该使用它)(参见第 1 点)。


编辑

What is the difference between frame.setSize(); and frame.setpack() ?

如果您阅读 docs对于 pack():

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.

因此,它会计算您的 JFrame 的最小尺寸,其中所有元素都可见并且是它们的首选尺寸,而 setSize 只会设置窗口尺寸,但是如果你在其中放置一个 JScrollBar 例如这将减小窗口大小,因此,这就是为什么你应该重写容器的 getPreferredSize(...) 方法,因此它将计算其首选大小,包括 JScrollBar 的宽度或其他一些可以修改其大小的元素。参见 Should I avoid the use of setPreferred|Maximum|MinimumSize in Swing? (普遍的共识是)

关于Java - 我的 Action 事件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42166509/

相关文章:

java - Cordova 构建 Android 错误

java - 内部类中的线程

java - Android:快速按下按钮会导致多个 Intent 实例

user-interface - vim + iterm : how to use mouse for everything EXCEPT selection?

java - JSP调用方法Servlet

java - 为什么这个程序用 Java 7 而不是 Java 8 编译?

java - system.out.println 必须在 edt 上吗?

java - 为什么我的 UI 元素在执行 Paint(); 后消失了?

java - 嵌入时监听 JOptionPane 事件?

java Swing 。如何等待其他 Jframes