2016-05-02 11 views
1

Ich habe ein Programm, das ein 4x4 Gitter von Quadraten durch einen GridBagLayout Layout Manager anzeigt. 16 JLabels, die alle ein Quadrat enthalten, werden angezeigt. Wenn auf eines der Rechtecke geklickt wird, soll es durch ein JLabel ersetzt werden, das ein Bild enthält (z. B. einen Hut). Das Bild nimmt also die Stelle des angeklickten Rechtecks ​​ein.JLabels kann nicht mit anderen JLabels mit GridBagLayout ersetzt werden

Im Moment passiert jedoch, dass das angeklickte Rechteck manchmal ersetzt wird. In anderen Fällen verschwindet das Rechteck, aber das Bild ersetzt es nicht. In anderen Fällen wird das Bild in einem Rechteck angezeigt, das zuvor angeklickt wurde, aber nur nach dem Klicken auf ein anderes Rechteck. Ich habe den relevantesten Code unten angegeben.

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(); 

     } 
    } 

} 

Im mouse() -Methode, habe ich versucht, Code zu schreiben, der die JLabel bestimmt, die gedrückt wird, erhält die GridBagConstraints dieser JLabel, entfernt die JLabel, die auf geklickt wird, und ersetzt dann das JLabel mit der neues JLabel mit den gegebenen GridBagConstraints. Wie ich bereits gesagt habe, funktioniert das Programm nicht wie geplant und ich weiß nicht warum.

Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu lesen. Jede Hilfe wäre willkommen.

Antwort

5

Warum möchten Sie JLabels tauschen? JLabels sind so konzipiert, dass sie Icons, normalerweise ImageIcons, enthalten. Wenn Sie Bilder austauschen möchten, sollten Sie die JLabels am besten belassen und einfach die angezeigte ImageIcon austauschen, indem Sie einfach setIcon(...) aufrufen. Das ist viel einfacher als das, was Sie versuchen, und das funktioniert mit der Bibliothek, nicht dagegen, wie Sie es versuchen.

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

Zum Beispiel aus meiner Antwort auf einen 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

Weiß nicht, warum ich nicht gedacht hätte. Vielen Dank. Was meinst du mit "mit der Bibliothek arbeiten, nicht dagegen?" – lb91

+0

@ lb91: Da JLabels zum Tausch von Icons gebaut wurden, ist es so einfach mit ihnen zu arbeiten, es beinhaltet so wenig Aufwand für den Programmierer, es gibt keine Notwendigkeit, neu zu lackieren, zu entfernen, hinzuzufügen, ... alles, was Sie tun müssen ist 'setIcon (...)' das ist es. Es ist eine natürliche Ergänzung für die Bibliothek. –

+0

Ich habe mich gerade daran erinnert, warum ich versuchte, das JLabel zu ändern. Der Grund war, weil ich nicht wusste, wie man feststellt, dass ein Rechteck bereits angeklickt wurde (ich möchte nur, dass jedes Rechteck einmal angeklickt wird). Das JPanel entfernt alle Komponenten, wenn auf 4 Rechtecke geklickt wurde. Ich kann jedoch nicht feststellen, dass ein JLabel bereits einmal angeklickt wurde, wenn ich nur das Symbol ändere. – lb91