I have a JPanel using GridLayout which contains 6 JLabels. If i add only this JPanel to a JFrame everything works fine, but when I add it on BorderLayout.WEST (along with 3 other panels on EAST, CENTER and SOUTH) it just won't show up.
Here's the code I'm using:
public class SwingView extends JFrame {
private DeckLabel[] terrains={
new DeckLabel(new ImageIcon("assets/graphics/mountains.png"),0),
new DeckLabel(new ImageIcon("assets/graphics/planes.png"),1),
new DeckLabel(new ImageIcon("assets/graphics/forest.png"),2),
new DeckLabel(new ImageIcon("assets/graphics/fields.png"),3),
new DeckLabel(new ImageIcon("assets/graphics/swamp.png"),4),
new DeckLabel(new ImageIcon("assets/graphics/desert.png"),5)};
public SwingView() {
super("Frame");
this.setSize(680, 740);
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Utilities.center(this);
// panels
//terrains
JPanel terrainsPanel = new JPanel();
terrainsPanel.setSize(100, 640);
terrainsPanel.setLayout(new GridLayout(6, 1));
//map
JPanel mapPanel = new JPanel();
mapPanel.setSize(480, 640);
//info
JPanel infoPanel = new JPanel();
infoPanel.setSize(100, 640);
//chat
JPanel chatPanel = new JPanel();
chatPanel.setSize(680, 100);
chatView.setEditable(false);
txtChat.addKeyListener(this);
chatPanel.add(txtChat, BorderLayout.SOUTH);
chatPanel.add(chatView);
// terrains
for (int i = 0; i < 6; i++) {
terrainsPanel.add(terrains[i]);
}
this.add(mapPanel,BorderLayout.CENTER);
this.add(terrainsPanel, BorderLayout.WEST);
this.add(infoPanel, BorderLayout.EAST);
this.add(chatPanel, BorderLayout.SOUTH);
}
}
public class DeckLabel extends JLabel{
private Image image;
private int index;
public DeckLabel(ImageIcon icon,int index){
this.image=icon.getImage();
this.index=index;
}
#Override
public void paint(Graphics g){
BufferedImage bi = new BufferedImage(85, 78,
BufferedImage.TYPE_INT_RGB);
Graphics2D tg = bi.createGraphics();
tg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// draw basic tile
tg.drawImage(image, 0, 0, null);
g.drawImage(bi,0,0,null);
}
}
Thank you
plenty issues
use JPanel instead of JLabel,
override paintComponent instead of paint for JLabel/JPanel/Swing JComponents
1st. code line should be super.pain(Component), or for JPanel to stop repainting (mouse and key events)
or to use JLabel.setIcon for Image
something wrong came from Utilities.center(this);, did you tried to layout container
FlowLayout is default LayoutManager for JPanel, then chatPanel.add(txtChat, BorderLayout.SOUTH); is ignored without missing code line chatPanel.setLayout(new BorderLayout)
txtChat.addKeyListener(this); I'm hope that isn't some of JTextComponents, if yes then to use DocumentListener/Filter instead
As your DeckLabel class sets no text for the JLabel, the component has no minimum and preferred size. So the border layout will assume a size of 0 -> component not visible. The same happens when you use a JPanel.
Call setPreferredSize(), setMinimumSize() or override getMinimumSize()/getPreferredSize().
Related
Panel Alignment Practice
Panel alignment practice. Each panel is a color. I haven't been able to resize using new Dimension() or flexibly manipulate the panels. I've tried frm.setLayout(null) with setBounds() and GridBagConstraints.
frm = new JFrame();
frmLayout = new BorderLayout();
frmLayout.layoutContainer(frm.getContentPane());
mainPnl = new MainPanel();
sP = new SecondPanel();
tP = new ThirdPanel();
getContentPane().add(mainPnl, BorderLayout.WEST);
getContentPane().add(sP, BorderLayout.EAST);
getContentPane().add(tP, BorderLayout.SOUTH);
To change the LayoutManager of a JPanel use :
frm.getContentPane().setLayout(frmLayout);
Don’t set it to null, a null-layout isn’t resized with the JFrame.
I was able to arrange the panels.
It seems if I add panels to a main panel setBounds() works. I'm probably violating all of your favorite swing conventions but hey, I'll learn just like you all at some point. Only issue with setBounds() so far is resizing the window. getWidth() or getHeight() cause the panel to disappear.
public class MainPanel extends JPanel {
SecondPanel sP;
ThirdPanel tP;
FourthPanel fP;
public MainPanel()
{
setBackground(Color.ORANGE);
setLayout(null);
sP = new SecondPanel();
sP.setBounds(0, 0, 90, 90);
tP = new ThirdPanel();
tP.setBounds(90, 0, 410, 90);
fP = new FourthPanel();
fP.setBounds(0, 400, 500, 100);
add(sP);
add(tP);
add(fP);
}
}
I have a strange white stripe (see below) appearing on top of my background image. The code is quite simple. How to get rid of the white stripe?
//Graphics side of the game
public class GUI extends JFrame {
private final int larghezza = 1280;
private final int altezza = 720;
private final String name = "Sette e Mezzo";
private final ImageIcon backgroundImage;
private JLabel bgImageLabel;
private JPanel backgroundPanel, borderLayoutPanel, topGridLayout, botGridLayout;
public GUI () {
backgroundImage = new ImageIcon ("assets/background.png");
bgImageLabel = new JLabel (backgroundImage);
//Panels
borderLayoutPanel = new JPanel (new BorderLayout ());
topGridLayout = new JPanel (new GridLayout (1, 3));
botGridLayout = new JPanel (new GridLayout (1, 3));
backgroundPanel = new JPanel ();
backgroundPanel.add (bgImageLabel);
//Frame
this.setName (name);
this.setPreferredSize (new Dimension(larghezza, altezza));
this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Adding to frame and panels
borderLayoutPanel.add (topGridLayout, BorderLayout.NORTH);
borderLayoutPanel.add (botGridLayout, BorderLayout.SOUTH);
this.add (borderLayoutPanel);
this.add (backgroundPanel);
this.pack ();
this.setLocationRelativeTo (null);
this.setVisible (true);
}
}
Don't use setPreferredSize() when you really mean to override getPreferredSize(). In this case, the specified Dimension probably doesn't quite match the size of "assets/background.png". This allows some portion of another panel to show, perhaps backgroundPanel.
In the example below,
The default layout of JPanel is FlowLayout, which has a "default 5-unit horizontal and vertical gap." A touch of Color.blue makes the gap stand out; resize the enclosing frame to see the behavior.
As the default layout of JFrame is BorderLayout, you may not need borderLayoutPanel at all.
Because the two GridLayout panels have no content, they remain invisible. Add content to each or override getPreferredSize() in each to see the effect.
Construct and manipulate Swing GUI objects only on the event dispatch thread.
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class GUI {
private static final String TITLE = "Title";
private static ImageIcon IMAGE_ICON;
private void display() {
//Panels
JPanel topGridLayout = new JPanel(new GridLayout(1, 3));
JPanel botGridLayout = new JPanel(new GridLayout(1, 3));
JPanel backgroundPanel = new JPanel();
backgroundPanel.setBackground(Color.blue);
backgroundPanel.add(new JLabel(IMAGE_ICON));
//Frame
JFrame f = new JFrame(TITLE);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add components
f.add(topGridLayout, BorderLayout.NORTH);
f.add(backgroundPanel);
f.add(botGridLayout, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) throws Exception {
IMAGE_ICON = new ImageIcon(new URL("http://i.imgur.com/mowekvC.jpg"));
EventQueue.invokeLater(new GUI()::display);
}
}
I am trying to paint two squares of defined size, one located next to another in a row, using paintComponent() method of JPanel.
Here what I tried so far:
1. BorderLayout
I tried to draw each square in a separate subclass of JPanel, and then add these JPanels to a JFrame.
Result: squares are squashed to the opposite sides of JPanel: height is as expected but width is minimal.
JFrame frame = new JFrame();
GreenPanel greenPanel = new GreenPanel();
frame.getContentPane().add(BorderLayout.WEST, greenPanel);
BluePanel bluePanel = new BluePanel();
frame.getContentPane().add(BorderLayout.EAST, bluePanel);
frame.setSize(500, 350);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
class GreenPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, 100, 100);
}
}
class BluePanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
2. FlowLayout
I tried to add my "children" JPanels with painted squares to a "parent" JPane and then call JFrame.setContentPane(JPanel).
Result: squares are painted in top-center region as tiny squares.
JFrame frame = new JFrame();
JPanel outerPanel = new JPanel();
frame.setContentPane(outerPanel);
GreenPanel greenPanel = new GreenPanel();
outerPanel.add(greenPanel);
BluePanel bluePanel = new BluePanel();
outerPanel.add(bluePanel);
frame.setSize(500, 350);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
class GreenPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, 100, 100);
}
}
class BluePanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
What am I doing wrong? Is there any way I can force layout managers to respect the size of the squares painted with paintComponent() ?
Make the following changes. See comments for explanations.
JFrame frame = new JFrame();
//add layout manager. You can achieve the desired layout
//with GridLayout, Box layout and others
frame.getContentPane().setLayout(new GridLayout(1,2));
GreenPanel greenPanel = new GreenPanel();
//set preferred size to the panel
greenPanel.setPreferredSize(new Dimension(100,100));
frame.add(greenPanel);
BluePanel bluePanel = new BluePanel();
//set preferred size to the panel
bluePanel.setPreferredSize(new Dimension(100,100));
frame.getContentPane().add(bluePanel);
//let the frame adapt to the panels size
//frame.setSize(500, 350);
frame.validate();
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Don't hesitate to ask for clarifications as needed.
(BTW overriding paintComponent(Graphics g) is not really needed. You could simply set preferred size and color to each JPanel)
I am creating a simple program in which I want to display an Image and a button.So I've created a JFrame.
This JFrame contains tow JPanel and one of the panels contains JButton and the other panel contains my image. But image is not displaying in the panel. When I add image to the JFrame, it is displaying normally. Please help with the following code!
main() method:
public class NewClass2 {
public static void main(String args[]){
EventQueue.invokeLater(new Runnable(){
public void run(){
JFrame frm = new JFrm();
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(500,500);
}
});
}
}
JFrm class which initialize JFrame:
class JFrm extends JFrame{
JButton button;
JPanel panel0,panel1;
JFrm(){
panel0 = new JPanel();
panel1 = new JPanel();
button = new JButton("Start");
button.setPreferredSize(new Dimension(100, 30));
panel0.add(button);
panel1.add(new ImageComponent()); //adding image component to panel1 is not working
//add(new ImageComponent()); //adding image component to the frame is working ..
add(panel1,BorderLayout.PAGE_START);
add(panel0,BorderLayout.PAGE_END);
}
}
ImageComponent class which adds the image:
class ImageComponent extends JComponent{
Image img;
ImageComponent(){
img = new ImageIcon("C:\\Users\\Kaushal28\\Desktop\\Aqua-Ball-icon.png").getImage();
}
#Override
public void paint(Graphics g){
g.drawImage(img, 100,100 , null);
}
}
How can I add image to JPanel?
You did not set a size for your custom JComponent so it'll be squished by the LayoutManager to zero size. Use setPreferredSize() to set whatever size seems suitable.
ImageComponent(){
ImageIcon temp = new ImageIcon("test.png");
img = temp.getImage();
setPreferredSize(new Dimension(temp.getIconWidth(),temp.getIconHeight()));
}
#Override
public void paint(Graphics g){
g.drawImage(img, 0,0 , null);
}
Consider wrapping the image in a JLabel before adding it to the JPanel.
See Display a jpg image on a JPanel
class JFrm extends JFrame{
JButton button;
JPanel panel0, panel1;
JFrm(){
panel0 = new JPanel();
panel1 = new JPanel();
button = new JButton("Start");
button.setPreferredSize(new Dimension(100, 30));
panel0.add(button);
ImageIcon image = new ImageIcon("C:\\Users\\Kaushal28\\Desktop\\Aqua-Ball-icon.png");
panel1.add(new JLabel(image));
add(panel1, BorderLayout.PAGE_START);
add(panel0, BorderLayout.PAGE_END);
}
}
I can't seem to figure out how I would add in a background WITH all of my panels showing.
I tried to set the JFrame content pane as a label with an imageicon and the frame does show, it just doesn't show the image like above.
This is the code that I've used.
frame.setContentPane(new JLabel(new ImageIcon("res/Wallpaper.png")));
The second attempt I've used is to ADD (not set) an image into the content pane of the frame. This did not work as shown in the second picture above and it only shows the panels but no background. The code is on the bottom.
frame.getContentPane().add(new JLabel(new ImageIcon("res/Wallpaper.png")));
The third attempt I've tried is to create a subclass of JComponent and Override the paintComponents method then setan object of it as the contentpane. This does not work and instead turns my screen blank.
Here is the code I've used and the class code is in the 1st answer of this link Setting background images in JFrame. The result is the 3rd image of this post.
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();
}
The 4th attempt I've tried is adding the picture into the main panel that fills up the screen. This does not work at all and instead breaks the image in half so half of the screen has the image half doesn't.
Here is the code I've used for my 4th attempt. The result is the 4th last image on the top.
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();
}
I'm not sure why the JPanels aren't showing up.
I know that in the 1st example when you set the frame as a JLabel it gives it a null layout but that was the only way I could find to DISPLAY the image.
I would like to somehow add the panels ontop of the frame with that background but after reading numerous threads I could not find out how.
If anyone does find out, please post the code and explain if you can. I also have the class get the system class theme that sets it into the theme of what the computer is using. Ex. I am using a windows operating system so it shows it kind of like my operating system.
This thread is not a duplicate. In other threads they only have a frame but in my thread I have several panels that aren't showing for some particular reason.
EDIT: I don't know what's up, I tried to use this thread Setting background images in JFrame but I had no luck.
The 1st method it gave me I tried and then instead of showing anything it showed nothing at all, no picture no components nothing at all. In case if you need more information I have: 4 JPanels on the bottom of the screen, I also have a border surrounding my window but doesn't show up in the 1st window. I also have borders surrounding my panels too.
So the 1st method I've tried setting it on the content pane, image loads but all of the components are gone.
2nd method I've tried adding it into the content pane but yet again with no luck and I get a panel with no background.
3rd method I've tried is creating a separate class and overriding the paintComponent method and adding an image to the constructor of it then placing this object of the class into the setcontentPane() parameter of the frame. Does not work at all, all I get is a blank frame.
Code I am using for my frame:
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 UPDATE 2: Here is the code that I've used using #peeskillet's 1st method. It works sort of but it gives me the same results as the 3rd photo, a cut off picture. P.S I add the panels down at the bottom to my JLabel at the end.
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);
"I tried to set the JFrame content pane as a label with an imageicon"
You need to set the layout on the JLabel. It will be null be default.
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"
Should be paintComponent (no "s"), but just like with JLabel, you need to set the layout. JComponent layout is null be default. You also need to give it a preferred size when painting.
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) {}
});
}
}
Using (extending) JPanel instead of JComponent would be similar except JPanel does have a default layout which is FlowLayout.
UPDATE
To get your desired layout, you need to play around with the different layout managers. The combination I used is
Outer (main panel) -- BorderLayout
Bottom (bottom panel) -- BoxLayout inside (south) of outer layout
For the BorderLayout, you need to make sure the panel opaque property is set to false, as BorderLayout will stretch the panel and cover the background.
For the BoxLayout, you need to make sure to set the maximum size and the preferred size
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) {
}
});
}
}
For more information about using the different layout managers, see
Laying Out Components Within a Container
You can try JLayeredPane and setOpaque(boolean) method.
Code:
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());
}
}