Java-我的动作事件无效 [英] Java - My action event doesn't work

查看:56
本文介绍了Java-我的动作事件无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  import javax.swing.JFrame;导入java.awt.event.ActionEvent;导入java.awt.event.ActionListener;导入javax.swing.*;公共课程计划{公共静态void main(String [] args){//TODO自动生成的方法存根尝试 {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}捕获(e例外){e.printStackTrace();}JFrame框架=新的JFrame("DIG");JPanel面板=新的JPanel();JButton按钮=新的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(){公共无效actionPerformed(ActionEvent e){//TODO自动生成的方法存根JLabel标签=新的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); 该行将被忽略,您不应该手动确定组件的位置.请参见

      import java.awt.BorderLayout;导入java.awt.Dimension;导入java.awt.event.ActionEvent;导入java.awt.event.ActionListener;导入javax.swing.BoxLayout;导入javax.swing.JButton;导入javax.swing.JFrame;导入javax.swing.JLabel;导入javax.swing.JPanel;导入javax.swing.SwingUtilities;公共课程计划{私有JFrame框架;专用的JPanel面板;专用JButton按钮;公共静态void main(String [] args){SwingUtilities.invokeLater(new Runnable(){@Override公共无效run(){新的Programma().createAndShowGui();}});}公共无效createAndShowGui(){frame = new JFrame("DIG");panel = new JPanel(){@Override公共维度getPreferredSize(){返回新的Dimension(400,400);}};button = new JButton("Click Me");panel.add(button);button.addActionListener(new ActionListener(){公共无效actionPerformed(ActionEvent e){JLabel标签=新的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 的宽度或其他可以修改其大小的元素.请参见应避免使用setPreferred | Maximum| Swing中的最小尺寸?(一般共识为)

    I'm learning Java and Swing, but my JButton doesn't work.

    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. The frame and button are visible, nut when I click it, the label doesn't appear. How can I fix this?

    2. Do I write this before the other component like JPanel, JButton, etc., or do I write this at the end of code:

      frame.setVisible(true);

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    What is the difference ?

    By the way, button.setBounds(100, 100, 130, 35) doesn't work, either.

    解决方案

    I see some issues in your code:

    1. button.setBounds(100, 100, 130, 35); that line will be ignored and you shouldn't be manually be determining the position of the components. See Null layout is evil and Why is it frowned upon to use a null layout in swing? altough you're not using null layout, there is explained why you shouldn't be manually determining the positions of the components.

    2. You're running everything in your program in the main method, that will be hard to maintain later.

    3. You're calling frame.setVisible(true) before you've added all your elements to it, that will cause you random issues.

    4. You're not running your program on the Event Dispatch Thread (EDT), you can solve this by starting your program with the following code, which places it in the EDT. It's recommended as Swing is not thread safe.

      public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  //Your constructor here
              }
          });
      }
      

    5. You're setting the size of the JFrame with setSize(...), instead call frame.pack() and override the getPreferredSize() method of the JPanel.


    After all the above has been said, you need to call revalidate() and repaint() on your ActionListener so your program paints its new state.

    This program follows all the above recommendations and produces the following outputs (before clicking and after clicking the button 3 times), I on purpose to not make the images so large, made the GUI shorter (200 x 200 instead of 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);
        }
    }
    


    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 ?

    Altough I answered this on the recommendations, the difference is that if you call setVisible before adding all your elements to the frame, then you'll find yourself with some random issues where the components are not all visible until you pass your mouse over them (or where they should be). frame.pack() and setVisible should be the last ones to be called in your program, and frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); can be at the start or the end, it doesn't affects, but I prefer to have it at the end too.

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

    Well, that's because of you're using a layout manager (and that's the right way to do your GUIs) instead of a null-layout (which you shouldn't be using anyway) (See point #1).


    Edit

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

    If you read the docs for 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.

    So, it will calculate the minimum size for your JFrame where all the elements are visible and in their preferred size while setSize will only set the window size, but if you place a JScrollBar inside it for example this will reduce the window size, because of that, that's why you should override the getPreferredSize(...) method of your container, so it will calculate its preferred size including the width of the JScrollBar or some other elements that could modify its size. See Should I avoid the use of setPreferred|Maximum|MinimumSize in Swing? (the general consensus says yes)

    这篇关于Java-我的动作事件无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆