Search code examples
javaswingjpaneljlabelbufferedimage

Java Add Click Listener to JButton in Loop in Thread


I have a loop, in which several JLabel's are created, containing a link to an image.

For each JLabel, there is a JButton created.

The behaviour I'm looking for is that for each JButton, to add a click listener, which fires a method.

The first issue is that it seems as though I am unable to add a Listener within the thread.

The second issue is that I don't see how I can specify each JButton to fire the click listener with a different value.

I'm looking for something similar to the following (obviously onClick method doesn't exist):

Thread thread = new Thread(new Runnable()
{
    public void run()
    {
        JPanel mainPanel = new JPanel();
        for (int counter = 0; counter < imageSources.size(); counter++)
        {
            JLabel imageSource = imageSources.get(counter);
            // JButton saveToDisk = new JButton("Save Image");
            // saveToDisk.onClick(saveFavourite(imageSources.get(counter)));
            mainPanel.add(imageSource);
            // mainPanel.add(saveToDisk);
        }

.
.
.

public void saveFavourite(String imageUrl)
{
    BufferedImage image = null;
    try
    {
        URL url = new URL(imageUrl);
        image = ImageIO.read(url);
        ImageIO.write(image, "jpg", new File("/Users/USERNAME/Desktop/" + webPage.getMemeId(imageUrl) + ".jpg"));
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

Solution

  • This is a simple example of creating buttons and adding to them ActionListeners that take String arguments during a loop

    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class Test extends JFrame {
    
        private final JLabel[] label = new JLabel[5];
        private final JButton[] button = new JButton[5];
    
        public Test() {
            JPanel mainPanel = new JPanel(new GridLayout(0,2));
            for (int counter = 0; counter < label.length; counter++) {
                label[counter] = new JLabel("Label " + counter);
                button[counter] = new JButton("Button " + counter);
                button[counter].addActionListener(new MyActionListener("Row " + counter));
                mainPanel.add(label[counter]);
                mainPanel.add(button[counter]);
            }
            this.add(mainPanel);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    Test run = new Test();
                    run.pack();
                    run.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    run.setVisible(true);
                }
            });
        }
    
        private class MyActionListener implements ActionListener {
    
            String text;
    
            public MyActionListener(String text) {
                this.text = text;
            }
    
            public void actionPerformed(ActionEvent e) {
                System.out.println(text);
            }
        }
    }