2014-01-24 256 views
2

嗨,我有一個刷新圖像的問題,添加到JLabel。它就像控制燈一樣給我們提供線上/線下狀態的信息。當我們啓動應用程序並啓動服務器時,它將調用此方法並將指示燈更改爲綠色。我們當然可以點擊按鈕「離線」,並一直離線。然後光線變紅。現在一切正常,但當我們點擊「上線」時,程序在線,但圖像仍然是紅色。在每個地方都被同樣的方法調用。只是這個燈不工作,因爲連接和斷開工作正常。在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(); 
     } 

    } 
} 

回答

5

您不僅僅是更改JLabel顯示的圖標,而是完全更改JLabels,並且我建議您不要這樣做。相反,...

  • 閱讀您的圖像,並在程序創建時創建ImageIcons,而不是每次需要更改光源。
  • 只使用一個 JLabel拿着圖標。
  • 當你想改變燈光時,調用一個不需要String的方法。如果光線僅處於2種狀態,布爾值可能會表現良好。然後在一個JLabel中換出ImageIcons。當不需要時,不要交換JLabels中間程序。
  • 這樣的代碼行: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 EnumMap<LightColor, Icon> lightIconMap = new EnumMap<LightColor, Icon>(
     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; 
    } 
} 

創建將可以改變光:

red lightyellow lightgreen light

+0

...但我可以給予好評你的,恕我直言,這是極好回答這個問題。 –

+0

我正在尋找解決方案,但我找不到如何交換標籤中的圖標,因爲我想我必須刪除一個圖標並添加另一個圖標? –

+0

@ user3233685:請參閱我上面的代碼示例。所有你需要做的就是調用JLabel上的'setIcon(Icon icon)'來交換圖標,就是這樣! –