2016-05-02 30 views
1

我有一個程序通過GridBagLayout佈局管理器顯示4x4方格網格。將顯示全部包含square.gif的16個JLabels。點擊其中一個矩形時,應該用包含圖像的JLabel(例如帽子)替換它。所以,圖像取代了被點擊的矩形。無法使用GridBagLayout替換其他JLabel JLabel

但是,此刻發生的情況是,僅點擊的矩形有時會被替換。其他時候,矩形會消失,但圖像不會取代它。其他時候,圖像將顯示在之前點擊過的矩形中,但只有在單擊不同的矩形後纔會顯示。我在下面放置了最相關的代碼。

public void displayGrid() { 


    c.gridx = 0; 
    c.gridy = 0; 

    try { 
     squareImage = ImageIO.read(this.getClass().getResource("stimulus(0).gif")); //line 37 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    JLabel squareLabel = new JLabel(new ImageIcon(squareImage)); 

    for(int i = 0; i < 16; i++){ 
     c.gridx = i % 4; 
     c.gridy = i/4; 
     squareLabel = new JLabel(new ImageIcon(squareImage)); 
     squareLabels[i] = squareLabel; 
     panel.add(squareLabels[i], c); 
     squareLabels[i].addMouseListener(this); 

     System.out.println(c.gridx + "" + c.gridy); 

    } 

    panel.validate(); 

} 

public void mousePressed(MouseEvent e) { 

    for(int i = 0; i < squareLabels.length; i++){ 
     if(e.getSource() == squareLabels[i]){ 
      //JLabel removedLabel = squareLabels[i]; 
      c.gridx = (i/4); 
      c.gridy = (i%4); 
      panel.remove(squareLabels[i]); 
      panel.revalidate(); 
      panel.repaint(); 
      panel.add(stimuliLabels[0], c); 
      panel.validate(); 

     } 
    } 

} 

在的mousePressed()方法,我試圖編寫的代碼,確定被按下的一個JLabel時,獲取的JLabel的的GridBagConstraints,刪除該被點擊選擇JLabel,然後替換的JLabel與具有給定GridBagConstraints的新JLabel。但是,正如我已經說過的那樣,該計劃沒有按計劃進行,我不知道爲什麼。

感謝您花時間閱讀本文。任何幫助,將不勝感激。

回答

5

爲什麼要換JLabels? JLabels是爲了保存圖標(通常是ImageIcons)而構建的,如果要交換圖像,最好將JLabels留在原位,並簡單地交換顯示的ImageIcon,通過調用setIcon(...)即可輕鬆完成。這比你想要做的要容易得多,這與圖書館一起工作,而不是像你正在做的那樣對付它。

public void mousePressed(MouseEvent e) { 
    // assuming that only JLabels are given this MouseListener: 
    JLabel label = (JLabel) e.getSource(); 
    label.setIcon(desiredNewIcon); 
} 

例如,從我回答一個similar question

import java.awt.GridLayout; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import javax.imageio.ImageIO; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class RandomChessMen extends JPanel { 
    // for this example I get a sprite sheet that holds several sprite images in it 
    // the images can be found here: https://stackoverflow.com/questions/19209650 
    private static final String IMAGE_PATH = "http://i.stack.imgur.com/memI0.png"; 
    private static final int LABEL_COUNT = 2; 
    private static final int ICON_COLUMNS = 6; 
    private Random random = new Random(); 

    public RandomChessMen() throws IOException { 
     URL url = new URL(IMAGE_PATH); 
     BufferedImage largeImg = ImageIO.read(url); 
     setLayout(new GridLayout(1, 0)); 

     // break down large image into its constituent sprites and place into ArrayList<Icon> 
     int w = largeImg.getWidth()/ICON_COLUMNS; 
     int h = largeImg.getHeight()/LABEL_COUNT; 
     for (int i = 0; i < LABEL_COUNT; i++) { 
     final List<Icon> iconList = new ArrayList<>(); 
     int y = (i * largeImg.getHeight())/LABEL_COUNT; 
     // get 6 icons out of large image 
     for (int j = 0; j < ICON_COLUMNS; j++) { 
      int x = (j * largeImg.getWidth())/ICON_COLUMNS; 
      // get subImage 
      BufferedImage subImg = largeImg.getSubimage(x, y, w, h); 
      // create ImageIcon and add to list 
      iconList.add(new ImageIcon(subImg)); 
     } 

     // create JLabel 
     final JLabel label = new JLabel("", SwingConstants.CENTER); 
     int eb = 40; 
     label.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb)); 

     // get random index for iconList 
     int randomIndex = random.nextInt(iconList.size()); 
     Icon icon = iconList.get(randomIndex); // use index to get random Icon 
     label.setIcon(icon); // set label's icon 
     label.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       Icon secondIcon = label.getIcon(); 
       // so we don't repeat icons 
       while (label.getIcon() == secondIcon) { 
        int randomIndex = random.nextInt(iconList.size()); 
        secondIcon = iconList.get(randomIndex); 
       } 
       label.setIcon(secondIcon); 
      } 
     }); 
     // add to GUI 
     add(label); 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("RandomImages"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     try { 
     frame.getContentPane().add(new RandomChessMen()); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
     } 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

不知道爲什麼我沒有想到這一點。謝謝。 「與圖書館合作,而不是反對」是什麼意思? – lb91

+0

@ lb91:因爲JLabel是用來交換圖標的,所以它們很容易處理,它涉及到程序員方面的小開銷,不需要重新繪製,重新驗證,移除,添加......所有你需要做的事情是'setIcon(...)'就是這樣。這對圖書館來說非常合適。 –

+0

我只記得我爲什麼要改變JLabel。原因是我不知道如何確定一個矩形已經被點擊(我只想每個矩形被點擊一次)。如果點擊4個矩形,JPanel將刪除所有組件。但是,如果我只是更改圖標,我無法確定JLabel已被點擊過一次。 – lb91