代码之家  ›  专栏  ›  技术社区  ›  DaveTheMinion

Java-更改JLabel的图标不起作用

  •  0
  • DaveTheMinion  · 技术社区  · 11 年前

    我正在尝试更改JLabel的图标(背景),但图标未更新时出现问题。每当我尝试 lblStatusImg.setIcon(new ImageIcon(Brix_Updater_Module.class.getResource("/resources/fail.png"))); 要更改main方法中的JLabel,编译器首先抱怨变量 lblStatusImg 不存在,所以我将其从JFrame初始化方法移到了类级变量。在这之后,Eclipse抱怨我试图从静态上下文引用非静态方法,所以我 lbl状态mg 静止的这使得程序可以编译,但图标并没有在任何时候改变。

    因为很难理解我的问题 here is a download link for an Eclipse workspace 这说明了我的问题。当你第一次打开它时,你会注意到它有一些问题。它们是故意放在那里的,以便你更容易看到我在哪里过得很艰难。如果Eclipse要求您将有问题的项目设置为静态,只需执行该操作,然后运行程序即可。你会注意到它并没有像应该的那样改变标签图标。

    因为不是所有人都有Eclipse,所以这里是工作区的全部代码。

    import java.awt.Component;
    import java.awt.EventQueue;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    import java.awt.Font;
    
    import javax.swing.SwingConstants;
    
    import java.awt.Window.Type;
    import java.io.BufferedOutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Timer;
    
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    
    public class StackOverflow_Image_Resource_Demo {
    
        private JFrame frmUpdate;
        JLabel lblStatusImg = new JLabel("");
        JButton btnUpdateComplete = new JButton("OK");
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
                        window.frmUpdate.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
    
            try {
                lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("success.png")));
                btnUpdateComplete.setVisible(true);
            }
            catch(Exception e)
            {
                Component frame = null;
                lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/fail.png")));
                JOptionPane.showMessageDialog(frame, "Update Failed", "Update Failed", JOptionPane.ERROR_MESSAGE);
                System.exit(1);
            }
        }
    
        /**
         * Create the application.
         */
        public StackOverflow_Image_Resource_Demo() {
            initialize();
        }
    
        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            frmUpdate = new JFrame();
            frmUpdate.setType(Type.UTILITY);
            frmUpdate.setTitle("StackOverflow Image Resource Issue Demo");
            frmUpdate.setBounds(100, 100, 450, 300);
            frmUpdate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmUpdate.getContentPane().setLayout(null);
    
            //JLabel lblStatusImg = new JLabel(""); - Commented out when I made lblStatusImg class level.
            lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/updating.gif")));
            lblStatusImg.setBounds(10, 22, 414, 97);
            frmUpdate.getContentPane().add(lblStatusImg);
    
            //JButton btnUpdateComplete = new JButton("OK"); - Commented out when I made btnUpdateComplete class level.
            btnUpdateComplete.setVisible(false);
            btnUpdateComplete.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseReleased(MouseEvent arg0) {
                    System.exit(1);
                }
            });
            btnUpdateComplete.setBounds(170, 179, 89, 23);
            frmUpdate.getContentPane().add(btnUpdateComplete);
        }
    }
    

    这是我的一个更新版本的代码,它更新了图像,但在完成所有其他操作之前不会完全加载UI。

    import java.awt.Component;
    import java.awt.EventQueue;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    import java.awt.Font;
    
    import javax.swing.SwingConstants;
    
    import java.awt.Window.Type;
    import java.io.BufferedOutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Timer;
    
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    
    public class StackOverflow_Image_Resource_Demo {
    
        private JFrame frmUpdate;
        JLabel lblStatusImg = new JLabel("");
        JButton btnUpdateComplete = new JButton("OK");
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
    

    尝试{ lblStatusImg.setIcon(新图像图标(StackOverflow_Image_Resource_Demo.class.getResource(“success.png”))); btnUpdateComplete.setVisible(true); } catch(异常e) { 组件框架=空; lblStatusImg.setIcon(新图像图标(StackOverflow_Image_Resource_Demo.class.getResource(“/resources/fail.png”))); JOptionPane.showMessageDialog(框架,“更新失败”,“更新错误”,JOption窗格.ERROR_MESSAGE); 系统出口(1); } window.frmUpdate.setVisible(true); }catch(异常e){ e.printStackTrace(); } } }); }

        /**
         * Create the application.
         */
        public StackOverflow_Image_Resource_Demo() {
            initialize();
        }
    
        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            frmUpdate = new JFrame();
            frmUpdate.setType(Type.UTILITY);
            frmUpdate.setTitle("StackOverflow Image Resource Issue Demo");
            frmUpdate.setBounds(100, 100, 450, 300);
            frmUpdate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmUpdate.getContentPane().setLayout(null);
    
            //JLabel lblStatusImg = new JLabel(""); - Commented out when I made lblStatusImg class level.
            lblStatusImg.setIcon(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource("/resources/updating.gif")));
            lblStatusImg.setBounds(10, 22, 414, 97);
            frmUpdate.getContentPane().add(lblStatusImg);
    
            //JButton btnUpdateComplete = new JButton("OK"); - Commented out when I made btnUpdateComplete class level.
            btnUpdateComplete.setVisible(false);
            btnUpdateComplete.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseReleased(MouseEvent arg0) {
                    System.exit(1);
                }
            });
            btnUpdateComplete.setBounds(170, 179, 89, 23);
            frmUpdate.getContentPane().add(btnUpdateComplete);
        }
    }
    
    1 回复  |  直到 11 年前
        1
  •  3
  •   MadProgrammer    11 年前

    发现了两件事。第一个是,正如您所说,您试图从静态上下文引用非静态变量。

    第二个问题是,你似乎不了解线程是如何工作的。。。

    大体上 main 通常在“主”线程中执行(由JVM执行时)。

    然后使用 EventQueue.invokeLater 。顾名思义,它将执行 Runnable “稍后”。。。在未来的某个时候。。。

            EventQueue.invokeLater(new Runnable() {
                public void run() {
    

    然后尝试更改图标(让我们暂时忽略非静态引用)。。。但是 lblStatusImg 不会初始化,也不可能显示,因为 可运行的 尚未执行,意味着,即使您没有遇到 NullPointerException ,你不会看到变化。。。

    您可以通过添加 System.out 在您的 可运行的 在第一次之前 lblStatusImg.setIcon 调用 主要的 方法

    你应该做的是。。。

    1. 将“状态”更改移动到 可运行的 上下文
    2. 提供 setStatus 能够根据提供状态根据需要更改标签和UI内容的方法

    例如

    public static final int SUCCESS = 0;
    public static final int FAIL = 0;
    
    //...
    
    public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        StackOverflow_Image_Resource_Demo window = new StackOverflow_Image_Resource_Demo();
                        // This e
                        window.frmUpdate.setVisible(true);
    
                        window.setStatus(StackOverflow_Image_Resource_Demo.SUCCESS);
                    } catch (Exception e) {
                        e.printStackTrace();
                        Component frame = null;
                        window.setStatus(StackOverflow_Image_Resource_Demo.FAIL);
                        JOptionPane.showMessageDialog(frame, "Update Failed", "Update Failed", JOptionPane.ERROR_MESSAGE);
                        window.dispose();
                    }
                }
            });
        }
    

    应避免将实例字段公开为 public 而是提供间接改变其状态的方法(例如 设置状态 )或直接( setStatusIcon ). 在这种情况下,我更喜欢第一种方法,因为这允许类确定状态变化的实际含义。