Why does GridBagLayout provide strange result? - java

I want the various components to spread out and fill the entire window.
Have you tried anything else? Yes, I tried GridLayout but then the buttons look huge. I also tried pack() which made the window small instead. The window should be 750x750 :)
What I was trying is this:
These 4 buttons on the top as a thin strip
The scroll pane with JPanels inside which will contain all the video conversion tasks. This takes up the maximum space
A JPanel at the bottom containing a JProgressBar as a thin strip.
But something seems to have messed up somewhere. Please help me solve this
SSCCE
import java.awt.*;
import javax.swing.*;
import com.explodingpixels.macwidgets.*;
public class HudTest {
public static void main(String[] args) {
HudWindow hud = new HudWindow("Window");
hud.getJDialog().setSize(750, 750);
hud.getJDialog().setLocationRelativeTo(null);
hud.getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton addVideo = HudWidgetFactory.createHudButton("Add New Video");
JButton removeVideo = HudWidgetFactory.createHudButton("Remove Video");
JButton startAll = HudWidgetFactory.createHudButton("Start All Tasks");
JButton stopAll = HudWidgetFactory.createHudButton("Stop All Tasks");
buttonPanel.add(addVideo);
buttonPanel.add(startAll);
buttonPanel.add(removeVideo);
buttonPanel.add(stopAll);
JPanel taskPanel = new JPanel(new GridLayout(0,1));
JScrollPane taskScrollPane = new JScrollPane(taskPanel);
IAppWidgetFactory.makeIAppScrollPane(taskScrollPane);
for(int i=0;i<10;i++){
ColorPanel c = new ColorPanel();
c.setPreferredSize(new Dimension(750,100));
taskPanel.add(c);
}
JPanel progressBarPanel = new JPanel();
JComponent component = (JComponent) hud.getContentPane();
component.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
Insets in = new Insets(2,2,2,2);
gbc.insets = in;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 10;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
component.add(buttonPanel,gbc);
gbc.gridy += 1;
gbc.gridheight = 17;
component.add(taskScrollPane,gbc);
gbc.gridy += 17;
gbc.gridheight = 2;
component.add(progressBarPanel,gbc);
hud.getJDialog().setVisible(true);
}
}

Use this
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridbagConstraints.BOTH

Why not simply place three JPanels on top of one JPanel with BorderLayout as Layout Manager, where the middle JPanel with all custom panels with their respective sizes can be accommodated inside a JScrollPane, as shown in the below example :
import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 5/17/13
* Time: 6:09 PM
* To change this template use File | Settings | File Templates.
*/
public class PlayerBase
{
private JPanel contentPane;
private JPanel buttonPanel;
private JPanel centerPanel;
private CustomPanel[] colourPanel;
private JPanel progressPanel;
private JButton addVideoButton;
private JButton removeVideoButton;
private JButton startAllButton;
private JButton stopAllButton;
private JProgressBar progressBar;
private Random random;
public PlayerBase()
{
colourPanel = new CustomPanel[10];
random = new Random();
}
private void displayGUI()
{
JFrame playerWindow = new JFrame("Player Window");
playerWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
addVideoButton = new JButton("Add New Video");
removeVideoButton = new JButton("Remove Video");
startAllButton = new JButton("Start all tasks");
stopAllButton = new JButton("Stop all tasks");
buttonPanel.add(addVideoButton);
buttonPanel.add(removeVideoButton);
buttonPanel.add(startAllButton);
buttonPanel.add(stopAllButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
JScrollPane scroller = new JScrollPane();
centerPanel = new JPanel(new GridLayout(0, 1, 2, 2));
for (int i = 0; i < colourPanel.length; i++)
{
colourPanel[i] = new CustomPanel(new Color(
random.nextInt(255), random.nextInt(255)
, random.nextInt(255)));
centerPanel.add(colourPanel[i]);
}
scroller.setViewportView(centerPanel);
contentPane.add(scroller, BorderLayout.CENTER);
progressPanel = new JPanel(new BorderLayout(5, 5));
progressBar = new JProgressBar(SwingConstants.HORIZONTAL);
progressPanel.add(progressBar);
contentPane.add(progressPanel, BorderLayout.PAGE_END);
playerWindow.setContentPane(contentPane);
playerWindow.pack();
//playerWindow.setSize(750, 750);
playerWindow.setLocationByPlatform(true);
playerWindow.setVisible(true);
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
#Override
public void run()
{
new PlayerBase().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class CustomPanel extends JPanel
{
public CustomPanel(Color backGroundColour)
{
setOpaque(true);
setBackground(backGroundColour);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(750, 100));
}
}
OUTPUT :

Related

I want my button not in the same row as my choose buttons in my gui? How will I do that?

How do I add a break to put my "Make pokemon" buttons and textarea not in the same row as my "Pokemon choice." I'm trying to put an empty JLabel, but I don't think it works.
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton(" Make Pokemon ");
private JButton bClear = new JButton(" Clear ");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel();
private JPanel bottomSubPanel = new JPanel();
private GUIListener listener = new GUIListener();
private Choice chSpe = new Choice();
private JLabel lEmp = new JLabel(" ");
private PokemonGUILizylf st;
private final int capacity = 10;
private PokemonGUILizylf[ ] stArr = new PokemonGUILizylf[capacity];
private int count = 0;
private String sOut = new String("");
private JTextArea textArea = new JTextArea(400, 500);
private JTextArea textArea2 = new JTextArea(400, 500);
private JScrollPane scroll = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lEmp = new JLabel(" ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
chSpe.add("Choose");
chSpe.add("Bulbasaur");
chSpe.add("Venusaur");
chSpe.add("Ivysaur");
chSpe.add("Squirtle");
chSpe.add("Wartortle");
chSpe.add("Blastoise");
chSpe.add("Charmander");
chSpe.add("Charmeleon");
chSpe.add("Charizard");
centerSubPanel.add(lSpe);
centerSubPanel.add(chSpe);
centerSubPanel.add(lEmp);
centerSubPanel.add(bDone);
centerSubPanel.add(lNew);
textArea.setPreferredSize(new Dimension(500, 200));
textArea.setEditable(false);
textArea2.setPreferredSize(new Dimension(500, 200));
textArea2.setEditable(false);
textArea.setBackground(Color.white);
textArea.setEditable(false);
scroll.setBorder(null);
centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
bottomSubPanel.add(lMsg);
bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
This is what my GUI looks like:
enter image description here
But it should show like this:
enter image description here
Can someone explain to me how I can do that?
Use a different layout manager (other then default FlowLayout which JPanel uses)
See Laying Out Components Within a Container for more details.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new PokemonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
// private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton("Make Pokemon ");
private JButton bClear = new JButton("Clear");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel(new GridBagLayout());
private JPanel bottomSubPanel = new JPanel();
// private GUIListener listener = new GUIListener();
private JComboBox<String> chSpe = new JComboBox<>();
private JLabel lEmp = new JLabel(" ");
// private PokemonGUILizylf st;
private final int capacity = 10;
// private PokemonGUILizylf[] stArr = new PokemonGUILizylf[capacity];
// private int count = 0;
// private String sOut = new String("");
// private JTextArea textArea = new JTextArea(400, 500);
// private JTextArea textArea2 = new JTextArea(400, 500);
//
// private JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
// JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
// this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
DefaultComboBoxModel<String> chSpeModel= new DefaultComboBoxModel<>();
chSpeModel.addElement("Choose");
chSpeModel.addElement("Bulbasaur");
chSpeModel.addElement("Venusaur");
chSpeModel.addElement("Ivysaur");
chSpeModel.addElement("Squirtle");
chSpeModel.addElement("Wartortle");
chSpeModel.addElement("Blastoise");
chSpeModel.addElement("Charmander");
chSpeModel.addElement("Charmeleon");
chSpeModel.addElement("Charizard");
chSpe.setModel(chSpeModel);
centerSubPanel.setBorder(new EmptyBorder(4, 4, 4, 4));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.LINE_END;
centerSubPanel.add(lSpe, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
centerSubPanel.add(chSpe);
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy++;
centerSubPanel.add(bDone, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
centerSubPanel.add(lNew, gbc);
gbc.gridx++;
gbc.gridheight = gbc.REMAINDER;
centerSubPanel.add(new JScrollPane(new JTextArea(10, 10)), gbc);
// textArea.setEditable(false);
// textArea2.setEditable(false);
//
// textArea.setBackground(Color.white);
// textArea.setEditable(false);
// scroll.setBorder(null);
// centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
// scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
// bottomSubPanel.add(lMsg);
// bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
// bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
}
}
Also, avoid using setPreferredSize, let the layout managers do their job. In the example I'm used insets (from GridBagConstraints) and an EmptyBorder to add some additional space around the components
Also, be careful of using AWT components (ie Choice), they don't always play nicely with Swing. In this case, you should be using JComboBox

Panels take equal space

I have two panels. The first one looks like this.
public class BoardPanel extends JPanel
{
public BoardPanel()
{
setLayout(null);
this.setOpaque(false);
Button button = new JButton("..");
button.setLocation(...);
button.setSize(...);
add(button);
}
public void paintComponent( Graphics g )
{
/*
* Painting some stuff here.
*/
}
}
The other panel is something like this:
public class OtherPanel extends JPanel
{
public OtherPanel()
{
super();
this.setLayout(null);
this.setOpaque(false);
JPanel panel1 = new JPanel();
panel1.setLocation(...);
panel1.setSize(...);
panel1.setOpaque( .. );
JPanel panel2 = new JPanel();
panel2.setLocation(...);
panel2.setSize(...);
panel2.setOpaque( .. );
add(panel1):
add(panel2);
}
}
After that , I put both my panels in a frame. But I want my BoardPanel to occupy more screen than OtherPanel. So I used GridBagLayout for the frame
public class MainFrame extends JFrame
{
private GridBagLayout aGridLayout = new GridBagLayout();
private GridBagConstraints constraints = new GridBagConstraints();
public MainFrame()
{
super("Quoridor");
setLayout(gridLayout);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1366, 768);
setVisible(true);
setResizable(false);
this.getContentPane().setBackground(Color.decode("#b2a6a6"));
BoardPanel boardPanel = new BoardPanel();
OtherPanel otherPanel = new OtherPanel();
this.addComponent(boardPanel, 1, 1, 2, 1);
this.addComponent(otherPanel, 1, 3, 1, 1);
}
public void addComponent(Component component , int row , int column , int width
, int height)
{
constraints.gridx = column;
constraints.gridy = row;
constraints.gridwidth = width;
constraints.gridheight = height;
aGridLayout.setConstraints(component, constraints);
add(component);
}
}
The problem is , that the frame gives equal space to both panels , and dont give more space to the boardPanel.
Why is this happening ? Doest it have to do with the bounds of the panels ?
Here is a good tutorial on GridBagLayout: https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html . Also see the code below and screenshot. The anchor field positions the component at the first line. The weightx field gives more space to the columns for boardPanel. The ipady field specifies how much to add to the height of the component. Here, boardPanel gets most of the width and all of the height. The otherPanel panel gets half of the height.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridExample {
private JFrame mainFrame;
private JPanel boardPanel, otherPanel;
public GridExample(){
mainFrame = new JFrame();
mainFrame.setSize(600,400);
mainFrame.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
boardPanel = new JPanel();
boardPanel.add(new JLabel("board panel"));
boardPanel.setBackground(Color.yellow);
otherPanel = new JPanel();
otherPanel.add(new JLabel("other panel"));
otherPanel.setBackground(Color.green);
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.75;
c.ipady = 400;
c.gridx = 0;
c.gridy = 0;
mainFrame.add(boardPanel, c);
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.25;
c.ipady = 200;
c.gridx = 1;
c.gridy = 0;
mainFrame.add(otherPanel, c);
mainFrame.setVisible(true);
}
public static void main(String[] args){
GridExample swingContainerDemo = new GridExample();
}
}

Issues in locating elements and re sizing

Please have a look at the following code
WizardPanel
package wizardGUI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WizardPanel extends JDialog
{
private JPanel cardPanel, buttonPanel;
private JButton next,previous;
private CardLayout c1;
private FileSelector fileSelector;
private DelemeterSelector delemeterSelector;
private int count = 1;
public WizardPanel()
{
//Intializing instance variables
fileSelector = FileSelector.getInstance();
delemeterSelector = DelemeterSelector.getInstance();
cardPanel = new JPanel();
c1 = new CardLayout();
cardPanel.setLayout(c1);
cardPanel.add(fileSelector,"1");
cardPanel.add(delemeterSelector,"2");
c1.show(cardPanel, "1");;
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
next.addActionListener(new NextButtonAction());
previous = new JButton("Previous");
buttonPanel.add(next);
buttonPanel.add(previous);
//Creating the GUI
this.setLayout(new BorderLayout());
this.add(cardPanel,"Center");
this.add(buttonPanel,"South");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setResizable(true);
this.pack();
this.setVisible(true);
}
private class NextButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
c1.show(cardPanel, "2");
}
}
}
FileSelector
package wizardGUI;
/*This is the first panel is wazard GUI. Using this window user can select the correct file
which contains the data required to create the table
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FileSelector extends JPanel
{
private JLabel fileName, description;
private JTextField fileTxt;
private JButton browse;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static FileSelector instance = null;
private FileSelector()
{
//Intializing instance variables
fileName = new JLabel("File Name: ");
description = new JLabel("Specify the source of the data");
fileTxt = new JTextField(10);
browse = new JButton("Browse");
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
//Creating GUI
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
this.setBorder(BorderFactory.createEmptyBorder());
}
private JPanel locationPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(fileName);
panel.add(fileTxt);
panel.add(browse);
return panel;
}
public static FileSelector getInstance()
{
if(instance==null)
{
instance = new FileSelector();
}
return instance;
}
}
DelemeterSelector
/*This is the second windows in wizard
This class is designed to let the user to select the delemeter to break information */
package wizardGUI;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class DelemeterSelector extends JPanel
{
private JLabel description;
private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
private JTextArea txtArea;
private JScrollPane scroll;
private ButtonGroup btnGroup;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static DelemeterSelector instance = null;
private DelemeterSelector()
{
//Initializing instance variables
description = new JLabel("What delemeter separates your fields? Select the appropreiate delemeter");
tabBtn = new JRadioButton("Tab");
semicolanBtn = new JRadioButton("Semicolan");
commaBtn = new JRadioButton("Comma");
spaceBtn = new JRadioButton("Space");
btnGroup = new ButtonGroup();
btnGroup.add(tabBtn);
btnGroup.add(semicolanBtn);
btnGroup.add(commaBtn);
btnGroup.add(spaceBtn);
txtArea = new JTextArea(20,70);
scroll = new JScrollPane(txtArea);
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
//Creating the GUI
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(radioPanel(),gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(10,0,0,0);
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll,gbc);
}
private JPanel radioPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(tabBtn);
panel.add(semicolanBtn);
panel.add(commaBtn);
panel.add(spaceBtn);
panel.setBorder(BorderFactory.createTitledBorder("Choose the Delimeter that seperates your fields"));
return panel;
}
public static DelemeterSelector getInstance()
{
if(instance == null)
{
instance = new DelemeterSelector();
}
return instance;
}
}
When I run the code, the "FileSelector" looks really ugly. I want everything to be appear at the top of the pane, but instead, everything appears in middle!! I have even tried GridBagLayout options to make it resizable, it also failed. The look of it is in the attached image
How can I make it look nice and scalable? Please help
Just a quick example which shows the same behavior and a fix, without the need for all that external code (an SSCCE)
import javax.swing.*;
import java.awt.*;
public class CardLayoutDemo {
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame( "TestFrame" );
CardLayout cardLayout = new CardLayout();
JPanel contentPane = new JPanel( cardLayout );
JPanel firstPanel = new JPanel( );
firstPanel.setLayout( new BorderLayout( ) );
firstPanel.add( new JLabel( "Contents" ) );
//wrap the smallest panel instead of directly adding it
contentPane.add( firstPanel, "first" );
// JPanel wrappedPanel = new JPanel( new BorderLayout( ) );
// wrappedPanel.add( firstPanel, BorderLayout.NORTH );
// contentPane.add( wrappedPanel, "first" );
JPanel secondPanel = new JPanel( new BorderLayout( ) );
secondPanel.add( new JComponent() {
#Override
public Dimension getPreferredSize() {
return new Dimension( 500, 500 );
}
}, BorderLayout.CENTER );
contentPane.add( secondPanel, "second" );
cardLayout.show( contentPane, "first" );
frame.setContentPane( contentPane );
frame.pack();
frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
frame.setVisible( true );
}
} );
}
}
When you run the code without making changes, it will show you a panel where the contents is centered (the firstPanel). Without making any changes to the firstPanel, but simply by wrapping it you can keep it at the top. Just replace the contentPane.add( firstPanel, "first" ) by the 3 lines (in comment) underneath.
There are a lot of times where nesting layouts makes it easier to get the desired result, and imo this is one of them.
The fill constraints are not necessary in this case. Also, gridx and gridy start from 0. This sample code
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10,0,0,0);
this.add(description,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weighty = 1;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
produces this
Not sure if this is what you want though.

Multi-colored lists

I have to create 5 Jlists in succession to make their backgrounds look in different colors. My existing code creates these 5 lists without the colors (the default JList). I understand that I can only customize the inside/border of a jlist and not the margin/padding around it? Or Am I wrong and is there a way to it?
Btw, The space above the list is a Jlabel (not shown in the pic above) and the layout managers in use are GroupLayout and GridBagLayout.
UPDATE
AT, as per your suggestion, here is a comparison to how the lists look like when surrounded by a jpanel. The lists in the back are the ones with the Jpanel surrounded with a minimal empty border of size 1.
The issue with creating a JPanel with preferredsize overridden is that the jlists are in horizontal jpanel and above them is another jpanel with labels. So, wrapping jlist in a jpanel is not going to do it.
Please do have a look at this code example. Is it closer to what you wanted, else you define the changes that needs to be done. I be on them as soon as I get the reply from your side :-)
Here is the outcome :
import java.awt.*;
import javax.swing.*;
public class JListExample
{
private JList<String> list1;
private JList<String> list2;
private JList<String> list3;
private JList<String> list4;
private JList<String> list5;
private CustomPanel panel1;
private CustomPanel panel2;
private CustomPanel panel3;
private CustomPanel panel4;
private CustomPanel panel5;
private String[] data = {"one", "two", "three", "four"};
private int width = 110;
private int height = 300;
private void displayGUI()
{
JFrame frame = new JFrame("JList Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 5, 2, 2));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1.0;
gbc.weighty = 0.9;
panel1 = new CustomPanel(width, height, Color.GRAY, "List 1");
list1 = new JList<String>(data);
panel1.add(list1, gbc);
panel2 = new CustomPanel(width, height,
Color.GREEN.brighter().brighter(), "List 2");
list2 = new JList<String>(data);
panel2.add(list2, gbc);
panel3 = new CustomPanel(width, height,
Color.ORANGE.brighter(), "List 3");
list3 = new JList<String>(data);
panel3.add(list3, gbc);
panel4 = new CustomPanel(width, height,
Color.BLUE.brighter(), "List 4");
list4 = new JList<String>(data);
panel4.add(list4, gbc);
panel5 = new CustomPanel(width, height, Color.RED, "List 5");
list5 = new JList<String>(data);
panel5.add(list5, gbc);
contentPane.add(panel1);
contentPane.add(panel2);
contentPane.add(panel3);
contentPane.add(panel4);
contentPane.add(panel5);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JListExample().displayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
private final int GAP = 5;
private int width;
private int height;
private Color backgroundColour;
private JLabel titleLabel;
public CustomPanel(int w, int h, Color c, String title)
{
width = w;
height = h;
backgroundColour = c;
titleLabel = new JLabel(title, JLabel.CENTER);
setBackground(backgroundColour);
setBorder(
BorderFactory.createEmptyBorder(
GAP, GAP, GAP, GAP));
setLayout(new GridBagLayout());
titleLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
add(titleLabel, gbc);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(width, height));
}
}
**LATEST EDIT : **
As rightly pointed by #kleopatra (not something that is new for me :-)), too good judgement call. Done the edit related to that below :
import java.awt.*;
import javax.swing.*;
public class JListExample
{
private final int GAP = 5;
private JList<String> list1;
private JList<String> list2;
private JList<String> list3;
private JList<String> list4;
private JList<String> list5;
private JPanel panel1;
private JPanel panel2;
private JPanel panel3;
private JPanel panel4;
private JPanel panel5;
private String[] data = {"one", "two", "three", "four"};
private int width = 110;
private int height = 300;
private GridBagConstraints gbc = new GridBagConstraints();
private void displayGUI()
{
JFrame frame = new JFrame("JList Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 5, 2, 2));
panel1 = getPanel(Color.GRAY, "List 1");
list1 = new JList<String>(data);
panel2 = getPanel(Color.GREEN.brighter().brighter(), "List 2");
list2 = new JList<String>(data);
panel3 = getPanel(Color.ORANGE.brighter(), "List 3");
list3 = new JList<String>(data);
panel4 = getPanel(Color.BLUE.brighter(), "List 4");
list4 = new JList<String>(data);
panel5 = getPanel(Color.RED, "List 5");
list5 = new JList<String>(data);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1.0;
gbc.weighty = 0.9;
panel1.add(list1, gbc);
panel2.add(list2, gbc);
panel3.add(list3, gbc);
panel4.add(list4, gbc);
panel5.add(list5, gbc);
contentPane.add(panel1);
contentPane.add(panel2);
contentPane.add(panel3);
contentPane.add(panel4);
contentPane.add(panel5);
frame.setContentPane(contentPane);
frame.setSize(610, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel getPanel(Color c, String title)
{
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBorder(
BorderFactory.createEmptyBorder(
GAP, GAP, GAP, GAP));
panel.setBackground(c);
panel.setLayout(new GridBagLayout());
JLabel label = new JLabel(title, JLabel.CENTER);
label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
panel.add(label, gbc);
return panel;
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JListExample().displayGUI();
}
});
}
}

Nested JPanels and GridBagLayout Not "Packing" Components

I've attached a screenshot for which the following Border legend applies:
Yellow = JPanel with BorderLayout
Blue = JPanel with GridBagLayout
Fuchsia = JPanel with FlowLayout
There are two panels not blocked out in colors that warrant mentioning:
1) The title panel where the word "Primary" is displayed; this panel is at BorderLayout.NORTH in "Yellow" panel.
2) The image panel where the image of the device is located; this panel is a sibling to "Fuchsia"
"Blue" is at BorderLayout.CENTER in "Yellow" while "Fuchsia" and the image panel are given the following constraints:
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1.0;
c.weighty = 1.0;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.insets = new Insets(0, 10, 0, 0);
c.fill = GridBagConstraints.BOTH;
//"Blue".add(imagePanel, c);
c.weighty = 0.80;
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
//"Blue".add("Fuchsia", c);
As you can probably tell from the image, I'm trying to get rid of the "wasted" space in "Blue" right below "Fuchsia". I don't seem to be able to do it with GridBagConstraints, so am I just using the wrong LayoutManager? It looks to me like "Blue", who is at CENTER in the BorderLayout is just giving each child JPanel half of the available space and reserving the remainder space instead of contracting upward. What am I missing here? Is this simply a matter of setting a preferred or maximum size on "Fuchsia"? it doesn't seem like that will get me where I want to be, since the border around "Fuchsia" (which is covered by my color coding) is where I want the end of the component to be.
Have a look at this output, from this code example :
import java.awt.*;
import javax.swing.*;
public class LayoutTest
{
private void displayGUI()
{
JFrame frame = new JFrame("Layout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.YELLOW);
contentPane.setLayout(new BorderLayout(2, 2));
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel headingLabel = new JLabel("Primary");
topPanel.add(headingLabel);
contentPane.add(topPanel, BorderLayout.PAGE_START);
JPanel centerPanel = new JPanel();
centerPanel.setOpaque(true);
centerPanel.setBackground(Color.BLUE);
centerPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 0;
JPanel imagePanel = new JPanel();
JLabel imageLabel = null;
try
{
imageLabel = new JLabel(
new ImageIcon(
new java.net.URL(
"http://pscode.org/"
+ "tame/screenshot/"
+ "landscape/slider1.gif")));
}
catch(Exception e)
{
e.printStackTrace();
}
imagePanel.add(imageLabel);
centerPanel.add(imagePanel, gbc);
JPanel detailsPanel = new JPanel();
detailsPanel.setOpaque(true);
detailsPanel.setBackground(Color.WHITE);
detailsPanel.setBorder(
BorderFactory.createEmptyBorder(
5, 5, 5, 5));
detailsPanel.setLayout(new GridLayout(0, 1, 5, 5));
JLabel statusLabel = new JLabel("Chassis Status : ");
JLabel usageLabel = new JLabel("Bandwidth Usage : ");
JLabel fanLabel = new JLabel("Fan Status : ");
detailsPanel.add(statusLabel);
detailsPanel.add(usageLabel);
detailsPanel.add(fanLabel);
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 0.8;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridheight = 3;
centerPanel.add(detailsPanel, gbc);
contentPane.add(centerPanel, BorderLayout.CENTER);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new LayoutTest().displayGUI();
}
});
}
}
Without using GridBagLayout could be
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class NestedLayout {
private JFrame frame = new JFrame();
private JPanel yellowNorthPanel = new JPanel();
private JPanel yellowPanel = new JPanel();
private JPanel bluePanel = new JPanel();
private JPanel fuchsiaTopPanel = new JPanel();
private JPanel fuchsiaBottonPanel = new JPanel();
public NestedLayout() {
yellowNorthPanel.setBorder(new LineBorder(Color.yellow, 5));
yellowPanel.setLayout(new BorderLayout());
yellowPanel.setBorder(new LineBorder(Color.yellow, 5));
bluePanel.setLayout(new BorderLayout(5, 5));
bluePanel.setBorder(new LineBorder(Color.blue, 5));
fuchsiaTopPanel.setBorder(new LineBorder(Color.cyan, 5));
fuchsiaBottonPanel.setBorder(new LineBorder(Color.cyan, 5));
bluePanel.add(fuchsiaTopPanel, BorderLayout.NORTH);
bluePanel.add(fuchsiaBottonPanel);
yellowPanel.add(bluePanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(yellowNorthPanel, BorderLayout.NORTH);
frame.add(yellowPanel);
//frame.pack();
frame.setSize(400, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new NestedLayout();
}
});
}
}

Categories