如何使 JButtons 在以图像为背景的 JPanel 上可见

How to make JButtons visible on a JPanel with an image as background

我用图像作为背景制作了 JPanel。但是在第一次加载 JPanel 时,其余添加的组件但图像不可见。将鼠标悬停在图像上后,按钮就会变得可见。如何在加载面板时使 JButtons 与作为背景的图像一起可见。

这是我的代码片段:

    contentPane = new JPanel();
    contentPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    homePanel.setBounds(10, 11, 959, 620);
    homePanel.setLayout(null);

    JPanel wizardPanel = new JPanel();
    wizardPanel.setBounds(10, 295, 545, 336);
    wizardPanel.setLayout(null);
    homePanel.add(wizardPanel);

    JLabel backgroundLabel;
    try {
        backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(new File("images/nature.jpg"))));
        backgroundLabel.setBounds(0, 0, 545, 336);
        wizardPanel.add(backgroundLabel);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    JButton btnNewButton = new JButton("New button");
    btnNewButton.setBounds(309, 95, 89, 23);
    wizardPanel.add(btnNewButton);

    JButton btnNewButton_1 = new JButton("New button");
    btnNewButton_1.setBounds(309, 150, 89, 23);
    wizardPanel.add(btnNewButton_1);

    JButton btnNewButton_2 = new JButton("New button");
    btnNewButton_2.setBounds(309, 212, 89, 23);
    wizardPanel.add(btnNewButton_2);

一个快速的解决方案可能是直接将 JFrame 内容窗格设置为图像并将您的组件添加到此 JFrame 的内容窗格。假设您的代码来自 JFrame class 的正文。我的建议大致是这样的:

        JRootPane rootpane = new JRootPane();
        JPanel contentPane = new JPanel();
        contentPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
        rootpane.setContentPane(contentPane);
        contentPane.setLayout(null);

        JPanel homePanel = new JPanel();
        homePanel.setBounds(10, 11, 959, 620);
        homePanel.setLayout(null);

        JRootPane wizardPanel = new JRootPane();
        wizardPanel.setBounds(10, 295, 545, 336);
        wizardPanel.setLayout(null);

        JLabel backgroundLabel;
        try {
            File f = new File("D:\work\eclipse\workspace_eclipse_4.4.1\trialExamples\src\main\images\nature.jpg");
            backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(f)));
            backgroundLabel.setBounds(0, 0, 545, 336);
            wizardPanel.setContentPane(backgroundLabel);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        JButton btnNewButton = new JButton("New button");
        btnNewButton.setBounds(309, 95, 89, 23);
        wizardPanel.getContentPane().add(btnNewButton);

        JButton btnNewButton_1 = new JButton("New button");
        btnNewButton_1.setBounds(309, 150, 89, 23);
        wizardPanel.getContentPane().add(btnNewButton_1);

        JButton btnNewButton_2 = new JButton("New button");
        btnNewButton_2.setBounds(309, 212, 89, 23);
        wizardPanel.getContentPane().add(btnNewButton_2);

        homePanel.add(wizardPanel.getContentPane());

        add(homePanel);

这太疯狂了!!我通过将 JButtons 初始化代码块放在它工作的图像加载部分上方来让它工作.....

     package demo;

     import java.awt.EventQueue;
     import java.io.File;
     import java.io.IOException;

     import javax.imageio.ImageIO;
     import javax.swing.ImageIcon;
     import javax.swing.JButton;
     import javax.swing.JFrame;
     import javax.swing.JLabel;
     import javax.swing.JPanel;
     import javax.swing.SwingUtilities;
     import javax.swing.UIManager;
     import javax.swing.border.EmptyBorder;

public class demoframe extends JFrame {

/**
 * 
 */
private static final long serialVersionUID = 1436190962490331120L;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                demoframe frame = new demoframe();

                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                SwingUtilities.updateComponentTreeUI(frame);

                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public demoframe() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 988, 678);
    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JPanel panel = new JPanel();
    panel.setBounds(10, 11, 501, 361);
    contentPane.add(panel);
    panel.setLayout(null);

    JButton btnNewButton = new JButton("New button");
    btnNewButton.setBounds(322, 112, 89, 23);
    panel.add(btnNewButton);

    JButton button = new JButton("New button");
    button.setBounds(322, 172, 89, 23);
    panel.add(button);

    JButton button_1 = new JButton("New button");
    button_1.setBounds(322, 244, 89, 23);
    panel.add(button_1);

    JLabel backgroundLabel;
    try {
        backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(new File("images/nature.jpg"))));
        backgroundLabel.setBounds(0, 0, 501, 361);
        panel.add(backgroundLabel);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }



    JPanel panel_1 = new JPanel();
    panel_1.setBounds(521, 11, 441, 361);
    contentPane.add(panel_1);

    JPanel panel_2 = new JPanel();
    panel_2.setBounds(10, 383, 952, 246);
    contentPane.add(panel_2);

}   
 }

将按钮放在标签上是个坏主意。更好的方法是将图像绘制为面板背景或使用 JLayer。这是第一个解决方案的示例:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import java.util.Objects;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class JImagePanel extends JPanel {

    private final Image image;

    private boolean scale;

    public JImagePanel(Image anImage) {
        image = Objects.requireNonNull(anImage);
    }

    public JImagePanel(Image anImage, LayoutManager aLayout) {
        super(aLayout);
        image = Objects.requireNonNull(anImage);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        final Image toDraw = scale? image.getScaledInstance(getWidth(), getHeight(), Image.SCALE_SMOOTH) : image;
        g.drawImage(toDraw, 0, 0, this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        } else {
            return new Dimension(image.getWidth(this), image.getHeight(this));
        }
    }

    public boolean isScale() {
        return scale;
    }

    public void setScale(boolean scale) {
        this.scale = scale;
    }


    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    final JImagePanel p = 
                            new JImagePanel(ImageIO.read(JImagePanel.class.getResource("myImage.png")), new FlowLayout());
                    p.setScale(true);
                    p.add(new JButton("Button"));
                    final JFrame frm = new JFrame("Image test");
                    frm.add(p);
                    frm.pack();
                    frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                    frm.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}