Search code examples
javaswingjlabel

Java selectable JLabel


I have made a GUI with a gallery panel which shows images held in JLabels. I need to make JLabel highlightable and then remove it if the user clicks remove. Is there a way or should I change my approach?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

public class GalleryPanel extends JPanel 
{

    private static final long serialVersionUID = 1L;
    private int currentImage;
    private JLabel[] images;
    private final int MAX_IMAGES = 12;
    private JScrollPane scrollPane;
    private JList<JLabel> imageGallery;
    private DefaultListModel<JLabel> listModel;
    private JPanel imageHolder;

public void init()
{   
    setLayout(new BorderLayout());

    imageHolder = new JPanel();
    imageHolder.setLayout(new BoxLayout(imageHolder, BoxLayout.PAGE_AXIS));
    imageHolder.setSize(getWidth(), getHeight());

    images = new JLabel[MAX_IMAGES];

    listModel = new DefaultListModel<JLabel>();
    listModel.addElement(new JLabel(new ImageIcon("Untitled.png")));


    imageGallery = new JList<JLabel>(listModel);
    imageGallery.setBackground(Color.GRAY);
    imageGallery.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    imageGallery.setLayoutOrientation(JList.VERTICAL);
    imageGallery.setFixedCellHeight(50);
    imageGallery.setFixedCellWidth(100);

    scrollPane = new JScrollPane(imageHolder);
    scrollPane.setBackground(Color.RED);
    add(scrollPane, BorderLayout.CENTER);
}


public void addImageToGallery(File file)
{
    if ( currentImage <= images.length - 1)
    {   
        BufferedImage bufImage = null;

        try
        {
            bufImage = ImageIO.read(file);  //tries to load the image
        }
        catch (Exception e)
        {
            System.out.println("Unable to load file " + file.toString());
        }

        Image resizedImage = bufImage.getScaledInstance(bufImage.getWidth()/5, bufImage.getHeight()/5, Image.SCALE_SMOOTH);
        ImageIcon icon = new ImageIcon(resizedImage);

        images[currentImage] = new JLabel(icon, JLabel.CENTER);
        //images[currentImage].setSize(resized);
        //images[currentImage
        images[currentImage].setBorder(new TitledBorder(new LineBorder(Color.GRAY,5), file.toString()));


        imageHolder.add(images[currentImage]);

        revalidate();
        repaint();


        currentImage++;
    }
    else
    {
        throw new ArrayIndexOutOfBoundsException("The gallery is full");
    }
}


public final int getMaxImages()
{
    return MAX_IMAGES;
}


public Dimension getPreferredSize() 
{
    return new Dimension(300, 700);
}

}

enter image description here


Solution

  • So you first of call should be the tutorals

    Which will give you the basic information you need to proceeded.

    Based on your available code, you should not be adding a JLabel to the ListModel, you should never add components to data models, as more often than not, Swing components have there own concept of how they will render them.

    In your case, you're actually lucky, as the default ListCellRenderer is based on a JLabel and will render Icon's automatically, for example

    import javax.swing.DefaultListModel;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
    
                    DefaultListModel model = new DefaultListModel();
                    model.addElement(new ImageIcon("mt01.jpg"));
                    model.addElement(new ImageIcon("mt02.jpg"));
                    model.addElement(new ImageIcon("mt03.jpg"));
    
                    JList list = new JList(model);
                    list.setVisibleRowCount(3);
                    list.addListSelectionListener(new ListSelectionListener() {
                        @Override
                        public void valueChanged(ListSelectionEvent e) {
                            if (!e.getValueIsAdjusting()) {
                                System.out.println(list.getSelectedIndex());
                            }
                        }
                    });
    
                    JFrame frame = new JFrame("Test");
                    frame.add(new JScrollPane(list));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }