背景 JSwing 图片加载异常
Background JSwing Image Loading Oddly
我似乎无法弄清楚如何在显示所有面板的情况下添加背景。
我尝试将 JFrame 内容窗格设置为带有 imageicon 的标签,并且框架确实显示了,只是没有像上面那样显示图像。
这是我用过的代码。
frame.setContentPane(new JLabel(new ImageIcon("res/Wallpaper.png")));
我使用的第二种尝试是将图像添加(未设置)到框架的内容窗格中。如上面第二张图片所示,这不起作用,它只显示面板但没有背景。代码在底部。
frame.getContentPane().add(new JLabel(new ImageIcon("res/Wallpaper.png")));
我尝试的第三次尝试是创建 JComponent 的子class 并覆盖 paintComponents 方法,然后将其对象设置为内容窗格。这不起作用,而是让我的屏幕变黑。
这是我使用的代码,class 代码在这个 link Setting background images in JFrame 的第一个答案中。结果就是这个post.
的第3张图
File img = new File("res/Wallpaper.png");
BufferedImage myImage;
try {
myImage = ImageIO.read(img);
frame.setContentPane(new ImagePanel(myImage));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我尝试的第四次尝试是将图片添加到填满屏幕的主面板中。这根本不起作用,而是将图像分成两半,因此屏幕的一半有图像,另一半没有。
这是我在第 4 次尝试中使用的代码。结果是顶部的倒数第 4 个图像。
BufferedImage myPicture;
try {
myPicture = ImageIO.read(new File("res/Wallpaper.png"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
pMain.add(picLabel);
} catch (IOException e) {
e.printStackTrace();
}
我不确定为什么 JPanel 没有出现。
我知道在第一个示例中,当您将框架设置为 JLabel 时,它会为它提供空布局,但这是我能找到的显示图像的唯一方法。
我想以某种方式将面板添加到具有该背景的框架顶部,但在阅读了无数线程后我找不到如何做。
如果有人发现了,请 post 代码并在可能的情况下进行解释。我还有 class 获取系统 class 主题,将其设置为计算机正在使用的主题。前任。我使用的是 windows 操作系统,所以它显示的有点像我的操作系统。
此线程不是重复的。在其他线程中,它们只有一个框架,但在我的线程中,由于某些特定原因,我有几个面板没有显示。
编辑:我不知道怎么回事,我尝试使用这个线程 Setting background images in JFrame 但我没有运气。
我尝试了它给我的第一种方法,然后没有显示任何东西,它什么也没显示,没有图片,没有组件,什么都没有。如果您需要更多信息,我有:屏幕底部的 4 个 JPanel,我的 window 周围也有一个边框,但没有出现在第一个 window 中。我的面板周围也有边框。
所以我尝试在内容窗格中设置第一种方法,图像加载但所有组件都消失了。
第二种方法我试过将它添加到内容窗格中,但还是没有成功,我得到了一个没有背景的面板。
我试过的第三种方法是创建一个单独的 class 并覆盖 paintComponent 方法并将图像添加到它的构造函数然后将 class 的这个对象放入 setcontentPane()帧的参数。根本不起作用,我得到的只是一个空白框。
我在框架中使用的代码:
public class LoginScreen {
JCheckBox remember_User;
JButton login, create_Account, forums, faqs;
Border whiteLine;
JTextField userField;
JFormattedTextField passField;
private void createView() {
// Created essential details for the frame
JFrame frame = new JFrame();
frame.setTitle("Name of the game");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Defining panels and a constraint on the bottomPanel.
// More info - Total amt of panels: 5
// pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in
// bottomPanel
// bottom panel is in pMain
// Giving panels some attributes like backgrounds and borders
JPanel pMain = new JPanel(new BorderLayout());
pMain.setBorder(BorderFactory.createMatteBorder(3, 3, 6, 3,
Color.DARK_GRAY));
frame.getContentPane().add(pMain);
whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setBackground(Color.green);
pInfo.setPreferredSize(new Dimension(200, 100));
pInfo.setBorder(whiteLine);
JPanel bottomCompPanel = new JPanel(new GridBagLayout());
GridBagConstraints bGBC = new GridBagConstraints();
bGBC.gridx = 0;
bGBC.gridy = 0;
bGBC.insets = new Insets(0, 20, 0, 0);
bGBC.anchor = GridBagConstraints.PAGE_END;
bottomCompPanel.add(pLogin, bGBC);
bGBC.gridx++;
bottomCompPanel.add(pInfo, bGBC);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.add(bottomCompPanel);
pMain.add(bottomPanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String[] args) {
LoginScreen login = new LoginScreen();
login.createView();
}
}
POST 更新 2:这是我使用 @peeskillet 的第一种方法使用的代码。它有点工作,但它给了我与第三张照片相同的结果,一张截断的照片。 P.S 我最后将底部的面板添加到我的 JLabel。
private void createView() {
//Created essential details for the frame
JFrame frame = new JFrame();
frame.setTitle("Name of the game");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JLabel background = new JLabel(new ImageIcon("res/Wallpaper.png"));
background.setLayout(new BorderLayout());
frame.setContentPane(background);
//Defining panels and a constraint on the bottomPanel.
//More info - Total amt of panels: 5
//pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in bottomPanel
//bottom panel is in pMain
//Giving panels some attributes like backgrounds and borders
whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400,250));
pLogin.setBorder(whiteLine);
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setBackground(Color.green);
pInfo.setPreferredSize(new Dimension(200,100));
pInfo.setBorder(whiteLine);
JPanel bottomCompPanel = new JPanel(new GridBagLayout());
GridBagConstraints bGBC = new GridBagConstraints();
bGBC.gridx = 0;
bGBC.gridy = 0;
bGBC.insets = new Insets(0,20,0,0);
bGBC.anchor = GridBagConstraints.PAGE_END;
bottomCompPanel.add(pLogin, bGBC);
bGBC.gridx++;
bottomCompPanel.add(pInfo, bGBC);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.add(bottomCompPanel);
background.add(bottomPanel, BorderLayout.SOUTH);
您可以试试 JLayeredPane 和 setOpaque(boolean) 方法。
代码:
public class BackgroundImageTest{
private JFrame frame;
public BackgroundImageTest() {
frame = new JFrame("Background Image Frame");
// set frame properties
JPanel panel = new JPanel(new FlowLayout());
panel.setOpaque(false);
JButton btn = new JButton("Change Background");
panel.add(btn);
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
setBackgroundImage(getImage(new File("Wallpaper2.png")));
}
});
JPanel main = (JPanel) frame.getContentPane();
main.setLayout(new FlowLayout());
main.add(panel);
main.setOpaque(false);
setBackgroundImage(getImage(new File("Wallpaper.png")));
frame.setVisible(true);
}
private Image getImage(File imageFile) {
BufferedImage image = null;
try {
image = ImageIO.read(imageFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return image;
}
private void setBackgroundImage(Image img) {
if(img == null) return;
ImageIcon ii = new ImageIcon(img);
JLabel lblBG = new JLabel(ii);
lblBG.setName("BackgroundImageLabel");
JLayeredPane layeredPane = frame.getLayeredPane();
Component[] comps = layeredPane.getComponentsInLayer(new Integer(Integer.MIN_VALUE));
for (int i = 0; i < comps.length; i++) {
System.out.println(comps[i].getName());
if (comps[i] instanceof JLabel && comps[i].getName().equals("BackgroundImageLabel")){
layeredPane.remove(comps[i]);
break;
}
}
layeredPane.add(lblBG, new Integer(Integer.MIN_VALUE));
lblBG.setBounds(0,0,ii.getIconWidth(), ii.getIconHeight());
}
}
"I tried to set the JFrame content pane as a label with an imageicon"
您需要在 JLabel
上设置布局。默认情况下将为空。
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel background = new JLabel(new ImageIcon(new URL(IMG)));
background.setLayout(new GridBagLayout());
background.add(loginPanel());
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel loginPanel() {
Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {}
});
}
}
"I've tried is to create a subclass of JComponent and Override the paintComponents method then setan object of it as the contentpane"
应该是paintComponent
(不是"s"),但是就像JLabel
一样,你需要设置布局。 JComponent
默认布局为空。绘画时还需要给它一个偏好的尺寸。
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
background.setLayout(new GridBagLayout());
background.add(loginPanel());
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel loginPanel() {
Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
class BackgroundComponent extends JComponent {
public ImageIcon background;
public BackgroundComponent(ImageIcon background) {
this.background = background;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(background.getIconWidth(), background.getIconHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getImage(),
0, 0,
background.getIconWidth(),
background.getIconHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {}
});
}
}
使用(扩展)JPanel
而不是 JComponent
会很相似,除了 JPanel
有默认布局 FlowLayout
.
更新
要获得所需的布局,您需要使用不同的布局管理器。我使用的组合是
Outer (main panel) -- BorderLayout
Bottom (bottom panel) -- BoxLayout inside (south) of outer layout
对于 BorderLayout,您需要确保面板不透明 属性 设置为 false,因为 BorderLayout 会拉伸面板并覆盖背景。
对于 BoxLayout,您需要确保设置最大尺寸和首选尺寸
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private final Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
background.setLayout(new BorderLayout());
background.add(bottomPanel(), BorderLayout.SOUTH);
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel bottomPanel() {
JPanel bottomPanel = new JPanel();
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
BoxLayout layout = new BoxLayout(bottomPanel, BoxLayout.X_AXIS);
bottomPanel.setLayout(layout);
bottomPanel.setOpaque(false);
bottomPanel.add(Box.createHorizontalGlue());
bottomPanel.add(loginPanel());
bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
bottomPanel.add(infoPanel());
return bottomPanel;
}
private JPanel infoPanel() {
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setAlignmentY(Component.BOTTOM_ALIGNMENT);
pInfo.setBackground(Color.green);
pInfo.setMaximumSize(new Dimension(200, 100));
pInfo.setPreferredSize(new Dimension(200, 100));
pInfo.setBorder(whiteLine);
return pInfo;
}
private JPanel loginPanel() {
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setAlignmentY(Component.BOTTOM_ALIGNMENT);
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setMaximumSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
class BackgroundComponent extends JComponent {
public ImageIcon background;
public BackgroundComponent(ImageIcon background) {
this.background = background;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(background.getIconWidth(), background.getIconHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getImage(),
0, 0,
background.getIconWidth(),
background.getIconHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {
}
});
}
}
有关使用不同布局管理器的详细信息,请参阅
- Laying Out Components Within a Container
我似乎无法弄清楚如何在显示所有面板的情况下添加背景。
我尝试将 JFrame 内容窗格设置为带有 imageicon 的标签,并且框架确实显示了,只是没有像上面那样显示图像。
这是我用过的代码。
frame.setContentPane(new JLabel(new ImageIcon("res/Wallpaper.png")));
我使用的第二种尝试是将图像添加(未设置)到框架的内容窗格中。如上面第二张图片所示,这不起作用,它只显示面板但没有背景。代码在底部。
frame.getContentPane().add(new JLabel(new ImageIcon("res/Wallpaper.png")));
我尝试的第三次尝试是创建 JComponent 的子class 并覆盖 paintComponents 方法,然后将其对象设置为内容窗格。这不起作用,而是让我的屏幕变黑。
这是我使用的代码,class 代码在这个 link Setting background images in JFrame 的第一个答案中。结果就是这个post.
的第3张图 File img = new File("res/Wallpaper.png");
BufferedImage myImage;
try {
myImage = ImageIO.read(img);
frame.setContentPane(new ImagePanel(myImage));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我尝试的第四次尝试是将图片添加到填满屏幕的主面板中。这根本不起作用,而是将图像分成两半,因此屏幕的一半有图像,另一半没有。
这是我在第 4 次尝试中使用的代码。结果是顶部的倒数第 4 个图像。
BufferedImage myPicture;
try {
myPicture = ImageIO.read(new File("res/Wallpaper.png"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
pMain.add(picLabel);
} catch (IOException e) {
e.printStackTrace();
}
我不确定为什么 JPanel 没有出现。
我知道在第一个示例中,当您将框架设置为 JLabel 时,它会为它提供空布局,但这是我能找到的显示图像的唯一方法。
我想以某种方式将面板添加到具有该背景的框架顶部,但在阅读了无数线程后我找不到如何做。
如果有人发现了,请 post 代码并在可能的情况下进行解释。我还有 class 获取系统 class 主题,将其设置为计算机正在使用的主题。前任。我使用的是 windows 操作系统,所以它显示的有点像我的操作系统。
此线程不是重复的。在其他线程中,它们只有一个框架,但在我的线程中,由于某些特定原因,我有几个面板没有显示。
编辑:我不知道怎么回事,我尝试使用这个线程 Setting background images in JFrame 但我没有运气。
我尝试了它给我的第一种方法,然后没有显示任何东西,它什么也没显示,没有图片,没有组件,什么都没有。如果您需要更多信息,我有:屏幕底部的 4 个 JPanel,我的 window 周围也有一个边框,但没有出现在第一个 window 中。我的面板周围也有边框。
所以我尝试在内容窗格中设置第一种方法,图像加载但所有组件都消失了。
第二种方法我试过将它添加到内容窗格中,但还是没有成功,我得到了一个没有背景的面板。
我试过的第三种方法是创建一个单独的 class 并覆盖 paintComponent 方法并将图像添加到它的构造函数然后将 class 的这个对象放入 setcontentPane()帧的参数。根本不起作用,我得到的只是一个空白框。
我在框架中使用的代码:
public class LoginScreen {
JCheckBox remember_User;
JButton login, create_Account, forums, faqs;
Border whiteLine;
JTextField userField;
JFormattedTextField passField;
private void createView() {
// Created essential details for the frame
JFrame frame = new JFrame();
frame.setTitle("Name of the game");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Defining panels and a constraint on the bottomPanel.
// More info - Total amt of panels: 5
// pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in
// bottomPanel
// bottom panel is in pMain
// Giving panels some attributes like backgrounds and borders
JPanel pMain = new JPanel(new BorderLayout());
pMain.setBorder(BorderFactory.createMatteBorder(3, 3, 6, 3,
Color.DARK_GRAY));
frame.getContentPane().add(pMain);
whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setBackground(Color.green);
pInfo.setPreferredSize(new Dimension(200, 100));
pInfo.setBorder(whiteLine);
JPanel bottomCompPanel = new JPanel(new GridBagLayout());
GridBagConstraints bGBC = new GridBagConstraints();
bGBC.gridx = 0;
bGBC.gridy = 0;
bGBC.insets = new Insets(0, 20, 0, 0);
bGBC.anchor = GridBagConstraints.PAGE_END;
bottomCompPanel.add(pLogin, bGBC);
bGBC.gridx++;
bottomCompPanel.add(pInfo, bGBC);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.add(bottomCompPanel);
pMain.add(bottomPanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String[] args) {
LoginScreen login = new LoginScreen();
login.createView();
}
}
POST 更新 2:这是我使用 @peeskillet 的第一种方法使用的代码。它有点工作,但它给了我与第三张照片相同的结果,一张截断的照片。 P.S 我最后将底部的面板添加到我的 JLabel。
private void createView() {
//Created essential details for the frame
JFrame frame = new JFrame();
frame.setTitle("Name of the game");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JLabel background = new JLabel(new ImageIcon("res/Wallpaper.png"));
background.setLayout(new BorderLayout());
frame.setContentPane(background);
//Defining panels and a constraint on the bottomPanel.
//More info - Total amt of panels: 5
//pLogin and pInfo are in the bottomCompPanel and bottomCompPanel is in bottomPanel
//bottom panel is in pMain
//Giving panels some attributes like backgrounds and borders
whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400,250));
pLogin.setBorder(whiteLine);
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setBackground(Color.green);
pInfo.setPreferredSize(new Dimension(200,100));
pInfo.setBorder(whiteLine);
JPanel bottomCompPanel = new JPanel(new GridBagLayout());
GridBagConstraints bGBC = new GridBagConstraints();
bGBC.gridx = 0;
bGBC.gridy = 0;
bGBC.insets = new Insets(0,20,0,0);
bGBC.anchor = GridBagConstraints.PAGE_END;
bottomCompPanel.add(pLogin, bGBC);
bGBC.gridx++;
bottomCompPanel.add(pInfo, bGBC);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.add(bottomCompPanel);
background.add(bottomPanel, BorderLayout.SOUTH);
您可以试试 JLayeredPane 和 setOpaque(boolean) 方法。
代码:
public class BackgroundImageTest{
private JFrame frame;
public BackgroundImageTest() {
frame = new JFrame("Background Image Frame");
// set frame properties
JPanel panel = new JPanel(new FlowLayout());
panel.setOpaque(false);
JButton btn = new JButton("Change Background");
panel.add(btn);
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
setBackgroundImage(getImage(new File("Wallpaper2.png")));
}
});
JPanel main = (JPanel) frame.getContentPane();
main.setLayout(new FlowLayout());
main.add(panel);
main.setOpaque(false);
setBackgroundImage(getImage(new File("Wallpaper.png")));
frame.setVisible(true);
}
private Image getImage(File imageFile) {
BufferedImage image = null;
try {
image = ImageIO.read(imageFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return image;
}
private void setBackgroundImage(Image img) {
if(img == null) return;
ImageIcon ii = new ImageIcon(img);
JLabel lblBG = new JLabel(ii);
lblBG.setName("BackgroundImageLabel");
JLayeredPane layeredPane = frame.getLayeredPane();
Component[] comps = layeredPane.getComponentsInLayer(new Integer(Integer.MIN_VALUE));
for (int i = 0; i < comps.length; i++) {
System.out.println(comps[i].getName());
if (comps[i] instanceof JLabel && comps[i].getName().equals("BackgroundImageLabel")){
layeredPane.remove(comps[i]);
break;
}
}
layeredPane.add(lblBG, new Integer(Integer.MIN_VALUE));
lblBG.setBounds(0,0,ii.getIconWidth(), ii.getIconHeight());
}
}
"I tried to set the JFrame content pane as a label with an imageicon"
您需要在 JLabel
上设置布局。默认情况下将为空。
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel background = new JLabel(new ImageIcon(new URL(IMG)));
background.setLayout(new GridBagLayout());
background.add(loginPanel());
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel loginPanel() {
Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {}
});
}
}
"I've tried is to create a subclass of JComponent and Override the paintComponents method then setan object of it as the contentpane"
应该是paintComponent
(不是"s"),但是就像JLabel
一样,你需要设置布局。 JComponent
默认布局为空。绘画时还需要给它一个偏好的尺寸。
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
background.setLayout(new GridBagLayout());
background.add(loginPanel());
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel loginPanel() {
Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
class BackgroundComponent extends JComponent {
public ImageIcon background;
public BackgroundComponent(ImageIcon background) {
this.background = background;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(background.getIconWidth(), background.getIconHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getImage(),
0, 0,
background.getIconWidth(),
background.getIconHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {}
});
}
}
使用(扩展)JPanel
而不是 JComponent
会很相似,除了 JPanel
有默认布局 FlowLayout
.
更新
要获得所需的布局,您需要使用不同的布局管理器。我使用的组合是
Outer (main panel) -- BorderLayout
Bottom (bottom panel) -- BoxLayout inside (south) of outer layout
对于 BorderLayout,您需要确保面板不透明 属性 设置为 false,因为 BorderLayout 会拉伸面板并覆盖背景。
对于 BoxLayout,您需要确保设置最大尺寸和首选尺寸
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.Border;
public class BackgroundImage {
private static final String IMG = "http://i.stack.imgur.com/JEoYs.jpg";
private final Border whiteLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
private void init() throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent background = new BackgroundComponent(new ImageIcon(new URL(IMG)));
background.setLayout(new BorderLayout());
background.add(bottomPanel(), BorderLayout.SOUTH);
f.setContentPane(background);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel bottomPanel() {
JPanel bottomPanel = new JPanel();
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
BoxLayout layout = new BoxLayout(bottomPanel, BoxLayout.X_AXIS);
bottomPanel.setLayout(layout);
bottomPanel.setOpaque(false);
bottomPanel.add(Box.createHorizontalGlue());
bottomPanel.add(loginPanel());
bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
bottomPanel.add(infoPanel());
return bottomPanel;
}
private JPanel infoPanel() {
JPanel pInfo = new JPanel(new GridBagLayout());
pInfo.setAlignmentY(Component.BOTTOM_ALIGNMENT);
pInfo.setBackground(Color.green);
pInfo.setMaximumSize(new Dimension(200, 100));
pInfo.setPreferredSize(new Dimension(200, 100));
pInfo.setBorder(whiteLine);
return pInfo;
}
private JPanel loginPanel() {
JPanel pLogin = new JPanel(new GridBagLayout());
pLogin.setAlignmentY(Component.BOTTOM_ALIGNMENT);
pLogin.setBackground(Color.cyan);
pLogin.setPreferredSize(new Dimension(400, 250));
pLogin.setMaximumSize(new Dimension(400, 250));
pLogin.setBorder(whiteLine);
return pLogin;
}
class BackgroundComponent extends JComponent {
public ImageIcon background;
public BackgroundComponent(ImageIcon background) {
this.background = background;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(background.getIconWidth(), background.getIconHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getImage(),
0, 0,
background.getIconWidth(),
background.getIconHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new BackgroundImage().init();
} catch (Exception ex) {
}
});
}
}
有关使用不同布局管理器的详细信息,请参阅
- Laying Out Components Within a Container