我正在尝试更改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);
}
}
答案 0 :(得分:3)
有两件事情可以找到。首先,正如您所说,您正在尝试从静态上下文中引用非静态变量。
第二,你似乎不明白线程是如何工作的......
基本上,main
通常在“主”线程内执行(由JVM执行时)。
然后使用EventQueue.invokeLater
。顾名思义,这将在以后的某个时间执行Runnable
“......”
EventQueue.invokeLater(new Runnable() {
public void run() {
然后尝试更改图标(让我们通过momement的非静态参考)...但lblStatusImg
将不会被初始化,也不会被显示,因为Runnable
尚未执行,这意味着,即使您没有遇到NullPointerException
,也不会看到更改...
您可以在System.out
和Runnable
方法中的第一个lblStatusImg.setIcon
来电之前添加main
进行测试。
你应该做的是......
Runnable
上下文。setStatus
方法例如......
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
)的方法。在这种情况下,我更喜欢第一种方法,因为这允许类确定状态的变化实际意味着什么。