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

时间:2014-03-23 22:57:33

标签: java swing jframe jlabel embedded-resource

我正在尝试更改JLabel的图标(背景),但我遇到了图标无法更新的问题。每当我尝试lblStatusImg.setIcon(new ImageIcon(Brix_Updater_Module.class.getResource("/resources/fail.png")));更改main方法中的JLabel时,编译器首先抱怨变量lblStatusImg不存在,所以我将它从JFrame初始化方法移动到类级变量。在此之后,Eclipse抱怨我试图从静态上下文引用非静态方法,因此我将lblStatusImg设为静态。这使得程序可以编译,但是图标没有随时改变。

因为很难理解我的问题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);
    }
}

以下是我的代码的更新版本,用于更新图片,但在完成所有其他操作之前,不会完全加载用户界面。

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(new ImageIcon(StackOverflow_Image_Resource_Demo.class.getResource(" success.png")));                 btnUpdateComplete.setVisible(真);             }             catch(例外e)             {                 组件帧= 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);             }                         window.frmUpdate.setVisible(真);                     } 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 个答案:

答案 0 :(得分:3)

有两件事情可以找到。首先,正如您所说,您正在尝试从静态上下文中引用非静态变量。

第二,你似乎不明白线程是如何工作的......

基本上,main通常在“主”线程内执行(由JVM执行时)。

然后使用EventQueue.invokeLater。顾名思义,这将在以后的某个时间执行Runnable“......”

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

然后尝试更改图标(让我们通过momement的非静态参考)...但lblStatusImg将不会被初始化,也不会被显示,因为Runnable尚未执行,这意味着,即使您没有遇到NullPointerException,也不会看到更改...

您可以在System.outRunnable方法中的第一个lblStatusImg.setIcon来电之前添加main进行测试。

你应该做的是......

  1. 将“状态”更改更改移至Runnable上下文。
  2. 根据提供状态提供能够根据需要更改标签和UI内容的setStatus方法
  3. 例如......

    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,而是提供间接更改其状态(例如setStatus)或直接(setStatusIcon)的方法。在这种情况下,我更喜欢第一种方法,因为这允许类确定状态的变化实际意味着什么。