嗨,我有一个刷新图像的问题,添加到JLabel
.它类似于控制灯,可以在线/离线提供有关状态的信息.当我们启动应用程序并启用服务器时,它将调用此方法并将指示灯变为绿色.我们当然可以点击"离线"按钮,让它一直处于脱机状态.然后灯是红色的.到目前为止一切正常,但是当我们点击"上线"时,程序在线,但图像仍然是红色的.在每个地方,它都用同样的方法调用.只是这种灯不起作用,因为连接和断开工作正常.
我给你一些代码:
只改变图像的方法:
public void changeLight(String name){ BufferedImage imgtmp; try { System.out.println("CHANGE LIGHT: "+name); imgtmp = ImageIO.read(new File(name)); panelMenuOnline.remove(panelMenuOnlineLight); panelMenuOnlineLight = new JLabel(new ImageIcon(imgtmp)); panelMenuOnline.add(panelMenuOnlineLight); } catch (IOException e) { e.printStackTrace(); } }
同一类中的按钮定义:
panelMenuButOn = new Guzik("GO ONLINE"){ @Override public void actionPerformed(ActionEvent e) { if(!Pang.game.online){ Pang.game.haveToBeOffline = false; if(Client.checkConnection()) { JOptionPane.showMessageDialog(this, "Successfully connected"); Pang.game.online=true; changeLight(imgGREEN); } else { JOptionPane.showMessageDialog(this, "Connection refused"); } } else { JOptionPane.showMessageDialog(this, "Successfully disconnected"); setText("GO ONLINE"); Pang.game.haveToBeOffline = true; Pang.game.online=false; changeLight(imgRED); } } };
我还有线程(如果我不让他离线)测试连接和更改控制灯:
public void run() { while(true){ Pang.game.online=Client.checkConnection(); if(Pang.game.online){ Pang.game.frame.panelMenuButOn.setText("GO OFFLINE"); Pang.game.frame.changeLight(Pang.game.frame.imgGREEN); } else { Pang.game.frame.panelMenuButOn.setText("GO ONLINE"); Pang.game.frame.changeLight(Pang.game.frame.imgRED); } //System.out.println("Checked = "+Pang.game.online); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
Hovercraft F.. 5
您不仅要更改JLabel显示的Icon,还要完全更改JLabel,我建议您不要这样做.代替,...
读入图像并在程序创建时创建ImageIcons,而不是每次需要更换灯光时.
只使用一个 JLabel来保存图标.
如果要更改灯光,请调用不需要String的方法.如果灯光仅处于2种状态,则布尔值可能会很好.然后在一个JLabel中换掉ImageIcons.如果不需要,请不要更换JLabels mid程序.
像这样的代码行:Pang.game.frame.panelMenuButOn.setText("GO OFFLINE");
表示您正在使用静态字段和方法.如果是这样,您将需要重新配置您的程序,以便它不会执行此操作,以便它使用实例方法和字段来处理大多数事情.
我同意Ross Drew - 所有的Swing调用都应该只在Swing Event Dispatch Thread(或EDT)上进行.他的答案是1+.
例如,
import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.util.EnumMap; import javax.imageio.ImageIO; import javax.swing.*; @SuppressWarnings("serial") public class StopLightApp extends JPanel { private static final String IMG_PATH = "http://urbannight.files.wordpress.com/2012/09/" + "red-orange-green-traffic-lights.jpg?w=300&h=240"; private static final int PAD = 13; private JLabel stopLightLabel = new JLabel(); private EnumMaplightIconMap = new EnumMap ( LightColor.class); private LightColor lightColor = LightColor.RED; public StopLightApp() throws IOException { URL stopLightImgUrl = new URL(IMG_PATH); BufferedImage stopLightImg = ImageIO.read(stopLightImgUrl); for (int i = 0; i < LightColor.values().length; i++) { BufferedImage smlLightImg = specializedForThisImageGetSubImage( stopLightImg, i); Icon smlIcon = new ImageIcon(smlLightImg); lightIconMap.put(LightColor.values()[i], smlIcon); } add(stopLightLabel); stopLightLabel.setIcon(lightIconMap.get(lightColor)); stopLightLabel.setText(lightColor.getName()); stopLightLabel.setHorizontalTextPosition(SwingConstants.CENTER); stopLightLabel.setVerticalTextPosition(SwingConstants.BOTTOM); setBackground(Color.white); setBorder(BorderFactory.createEmptyBorder(10, 60, 10, 60)); } private BufferedImage specializedForThisImageGetSubImage( BufferedImage stopLightImg, int i) { int x = PAD + (i * (stopLightImg.getWidth() - 2 * PAD)) / 3; int y = PAD; int w = (stopLightImg.getWidth() - 2 * PAD) / 3; int h = stopLightImg.getHeight() - 2 * PAD; BufferedImage smlLightImg = stopLightImg.getSubimage(x, y, w, h); return smlLightImg; } public void setLightColor(LightColor lightColor) { this.lightColor = lightColor; stopLightLabel.setIcon(lightIconMap.get(lightColor)); stopLightLabel.setText(lightColor.getName()); } private static void createAndShowGui() { try { final StopLightApp stopLight = new StopLightApp(); JFrame frame = new JFrame("Stop Light App"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(stopLight); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); int delay = 1000; new Timer(delay, new ActionListener() { int index = 0; @Override public void actionPerformed(ActionEvent e) { index++; index %= LightColor.values().length; stopLight.setLightColor(LightColor.values()[index]); } }).start(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } enum LightColor { RED("Red"), YELLOW("Yellow"), GREEN("Green"); private String name; private LightColor(String name) { this.name = name; } public String getName() { return name; } }
这会产生一种可以改变的光: