繁体   English   中英

Java-我的动作事件无效

[英]Java - My action event doesn't work

我正在学习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布局是邪恶的为什么不赞成在swing中使用null布局? 尽管您没有使用null布局,但解释了为什么不应该手动确定组件的位置。

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

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

  4. 您没有在事件调度线程(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()方法。


说完上述所有内容后,您需要在ActionListener上调用revalidate()repaint() ,以便您的程序绘制其新状态。

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

在此处输入图片说明 在此处输入图片说明

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

我是在JPanel,JButton等其他组件之前编写此代码还是在代码末尾编写此代码?

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

有什么区别 ?

尽管我在建议中回答了这个问题,但不同之处在于,如果在将所有元素添加到框架之前调用setVisible ,则会遇到一些随机问题,在这些问题上,除非您将鼠标移到组件上,否则所有组件都不可见(或应该在哪里)。 frame.pack()setVisible应该是程序中要调用的最后一个,并且frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 可以在开始或结束时使用,但不受影响,但我也希望在结束时使用。

button.setBounds(100,100,130,35); 也行不通。

好吧,这是因为您使用的是布局管理器 (这是执行GUI的正确方法),而不是使用null-layout (无论如何您都不应使用)(请参阅第1点)。


编辑

frame.setSize();有什么区别? 和frame.setpack()?

如果您阅读pack()文档

使此窗口的大小适合其子组件的首选大小和布局。 如果任意一个尺寸小于上一次调用setMinimumSize方法指定的最小尺寸,则窗口的宽度和高度将自动放大。

因此,它将为您的JFrame计算最小尺寸,在该尺寸下所有元素都是可见的且处于其首选尺寸,而setSize仅设置窗口尺寸,但是例如,如果在其中放置JScrollBar ,则会减小窗口尺寸,因为因此,您应该重写容器的getPreferredSize(...)方法,以便它将计算其首选大小,包括JScrollBar的宽度或其他可以修改其大小的元素。 请参阅我应该避免在Swing中使用setPreferred | Maximum | MinimumSize吗? (一般共识

将组件动态添加到面板时,需要重新添加面板。

做这个

panel.revalidate(); 

panel.add(label);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM