通过按下按钮将图像添加到框架

Adding an image to a frame by button press

我正在尝试实现按下按钮时出现的图像。为此,我想我可以复制按钮 4 的概念(有效)并将 System.exit(0) 与代码交换以添加图像,但是虽然我已经能够在其他地方成功使用该代码,这里好像不行。

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

这是一个演示 CardLayout. Note that I used [Eclipse] WindowBuilder. All the below code was generated by WindowBuilder apart from the ActionListener implementations. Also note that the ActionListener implementation for quitButton uses a lambda expression while the insertButton implementation uses a method reference.

用法的示例应用程序

代码后有更多注释。

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import javax.swing.JLabel;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class MainFram {

    private JFrame frame;
    private JPanel cardsPanel;
    private JPanel firstPanel;
    private JLabel firstLabel;
    private JPanel secondPanel;
    private JLabel secondLabel;
    private JPanel buttonsPanel;
    private JButton insertButton;
    private JButton quitButton;

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

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

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(getCardsPanel(), BorderLayout.CENTER);
        frame.getContentPane().add(getButtonsPanel(), BorderLayout.SOUTH);
    }

    private JPanel getCardsPanel() {
        if (cardsPanel == null) {
            cardsPanel = new JPanel();
            cardsPanel.setLayout(new CardLayout(0, 0));
            cardsPanel.add(getFirstPanel(), "first");
            cardsPanel.add(getSecondPanel(), "second");
        }
        return cardsPanel;
    }

    private JPanel getFirstPanel() {
        if (firstPanel == null) {
            firstPanel = new JPanel();
            firstPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
            firstPanel.add(getFirstLabel());
        }
        return firstPanel;
    }

    private JLabel getFirstLabel() {
        if (firstLabel == null) {
            firstLabel = new JLabel("");
            firstLabel.setIcon(new ImageIcon(getClass().getResource("underwater-600x450.png")));
        }
        return firstLabel;
    }

    private JPanel getSecondPanel() {
        if (secondPanel == null) {
            secondPanel = new JPanel();
            secondPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
            secondPanel.add(getLabel_1());
        }
        return secondPanel;
    }

    private JLabel getLabel_1() {
        if (secondLabel == null) {
            secondLabel = new JLabel("");
            secondLabel.setIcon(new ImageIcon(getClass().getResource("Stone.png")));
        }
        return secondLabel;
    }

    private JPanel getButtonsPanel() {
        if (buttonsPanel == null) {
            buttonsPanel = new JPanel();
            buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
            buttonsPanel.add(getInsertButton());
            buttonsPanel.add(getQuitButton());
        }
        return buttonsPanel;
    }

    private JButton getInsertButton() {
        if (insertButton == null) {
            insertButton = new JButton("Einfügen");
            insertButton.addActionListener(this::insertAction);
        }
        return insertButton;
    }

    private JButton getQuitButton() {
        if (quitButton == null) {
            quitButton = new JButton("Quit");
            quitButton.addActionListener(e -> System.exit(0));
        }
        return quitButton;
    }

    private void insertAction(ActionEvent event) {
        CardLayout cardLayout = (CardLayout) cardsPanel.getLayout();
        cardLayout.next(cardsPanel);
    }
}

以上代码要求图像文件,即 underwater-600x450.pngStone.png,与文件 MainFram.class 位于同一目录中。参考How to Use Icons.

当您单击 insertButton 时,包含 underwater-600x450.png 图像的面板将隐藏,并显示包含 Stone.png 图像的面板。再次单击 insertButton 将隐藏 Stone.png 并显示 underwater-600x450.png。换句话说,单击 insertButton 可切换图像。

问题是您正在创建一个新的 JLabel 并尝试在按下按钮后将其添加到框架中。相反,您应该使用 piclabel.setIcon(icon); 更改已添加到框架的标签的图标(即 piclabel)。因此,您应该在代码的开头声明 picLabel,以便可以在按钮的 actionPerformed 方法中访问它。

public class Mainframe {

    private JFrame frmOceanlife;
    JLabel piclabel;
...

然后,在initialize()方法中实例化标签如下:

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

最后,btnNewButton_5 的 actionPerformed 方法(请考虑改用描述性名称)应如下所示:

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

更新

但是,如果您想要每次都添加一个新的 JLabel,而不是更改现有 JLabel 的图标,则可以使用 Box 对象并将 BoxLayout 添加到 ScrollPane。然后将 ScrollPane 添加到您的 JFrame。工作示例如下所示,基于您提供的代码(同样,请考虑使用描述性名称并删除不必要的代码):

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

    }
}

首先要做的是使用 layout managers 而不是手动设置边界:

import java.awt.*;
import javax.swing.*;

public class Mainframe {
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            try {
                new Mainframe();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

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

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        JFrame frmOceanlife = new JFrame();
        frmOceanlife.setTitle("OceanLife");
        //frmOceanlife.setBounds(100, 100, 750, 600);
        frmOceanlife.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //frmOceanlife.getContentPane().setLayout(null);
        frmOceanlife.setLayout(new BoxLayout(frmOceanlife.getContentPane(), BoxLayout.PAGE_AXIS));

        JButton btnNewButton_4 = new JButton("Quit");
        btnNewButton_4.addActionListener(e -> System.exit(0));
        //btnNewButton_4.setBounds(640, 6, 81, 29);
        JPanel quitPanel = new JPanel();
        quitPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        quitPanel.add(btnNewButton_4);
        frmOceanlife.getContentPane().add(quitPanel);

        JPanel stonesPanel = new JPanel();
        frmOceanlife.getContentPane().add(stonesPanel);

        JButton btnNewButton_5 = new JButton("Insert");
        //btnNewButton_5.setBounds(410, 34, 103, 29);
        btnNewButton_5.addActionListener(e -> {
            ImageIcon icon = new ImageIcon("Stone.png");
            JLabel label = new JLabel(icon);
            //label.setBounds(25,25,50,50);
            stonesPanel.add(label);
            frmOceanlife.revalidate();
        });

        JPanel insertPanel = new JPanel();
        insertPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        insertPanel.add(btnNewButton_5);
        frmOceanlife.getContentPane().add(insertPanel);

        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);
        //panel.setBounds(70, 75, 600, 450);
        panel.setLayout(new FlowLayout());
        panel.setPreferredSize(new Dimension(700,550));

        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);
        JPanel infoPanel = new JPanel();
        infoPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        infoPanel.add(lblNewLabel_2);
        frmOceanlife.getContentPane().add(infoPanel);
        frmOceanlife.pack();
        frmOceanlife.setVisible(true);
    }
}

接下来,让我们引入更好的名字,并使用公开可用的图像,使代码更具可读性,更mre:

import java.awt.*;
import java.net.*;
import javax.swing.*;

public class Mainframe {

    private static final String STONE = "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/32x32/Circle_Red.png",
                        OCEAN ="https://media-gadventures.global.ssl.fastly.net/media-server/dynamic/blogs/posts/robin-wu/2014/12/PB110075.jpg";
    public Mainframe() {
        initialize();
    }

    private void initialize() {
        JFrame frmOceanlife = new JFrame();
        frmOceanlife.setTitle("OceanLife");
        frmOceanlife.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOceanlife.setLayout(new BoxLayout(frmOceanlife.getContentPane(), BoxLayout.PAGE_AXIS));

        JButton quitBtn = new JButton("Quit");
        quitBtn.addActionListener(e -> System.exit(0));
        JPanel quitPanel = new JPanel();
        quitPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        quitPanel.add(quitBtn);
        frmOceanlife.getContentPane().add(quitPanel);

        JPanel stonesPanel = new JPanel();
        frmOceanlife.getContentPane().add(stonesPanel);

        JButton insertBtn = new JButton("Insert");
        insertBtn.addActionListener(e -> {

            try {
                ImageIcon icon = new ImageIcon(new URL(STONE));
                JLabel stoneLbl = new JLabel(icon);
                stonesPanel.add(stoneLbl);
                frmOceanlife.revalidate();
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            }
        });

        JPanel insertPanel = new JPanel();
        insertPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        insertPanel.add(insertBtn);
        frmOceanlife.getContentPane().add(insertPanel);

        JPanel oceanPanel = new JPanel();
        oceanPanel.setBackground(Color.WHITE);
        oceanPanel.setLayout(new FlowLayout());
        oceanPanel.setPreferredSize(new Dimension(700,550));

        try {
            JLabel oceanLbl = new JLabel(new ImageIcon(new URL(OCEAN)));
            oceanPanel.add(oceanLbl);
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }

        frmOceanlife.getContentPane().add(oceanPanel);

        JLabel infoLabel = new JLabel("Welcome to Oceanlife - Your Ocean size is 600x450!");
        JPanel infoPanel = new JPanel();
        infoPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        infoPanel.add(infoLabel);
        frmOceanlife.getContentPane().add(infoPanel);
        
        frmOceanlife.pack();
        frmOceanlife.setVisible(true);
    }

    public static void main(String[] args) {
       //no change in main 
    }
}

并添加一些最后的修饰:

public class Mainframe {

    private static final String STONE = "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/32x32/Circle_Red.png",
                        OCEAN ="https://media-gadventures.global.ssl.fastly.net/media-server/dynamic/blogs/posts/robin-wu/2014/12/PB110075.jpg";

    private ImageIcon oceanIcon;

    public Mainframe() {
        initialize();
    }

    private void initialize() {
        JFrame frmOceanlife = new JFrame();
        frmOceanlife.setTitle("OceanLife");
        frmOceanlife.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOceanlife.setLayout(new BoxLayout(frmOceanlife.getContentPane(), BoxLayout.PAGE_AXIS));

        JButton quitBtn = new JButton("Quit");
        quitBtn.addActionListener(e -> System.exit(0));
        JPanel quitPanel = new JPanel();
        quitPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        quitPanel.add(quitBtn);
        frmOceanlife.getContentPane().add(quitPanel);

        JPanel stonesPanel = new JPanel();
        JLabel stoneLbl = new JLabel();
        stonesPanel.add(stoneLbl);
        frmOceanlife.getContentPane().add(stonesPanel);

        JButton insertBtn = new JButton("Insert");

        insertBtn.addActionListener(e -> {

            try {
                ImageIcon icon = new ImageIcon(new URL(STONE));
                stoneLbl.setIcon(icon);
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            }
        });

        JPanel insertPanel = new JPanel();
        insertPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        insertPanel.add(insertBtn);
        frmOceanlife.getContentPane().add(insertPanel);

        try {
            oceanIcon = new ImageIcon(new URL(OCEAN));
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }

        JLabel oceanLbl = new JLabel();
        oceanLbl.setIcon(oceanIcon);
        JPanel oceanPanel = new JPanel(){
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(oceanIcon.getIconWidth()+100, oceanIcon.getIconHeight());
            };
        };
        oceanPanel.add(oceanLbl);
        oceanPanel.setBackground(Color.WHITE);
        oceanPanel.setLayout(new GridBagLayout()); //center image in panel
        frmOceanlife.getContentPane().add(oceanPanel);

        JLabel infoLabel = new JLabel("Welcome to Oceanlife - Your Ocean size is "+oceanIcon+oceanIcon.getIconWidth()+
                "x"+oceanIcon.getIconHeight()+"!");
        JPanel infoPanel = new JPanel();
        infoPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        infoPanel.add(infoLabel);
        frmOceanlife.getContentPane().add(infoPanel);

        frmOceanlife.pack();
        frmOceanlife.setVisible(true);
    }

    public static void main(String[] args) {
      //no change in main
    }
}