如何使 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();
}
}
});
}
}
我用图像作为背景制作了 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();
}
}
});
}
}