Positioning of Swing Components Java - JPanel, JButton, JFrame

32,862

Solution 1

Let's start with the problem at hand...

As JFrame uses a BorderLayout by default, doing frame.getContentPane().add(panel); is going to add it to the center position of the window. Instead, try frame.getContentPane().add(panel, BorderLayout.NORTH); instead

The setSize call in TapTabButton is irrelevant. It's size will be established by the layout manager of the container it is added to...

The calls to setPreferredSize(size), setMinimumSize(size) and setMaximumSize(size) are not recommended, instead, you should override the corresponding getXxxSize methods and return the size you want. This will prevent people from overriding them later ;)

Also, the call to setSize is irrelevant...

I'd be wary of ImageIcon. It uses a delegation model to load the image (passes it off to another Thread), meaning that getWidth and getHeight might actually return 0 as the there might not be enough data loaded to ascertain the size of the image.

Instead, use ImageIO, this will read the image in before returning...

You MUST call super.paintComponent in you paintComponent method! This is very important, as one of the jobs of paintComponent is to prepare the Graphics context for painting

setSize in ButtonPanelTest...irrelevant

Working Example

Okay, took a little playing with, but basically, all the setXxxSize calls was messing about with things...

enter image description here

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImageTest {

    public static void main(String[] args) {
        ImagePanel panel = new ImagePanel("program/assets/main_bg.jpg");

        TopTabButton buttonHome = new TopTabButton("home");
        TopTabButton buttonSettings = new TopTabButton("settings");
        TopTabButton buttonHelp = new TopTabButton("help");

        panel.add(buttonHome);
        panel.add(buttonSettings);
        panel.add(buttonHelp);


//        panel.setPreferredSize(new Dimension(1000, 760));

        JFrame frame = new JFrame();
        frame.setBackground(new Color(53, 56, 64));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(panel, BorderLayout.NORTH);

        frame.pack();

        frame.setLocationRelativeTo(null);
//        frame.setResizable(false);
        frame.setVisible(true);
    }

    class TopTabButton extends JButton {

        public TopTabButton(String buttonCode) {
            setText(buttonCode);
//        setIcon(new ImageIcon("program/assets/top_tab_button_bg_" + buttonCode + "_inactive.png"));
//        setRolloverIcon(new ImageIcon("program/assets/top_tab_button_bg_" + buttonCode + "_active.png"));
//        setBorderPainted(false);
//        setFocusPainted(false);
//        setContentAreaFilled(true);
//        setSize(new Dimension(126, 75));
        }
    }

    class ImagePanel extends JPanel {

        private Image img;

        public ImagePanel(String img) {
            this(Toolkit.getDefaultToolkit().createImage(img));
        }

        public ImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
//        setPreferredSize(size);
//        setMinimumSize(size);
//        setMaximumSize(size);
//        setSize(size);
            setLayout(new GridBagLayout());
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        }
    }
//
//class ButtonPanelTest extends JPanel {
//
//    private Image img;
//
//    public ButtonPanelTest(String name) {
//        Button Button1 = new Button(name);
//        Dimension size = new Dimension(100, 50);
//        setSize(size);
//        setLayout(new GridBagLayout());
//    }
//}
}

Yes, I would probably build each element of the UI as separate panels, rather the trying to get it all to work in pane.

This isolates control and responsibility as well as reduce layout congestion and confusion...

Solution 2

You have to split your window into different panels, and give a different type of Layout in each one of these panels.

For example, in your case, you have to apply a BorderLayout to your window and place the panel of your 3 buttons to the position NORTH. It will place your buttons to the top of the window (at the middle for the moment). You have to apply layouts to every panels to choose the position of your elements in the window.

Check this link, it will explain you the way layouts work Visual Guide to Layouts

Share:
32,862
Charlie Sheather
Author by

Charlie Sheather

Updated on November 14, 2020

Comments

  • Charlie Sheather
    Charlie Sheather over 3 years

    I'm currently studying Java GUI implementations and for my next assignment we are to create a program to simulate the control of a house. We have been given pretty much free reign to build it however we like (as long as its in Java). I've drawn up this mockup: http://i.imgur.com/9RtWL7b.jpg (shown below) and thats what I'm looking to produce.

    Program Mockup: Program Mockup

    Below is the code I have at the moment and it produces this http://i.imgur.com/XZLiwWx.jpg (below)

    Example Code Below: Program Example

    My question is; how can I get the three buttons to be in the to left of the screen? Am I going about this the wrong way? I feel like the code I have below is quite clunky and un-organised, should I be taking a different approach?

    Let me know if any more information is needed.

    import java.awt.*;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Image;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JButton;
    
    public class ImageTest {
    
        public static void main(String[] args) {
            ImagePanel panel            = new ImagePanel("program/assets/main_bg.jpg");
    
            TopTabButton buttonHome     = new TopTabButton("home");
            TopTabButton buttonSettings = new TopTabButton("settings");
            TopTabButton buttonHelp     = new TopTabButton("help");
    
            panel.add(buttonHome);
            panel.add(buttonSettings);
            panel.add(buttonHelp);
    
    
            panel.setPreferredSize(new Dimension(1000, 760));
    
            JFrame frame = new JFrame();
            frame.setBackground(new Color(53, 56, 64));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            frame.getContentPane().add(panel);
    
            frame.pack();
    
            frame.setLocationRelativeTo(null);
            frame.setResizable(false);
            frame.setVisible(true);
        }
    
    }
    
    class TopTabButton extends JButton {
    
        public TopTabButton(String buttonCode) {
            setIcon(new ImageIcon("program/assets/top_tab_button_bg_" + buttonCode + "_inactive.png"));
            setRolloverIcon(new ImageIcon("program/assets/top_tab_button_bg_" + buttonCode + "_active.png"));
            setBorderPainted(false);
            setFocusPainted(false);
            setContentAreaFilled(true);
            setSize(new Dimension(126, 75));
         }
    
    }
    
    class ImagePanel extends JPanel {
    
        private Image img;
    
        public ImagePanel(String img) {
            this(Toolkit.getDefaultToolkit().createImage(img));
        }
    
        public ImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
            setPreferredSize(size);
            setMinimumSize(size);
            setMaximumSize(size);
            setSize(size);
            setLayout(new GridBagLayout());
        }
    
        public void paintComponent(Graphics g) {
            g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        }
    }
    
    class ButtonPanelTest extends JPanel {
    
        private Image img;
    
        public ButtonPanelTest(String name) {
            Button Button1 = new Button(name);
            Dimension size = new Dimension(100, 50);
            setSize(size);
            setLayout(new GridBagLayout());
        }
    
    }
    
  • Andrew Thompson
    Andrew Thompson almost 11 years
    +1 See also the Nested Layout Example for ideas about how to combine layouts.
  • Charlie Sheather
    Charlie Sheather almost 11 years
    Hi MadProgrammer, Thank you! I've implemented all your recommendations . When I use frame.getContentPane().add(panel, BorderLayout.NORTH); I get no change in the position of the buttons. Should I go for what MnK suggested and rebuild using bunch of different panels?
  • Charlie Sheather
    Charlie Sheather almost 11 years
    Thanks @MadProgrammer, the code above has definitely helped! It's given me a better understanding of setXXXSize etc. I'm going to try and rebuild using what you've given me and MnK's suggestion.
  • MadProgrammer
    MadProgrammer almost 11 years
    @CharlieSheather I like the look of the UI, I hope you get it to work!