Search code examples
javaimageswingjbuttonactionlistener

Adding an image to a frame by button press


I am trying to implement an image appearing when a button is pressed. For this purpose I thought I could just copy the concept of button 4 (which works) and exchange the System.exit(0) with code to add an image, but while I've been able to use that code elsewhere successfully, here it does not seem to work.

import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JSpinner;
import java.awt.Color;
import java.util.ArrayList;

public class Mainframe {

    private JFrame frmOceanlife;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Mainframe window = new Mainframe();
                    window.frmOceanlife.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Mainframe() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frmOceanlife = new JFrame();
        frmOceanlife.setTitle("OceanLife");
        frmOceanlife.setBounds(100, 100, 750, 600);
        frmOceanlife.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOceanlife.getContentPane().setLayout(null);
        
        
        JButton btnNewButton_4 = new JButton("Quit");
        btnNewButton_4.setBounds(640, 6, 81, 29);
        frmOceanlife.getContentPane().add(btnNewButton_4);
        
        btnNewButton_4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
                    }
                });
                
        
        JButton btnNewButton_5 = new JButton("Einfügen");
        btnNewButton_5.setBounds(410, 34, 103, 29);
        frmOceanlife.getContentPane().add(btnNewButton_5);
        
        btnNewButton_5.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ImageIcon icon = new ImageIcon("Stone.png");
                JLabel label = new JLabel(icon);
                // label.setBounds(25,25,50,50);
                frmOceanlife.getContentPane().add(label);
                
            }
        });
        
        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);
        panel.setBounds(70, 75, 600, 450);
        panel.setLayout(new FlowLayout());
        JLabel piclabel = new JLabel(new ImageIcon("underwater-600x450.png"));
        panel.add(piclabel);
        frmOceanlife.getContentPane().add(panel);
        
        
        JLabel lblNewLabel_2 = new JLabel("Welcome to Oceanlife - Your Ocean size is 600x450!");
        lblNewLabel_2.setBounds(6, 539, 334, 16);
        frmOceanlife.getContentPane().add(lblNewLabel_2);
    }
}

Solution

  • The problem is that you are creating a new JLabel and trying to add it to the frame, once the button is pressed. Instead, you should just change the Icon of the label that is already added to the frame (i.e., piclabel), using piclabel.setIcon(icon);. So, you should declare picLabel at the start of your code, so that it can be accessible in the actionPerformed method of your button.

    public class Mainframe {
    
        private JFrame frmOceanlife;
        JLabel piclabel;
    ...
    

    Then, instantiate the label in the initialize() method as below:

    ...
    panel.setBounds(70, 75, 600, 450);
    panel.setLayout(new FlowLayout());
    piclabel = new JLabel(new ImageIcon("underwater-600x450.png"));
    ...
    

    Finally, your actionPerformed method for btnNewButton_5 (please consider using descriptive names instead) should look like this:

    btnNewButton_5.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            ImageIcon icon = new ImageIcon("Stone.png");
            piclabel.setIcon(icon);
            
        }
    }); 
    

    Update

    If, however, what you want is to add a new JLabel each time, and not change the icon of the existing one, you could use Box object with BoxLayout added to a ScrollPane. Then add the ScrollPane to your JFrame. Working example is shown below, based on the code you provided (again, please consider using descriptive names and removing unecessary code):

    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import java.awt.*;
    import javax.swing.*;
    
    public class Mainframe {
        
        private JFrame frmOceanlife;
        Box box;
        JScrollPane scrollPane;
        
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        Mainframe mf = new Mainframe();
                        mf.initialize();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            
            JButton insertBtn = new JButton("Einfügen");
            insertBtn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    ImageIcon icon = new ImageIcon("Stone.png");
                    JLabel label = new JLabel(icon);
                    box.add(Box.createRigidArea(new Dimension(0, 5)));// creates space between the JLabels
                    box.add(label);
                    frmOceanlife.repaint();
                    frmOceanlife.revalidate();
                    Rectangle bounds = label.getBounds();
                    scrollPane.getViewport().scrollRectToVisible(bounds);// scroll to the new image
    
                }
            });
    
            JButton quitBtn = new JButton("Quit");
            quitBtn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });
    
            box = new Box(BoxLayout.Y_AXIS);
            JLabel piclabel = new JLabel(new ImageIcon("underwater-600x450.png"));
            box.add(piclabel);
            
            scrollPane = new JScrollPane(box);
            Dimension dim = new Dimension(box.getComponent(0).getPreferredSize());
            scrollPane.getViewport().setPreferredSize(dim);
            scrollPane.getVerticalScrollBar().setUnitIncrement(dim.height);
            scrollPane.getViewport().setBackground(Color.WHITE);
    
            JPanel controlPanel = new JPanel();
            controlPanel.setLayout(new FlowLayout());
            controlPanel.add(insertBtn);
            controlPanel.add(quitBtn);
            
            JLabel titleLbl = new JLabel("Welcome to Oceanlife - Your Ocean size is 600x450!", SwingConstants.CENTER);
           
            frmOceanlife = new JFrame();
            frmOceanlife.getContentPane().add(titleLbl, BorderLayout.NORTH);
            frmOceanlife.getContentPane().add(scrollPane, BorderLayout.CENTER);
            frmOceanlife.getContentPane().add(controlPanel, BorderLayout.SOUTH);
            frmOceanlife.setTitle("OceanLife");
            frmOceanlife.pack();
            frmOceanlife.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmOceanlife.setLocationRelativeTo(null);
            frmOceanlife.setVisible(true);
    
        }
    }