JPanel doesnt show components after the second button click - java

I want to put a JTextPane component in a JPanel with a GridBagLayout when I click on button.
My code works fine for the first button click, But after, the next components are not displayed.
Here is my code:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class RefreshPanel {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private JTextPane [] textPane;// = new JTextPane[1];
private JScrollPane scrollbar;
private ArrayList arrayList = new ArrayList();
private JButton newItem = new JButton("new");
private int counter=0;
private GridBagLayout gbl = new GridBagLayout();
RefreshPanel() {
scrollbar = new JScrollPane(panel);
panel.setBackground(Color.WHITE);
panel.setLayout(gbl);
addButtonListener();
createFrame();
} //constructor
public void addButtonListener() {
newItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
arrayList.add("data");
textPane = generateTextPane(arrayList.size(), arrayList);
System.out.println(textPane.length);
for(int i=0;i<textPane.length;i++) {
System.out.println(textPane[i].getText());
addComponent(panel, gbl, textPane[i], 0, counter, 1, 1,1,1);
panel.revalidate();
}
}
});
}
private JTextPane[] generateTextPane(int arraySize, ArrayList arrayList) {
JTextPane [] textPane = new JTextPane[arraySize];
for(int i=0;i<textPane.length;i++) {
textPane[i]=new JTextPane();
textPane[i].setText((String) arrayList.get(i));
}
return textPane;
}
public void addComponent(Container cont,
GridBagLayout gbl,
Component c,
int x, int y,
int width, int height,
double weightx, double weighty) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = width; gbc.gridheight = height;
gbc.weightx = weightx; gbc.weighty = weighty;
gbl.setConstraints( c, gbc );
cont.add( c );
}
public void createFrame() {
//frame.getContentPane().setLayout(new FlowLayout());
frame.add(scrollbar, BorderLayout.CENTER);
frame.add(newItem, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300,300));
frame.setVisible(true);
}
public static void main(String [] args) {
new RefreshPanel();
}
}

Patrick: you are right! I really forgot to change the gridbagconstraints
addComponent(panel, gbl, textPane[i], 0, i, 1, 1, 1, 1);
instead of
addComponent(panel, gbl, textPane[i], 0, counter, 1, 1, 1, 1);

Related

JAVA JTabbedPane - border of stacked tabs removal

I have simple GUI that is supposed to show some informations. I created menu of multiple JTabbedPanes and the tabs are stacking on each other as intended. I am trying to remove borders on left, right and bottom sides of each tab so it doesn't look stacked. I haven't found anything that would solve my problem, is there actually a way to do it?
Thank you for answer in advance.
Here is screen shot:
Here is my code:
import java.awt.*;
import java.awt.event.*;
import java.io.FileNotFoundException;
import javax.swing.*;
public class Convertor implements ItemListener {
public void addComponentToPane(Container pane) throws FileNotFoundException {
//main panel containing all below
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//Menu panel
JPanel menuPanel = new JPanel();
menuPanel.setMinimumSize(new Dimension(1200, 30));
menuPanel.setMaximumSize(new Dimension(1200, 30));
menuPanel.setPreferredSize(new Dimension(1200, 30));
menuPanel.setBackground(Color.BLUE);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx = 0;
gbc.gridy = 0;
mainPanel.add(menuPanel, gbc);
//Menu panel buttons
JButton importButton = new JButton("Import");
importButton.setPreferredSize(new Dimension(75, 20));
menuPanel.add(importButton, BorderLayout.EAST);
JButton button2 = new JButton("XXX");
button2.setPreferredSize(new Dimension(75, 20));
menuPanel.add(button2, BorderLayout.EAST);
//PAYER PANEL CONTAINER - containing payer panel
JPanel payerPanelContainer = new JPanel(new BorderLayout());
//payerPanelContainer.setBackground(Color.RED);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0;
gbc.weighty = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx = 0;
gbc.gridy = 1;
mainPanel.add(payerPanelContainer, gbc);
//PAYER PANEL
JPanel payerPanel = new JPanel(new GridBagLayout());
payerPanel.setBackground(Color.YELLOW);
payerPanelContainer.add(payerPanel);
//PAYER PANEL TABBED PANE
JTabbedPane payerTabbedPane = new JTabbedPane();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx = 0;
gbc.gridy = 0;
payerPanel.add(payerTabbedPane, gbc);
//Create payer tabs
JPanel payerTab1 = new JPanel(new BorderLayout());
payerTabbedPane.addTab("Payer 1", payerTab1);
JPanel payerTab2 = new JPanel(new BorderLayout());
payerTabbedPane.addTab("Payer 2", payerTab2);
//create MSISDN tabbed pane in each payer tab
JTabbedPane msisdnTabbedPane1 = new JTabbedPane();
payerTab1.add(msisdnTabbedPane1);
//create MSISDN tabs
JPanel generalTabPayer1 = new JPanel(new BorderLayout());
msisdnTabbedPane1.addTab("GENERAL", generalTabPayer1);
JPanel msisdnTab1 = new JPanel(new BorderLayout());
msisdnTabbedPane1.addTab("MSISDN 1", msisdnTab1);
JPanel msisdnTab2 = new JPanel(new BorderLayout());
msisdnTabbedPane1.addTab("MSISDN 2", msisdnTab2);
JPanel msisdnTab3 = new JPanel(new BorderLayout());
msisdnTabbedPane1.addTab("MSISDN 2", msisdnTab3);
//create MSISDN options tabbed pane
JTabbedPane msisdnOptionsTabbedPane1 = new JTabbedPane();
msisdnTab1.add(msisdnOptionsTabbedPane1);
//create MSISDN options tabs
JPanel msisdnOptionsTab1 = new JPanel(new BorderLayout());
msisdnOptionsTabbedPane1.addTab("Option 1", msisdnOptionsTab1);
JPanel msisdnOptionsTab2 = new JPanel(new BorderLayout());
msisdnOptionsTabbedPane1.addTab("Option 2", msisdnOptionsTab2);
//add main panel to window
pane.add(mainPanel);
}
private static void createAndShowGUI() throws FileNotFoundException {
//Create and set up the window.
JFrame frame = new JFrame("CSV Reader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
Convertor demo = new Convertor();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setSize(1206, 800);
frame.setMinimumSize(new Dimension(1206, 800));
frame.setMaximumSize(new Dimension(1206, 800));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
#Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
}
}
It's possible, but it's hard. The only way to do it is to provide your own UI for the tabbed pane. Here is the example, which is not completly satisfied your requirements, but it can show the way, which you must go (sorry, but I cann't provide a complete solution, because it could be time expansive).
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
public class BorderlessTabsExample implements Runnable {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
} catch (Exception e) {
// Nothing
}
SwingUtilities.invokeLater(new BorderlessTabsExample());
}
#Override
public void run() {
JTabbedPane tabber = new JTabbedPane();
tabber.addTab("First", new JLabel("First"));
tabber.addTab("Second", new JLabel("Second"));
tabber.addTab("Third", new JLabel("Third"));
// set the UI which will paint your tabs
tabber.setUI(new MetalBorderlessTabbedPaneUI());
JFrame frm = new JFrame("Tabber test");
frm.add(tabber);
frm.setSize(500, 400);
frm.setLocationRelativeTo(null);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setVisible(true);
}
private static class MetalBorderlessTabbedPaneUI extends MetalTabbedPaneUI {
#Override
protected void installDefaults() {
super.installDefaults();
if (contentBorderInsets != null) {
contentBorderInsets = new Insets(contentBorderInsets.top, 0, 0, 0);
}
}
#Override
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
#Override
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
#Override
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
}
}

Small GUI issue I cannot fix. JTextFields

Small error I can't manage to do. So right now my program GUI looks like this:
Now there is a TextField under the 'Mark' column were the user can input their data. I also want the same for the weight section were I want to insert a TextField right under 'Weight' column.
However when I try and put in a TextField, both the the Textfields turn like this when the window is small:
and this when the window is enlarged:
How can I make it so that there is a textfield under Mark AND Weight?
Code:
public class Gradeanalysis implements ActionListener {
public void actionPerformed (ActionEvent e){
GridBagConstraints gbc = new GridBagConstraints();
//Adding the JPanels. Panel for instructions
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
//JLabel for the Instructions.
JLabel label = new JLabel("<html> Instructions: Type in the grades you’ve received, along with the weights they’ll have in the determination of your overall average. <br> After you press ‘Calculate’, the results will show your average so far. <br> Every grade you enter must be a non-negative number, and every percentage/weight you enter must be a positive number :)</html>");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 2;
gbc.gridy = 0;
panel.add(label, gbc);
//JLabel1 for Assingment/Grade/Weight(Percent)
JLabel label1 = new JLabel("<html><pre>Assingment\t\t\t\t\t Mark\t\t\t\t\tWeight</pre></html>");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.NORTH;
panel.add(label1, gbc);
//JLabel Numbers for the number list of assingments at the side.
JLabel numbers = new JLabel("1");
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
panel.add(numbers, gbc);
//JTextfield for Mark
JTextField mark = new JTextField(2);
gbc.fill = GridBagConstraints.NONE;
gbc.gridy = 2;
panel.add(mark, gbc);
//JTextfield for Weight
JTextField weight = new JTextField(2);
gbc.gridx = 2;
panel.add(weight, gbc);
//New frame set
JFrame frame = new JFrame("Grade Calculator-- ");
frame.setVisible(true);
frame.setSize(750,700);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(panel);
}
}
Thanks for reading.
Here's the GUI I created.
I don't know where your main method is, but you must always start a Swing application with a call to the SwingUtilities invokeLater method. The invokeLater method puts the creation and execution of the Swing components on the Event Dispatch thread (EDT).
When I use the GridBagLayout, I use the addComponent method I created to create a unique GridBagConstraints for each Swing component. I don't like to remember defaults.
The order of the JFrame methods is extremely important. Memorize the order of the JFrame methods in this example.
I put the instructions in a JTextArea. This way, the instruction text splits based on the size of the JTextArea. There's no need to hard code the line breaks with HTML.
Here's the code.
package com.ggl.testing;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GradeAnalysis implements Runnable {
private static final Insets normalInsets = new Insets(10, 10, 0, 10);
private static final Insets finalInsets = new Insets(10, 10, 10, 10);
public static void main(String[] args) {
SwingUtilities.invokeLater(new GradeAnalysis());
}
#Override
public void run() {
JFrame frame = new JFrame("Grade Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setVisible(true);
}
private JPanel createMainPanel() {
GridBagConstraints gbc = new GridBagConstraints();
// Adding the JPanels. Panel for instructions
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
int gridy = 0;
// JLabel for the Instructions.
JTextArea instructionTextArea = new JTextArea(5, 30);
instructionTextArea.setEditable(false);
instructionTextArea.setLineWrap(true);
instructionTextArea.setWrapStyleWord(true);
instructionTextArea.setText(getInstructions());
JScrollPane instructionScrollPane = new JScrollPane(instructionTextArea);
addComponent(panel, instructionScrollPane, 0, gridy++, 3, 1,
finalInsets, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL);
// JLabels for Assignment/Grade/Weight(Percent)
JLabel label1 = new JLabel("Assignment");
label1.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, label1, 0, gridy, 1, 1, finalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
JLabel label2 = new JLabel("Mark");
label2.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, label2, 1, gridy, 1, 1, finalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
JLabel label3 = new JLabel("Weight");
label3.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, label3, 2, gridy++, 1, 1, finalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
// JLabel Numbers for the number list of assignments at the side.
JLabel number = new JLabel("1");
number.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, number, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
// JTextfield for Mark
JTextField mark = new JTextField(20);
mark.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, mark, 1, gridy, 1, 1, normalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
// JTextfield for Weight
JTextField weight = new JTextField(20);
weight.setHorizontalAlignment(JLabel.CENTER);
addComponent(panel, weight, 2, gridy++, 1, 1, normalInsets,
GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
return panel;
}
private String getInstructions() {
return "Instructions: Type in the grades you’ve received, along with the weights "
+ "they’ll have in the determination of your overall average. After you "
+ "press ‘Calculate’, the results will show your average so far. Every "
+ "grade you enter must be a non-negative number, and every "
+ "percentage/weight you enter must be a positive number :)";
}
private void addComponent(Container container, Component component,
int gridx, int gridy, int gridwidth, int gridheight, Insets insets,
int anchor, int fill) {
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0);
container.add(component, gbc);
}
}
I suggest that you
Don't use setBounds(...) on any component or GUI
Same for setSize(...)
Instead nest JPanels each using its own layouts to achieve a pleasing and easy to manage layout and GUI.
Consider putting your intro text into a JTextArea. If you want it to look like a JLabel, you can take out the background color and borders.
Best of all would be to display the tabular data in a JTable, and for that you'd want to create your own table model, one based on the AbstractTableModel and that uses an Assignment object for each row.
An example without the JTable:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class GradeAnalysis2 extends JPanel {
private static final int PREF_H = 400;
private static final String DISPLAY_TEXT = "Instructions: "
+ "Type in the grades you’ve received, along with the "
+ "weights they’ll have in the determination of your "
+ "overall average.\n"
+ "After you press ‘Calculate’, the results will show "
+ "your average so far.\n"
+ "Every grade you enter must be a non-negative number, "
+ "and every percentage/weight you enter must be a "
+ "positive number :)";
private JTextArea displayArea = new JTextArea(5, 50);
private GradeTablePanel gradeTablePanel = new GradeTablePanel();
public GradeAnalysis2() {
displayArea.setText(DISPLAY_TEXT);
displayArea.setWrapStyleWord(true);
displayArea.setLineWrap(true);
displayArea.setEditable(false);
displayArea.setFocusable(false);
displayArea.setBorder(null);
displayArea.setBackground(null);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(gradeTablePanel, BorderLayout.PAGE_START);
centerPanel.add(Box.createGlue(), BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane(centerPanel);
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new AddAssignmentAction("Add")));
setLayout(new BorderLayout());
add(displayArea, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
#Override
public Dimension getPreferredSize() {
Dimension sz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return sz;
}
int height = Math.max(sz.height, PREF_H);
return new Dimension(sz.width, height);
}
private class AddAssignmentAction extends AbstractAction {
public AddAssignmentAction(String name) {
super(name);
int mnenomic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnenomic);
}
public void actionPerformed(ActionEvent e) {
gradeTablePanel.addAssignment();
gradeTablePanel.revalidate();
gradeTablePanel.repaint();
};
}
private class GradeTablePanel extends JPanel {
private int count = 0;
// parallel collections -- a bad kludge.
// a table model would make this much cleaner
private List<JTextField> marks;
private List<JTextField> weights;
public GradeTablePanel() {
setLayout(new GridBagLayout());
JLabel assgmntLbl = new JLabel(Assignment.ASSIGNMENT, SwingConstants.CENTER);
assgmntLbl.setFont(assgmntLbl.getFont().deriveFont(Font.BOLD));
JLabel markLbl = new JLabel(Assignment.MARK, SwingConstants.CENTER);
markLbl.setFont(markLbl.getFont().deriveFont(Font.BOLD));
JLabel weightLbl = new JLabel(Assignment.WEIGHT, SwingConstants.CENTER);
weightLbl.setFont(weightLbl.getFont().deriveFont(Font.BOLD));
add(assgmntLbl, createGbc(0, 0));
add(markLbl, createGbc(1, 0));
add(weightLbl, createGbc(2, 0));
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
return gbc;
}
public void addAssignment() {
count++;
JLabel countLabel = new JLabel(String.valueOf(count));
JTextField markField = new JTextField(2);
JTextField weightField = new JTextField(2);
add(countLabel, createGbc(0, count));
add(markField, createGbc(1, count));
add(weightField, createGbc(2, count));
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("GradeAnalysis2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GradeAnalysis2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Assignment {
public static final String ASSIGNMENT = "Assignment";
public static final String MARK = "Mark";
public static final String WEIGHT = "Weight";
private String assignment;
private int mark;
private double weight;
public Assignment(String assignment, int mark, double weight) {
this.assignment = assignment;
this.mark = mark;
this.weight = weight;
}
public String getAssignment() {
return assignment;
}
public void setAssignment(String assignment) {
this.assignment = assignment;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
You can set the minimum, expected and maximum sizes for each JTextField like so:
JTextField t = new JTextField();
t.setMaximumSize(MAX);
t.setMinimumSize(MIN);
t.setBounds(x, y, width, height);
Where MIN and MAX are a Dimension Object, and the inputs to set bounds are int

GridBagLayout formatting in Swing

When I add the second row (of buttons), my textArea disappears.
Here is the GridBagLayout code:
public void gridlayout(){
setLayout(new GridBagLayout());
GridBagConstraints grid = new GridBagConstraints();
grid.gridy = 0;
grid.gridx = 0;
add(refreshButton, grid);
grid.gridx = 1;
grid.gridwidth = 4;
add(textArea, grid);
grid.gridy = 1;
grid.gridx = 0;
grid.anchor = GridBagConstraints.LINE_END;
add(button1, grid);
grid.gridx = 1;
add(button2, grid);
grid.gridx = 2;
add(button3,grid);
grid.gridx = 3;
add(button4,grid);
grid.gridx = 4;
add(button5,grid);
grid.gridx = 5;
add(button6,grid);
}
How do I make it so that the refresh button stays on the left and the textArea appears above the second row and takes up the gridx = 1 <----> gridx =5 space?
Your JTextArea's grid.gridx should be 1, and its grid.gridwidth should likely be 5.
If you're setting sizes or preferredSizes anywhere don't.
You should wrap that JTextArea in a JScrollPane and add the scrollpane to the GUI, not the text area.
If you're not calling pack() on the top level window before displaying it, do this.
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class GridBagExample extends JPanel {
public GridBagExample() {
setLayout(new GridBagLayout());
add(new JButton("Refresh"), createGbc(0, 0));
add(new JScrollPane(new JTextArea(12, 20)), createGbc(1, 0, 5, 1));
for (int i = 0; i < 6; i++) {
String text = "Button: " + (10 - i);
JButton button = new JButton(text);
add(button, createGbc(i, 1));
}
}
private GridBagConstraints createGbc(int x, int y) {
return createGbc(x, y, 1, 1);
}
private GridBagConstraints createGbc(int x, int y, int w, int h) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = w;
gbc.gridheight = h;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 2, 2, 2);
return gbc;
}
private static void createAndShowGui() {
GridBagExample mainPanel = new GridBagExample();
JFrame frame = new JFrame("GridBagExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Multiple JTextFields in a JOptionPane.ShowInputDialog?

I'm wanting to put several JTextFields into a JOptionPane so that I can validate the information put within them. I know that showInputDialog() will produce one Input, but how would I go about implementing 3/4
EDIT: (At run-time it just shows one input field)
//JDIALOG(FOR END PAYMENT)
dialogPanel = new JPanel();
creditCardNoInput = new JTextField();
sortCodeInput = new JTextField();
secNoInput = new JTextField();
cardHolderName = new JTextField();
dialogPanel.add(creditCardNoInput);
dialogPanel.add(sortCodeInput);
dialogPanel.add(secNoInput);
dialogPanel.add(cardHolderName);
int result = JOptionPane.showConfirmDialog(null, dialogPanel,
"Please Enter your card details", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
//Execute desired code
Use a JPanel.
Put your JTextFields, along with your JLabels (since you'll likely need these as well), into a JPanel or JPanels, and put the main JPanel into the JOptionPane. You can put a complete complex GUI into JPanels and display this in a JOptionPane if desired.
For example:
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class ComplexOptionPane extends JPanel {
private PlayerEditorPanel playerEditorPanel = new PlayerEditorPanel();
private JTextArea textArea = new JTextArea(12, 30);
public ComplexOptionPane() {
textArea.setEditable(false);
textArea.setFocusable(false);
textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16));
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new AbstractAction("Get Player Information") {
#Override
public void actionPerformed(ActionEvent arg0) {
int result = JOptionPane.showConfirmDialog(null, playerEditorPanel,
"Edit Player JOptionPane", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
for (PlayerEditorPanel.FieldTitle fieldTitle : PlayerEditorPanel.FieldTitle
.values()) {
textArea.append(String.format("%10s: %s%n",
fieldTitle.getTitle(),
playerEditorPanel.getFieldText(fieldTitle)));
}
}
}
}));
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
add(new JScrollPane(textArea), BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
ComplexOptionPane mainPanel = new ComplexOptionPane();
JFrame frame = new JFrame("ComplexOptionPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
enum FieldTitle {
NAME("Name"), SPEED("Speed"), STRENGTH("Strength"), HEALTH("Health");
private String title;
private FieldTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
};
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FieldTitle.values().length; i++) {
FieldTitle fieldTitle = FieldTitle.values()[i];
gbc = createGbc(0, i);
add(new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT), gbc);
gbc = createGbc(1, i);
JTextField textField = new JTextField(10);
add(textField, gbc);
fieldMap.put(fieldTitle, textField);
}
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public String getFieldText(FieldTitle fieldTitle) {
return fieldMap.get(fieldTitle).getText();
}
}
Also -- this answer
An MCVE using your code example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.Border;
public class Foo1 {
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private JPanel dialogPanel;
private JTextField creditCardNoInput;
private JTextField sortCodeInput;
private JTextField secNoInput;
private JTextField cardHolderName;
public Foo1() {
dialogPanel = new JPanel(new GridBagLayout());
Border titleBorder = BorderFactory.createTitledBorder("Credit Card Information");
Border emptyBorder = BorderFactory.createEmptyBorder(10, 10, 10, 10);
Border combinedBorder = BorderFactory.createCompoundBorder(titleBorder, emptyBorder);
dialogPanel.setBorder(combinedBorder);
creditCardNoInput = new JTextField(5);
sortCodeInput = new JTextField(5);
secNoInput = new JTextField(5);
cardHolderName = new JTextField(5);
dialogPanel.add(new JLabel("Credit Card Number:"), createGbc(0, 0));
dialogPanel.add(creditCardNoInput, createGbc(1, 0));
dialogPanel.add(new JLabel("Sort Code:"), createGbc(0, 1));
dialogPanel.add(sortCodeInput, createGbc(1, 1));
dialogPanel.add(new JLabel("Second Number:"), createGbc(0, 2));
dialogPanel.add(secNoInput, createGbc(1, 2));
dialogPanel.add(new JLabel("Cardholder Name:"), createGbc(0, 3));
dialogPanel.add(cardHolderName, createGbc(1, 3));
int result = JOptionPane.showConfirmDialog(null, dialogPanel,
"Please Enter your card details", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// Execute desired code
}
}
private static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
private static void createAndShowGui() {
new Foo1();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Solution:
When I was running my code, for some reason it was preferring my other GUI to start up. I only found this out when I commented out the code and the JOptionPane was still executing, so I manually selected my GUI, ran it, and the 4 boxed appeared.
P.S Please vote this answer so that I can get a badge. Thanks! :)

Providing white space in a Swing GUI

A GUI with no white space appears 'crowded'. How can I provide white space without resorting to explicitly setting the position or size of components?­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
Using various LayoutManagers one can provide spacing between various components.
1.) BorderLayout :
Overloaded Constructor : BorderLayout(int horizontalGap, int verticalGap)
Getter and setter methods
For Horizontal Spacing : BorderLayout.getHgap() and BorderLayout.setHgap(int hgap)
For Vertical Spacing : BorderLayout.getVgap() and BorderLayout.setVgap()
2.) FlowLayout :
Overloaded Constructor : FlowLayout(int align, int hgap, int vgap)
Getter and setter methods
For Horizontal Spacing : FlowLayout.getHgap() and FlowLayout.setHgap(int hgap)
For Vertical Spacing : FlowLayout.getVgap() and FlowLayout.setVgap()
3.) GridLayout :
Overloaded Constructor : GridLayout(int rows, int columns, int hgap, int vgap)
Getter and setter methods
For Horizontal Spacing : GridLayout.getHgap() and GridLayout.setHgap(int hgap)
For Vertical Spacing : GridLayout.getVgap() and GridLayout.setVgap()
4.) GridBagLayout :
GridBagConstraints.insets
5.) CardLayout (example) :
CardLayout(int hGap, int vGap)
Example to display all constructors in action :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LayoutExample {
private final int hGap = 5;
private final int vGap = 5;
private String[] borderConstraints = {
BorderLayout.PAGE_START,
BorderLayout.LINE_START,
BorderLayout.CENTER,
BorderLayout.LINE_END,
BorderLayout.PAGE_END
};
private JButton[] buttons;
private GridBagConstraints gbc;
private JPanel borderPanel;
private JPanel flowPanel;
private JPanel gridPanel;
private JPanel gridBagPanel;
private JPanel cardPanel;
public LayoutExample() {
buttons = new JButton[16];
gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.insets = new Insets(hGap, vGap, hGap, vGap);
}
private void displayGUI() {
JFrame frame = new JFrame("Layout Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(
new GridLayout(0, 1, hGap, vGap));
contentPane.setBorder(
BorderFactory.createEmptyBorder(hGap, vGap, hGap, vGap));
borderPanel = new JPanel(new BorderLayout(hGap, vGap));
borderPanel.setBorder(
BorderFactory.createTitledBorder("BorderLayout"));
borderPanel.setOpaque(true);
borderPanel.setBackground(Color.WHITE);
for (int i = 0; i < 5; i++) {
buttons[i] = new JButton(borderConstraints[i]);
borderPanel.add(buttons[i], borderConstraints[i]);
}
contentPane.add(borderPanel);
flowPanel = new JPanel(new FlowLayout(
FlowLayout.CENTER, hGap, vGap));
flowPanel.setBorder(
BorderFactory.createTitledBorder("FlowLayout"));
flowPanel.setOpaque(true);
flowPanel.setBackground(Color.WHITE);
for (int i = 5; i < 8; i++) {
buttons[i] = new JButton(Integer.toString(i));
flowPanel.add(buttons[i]);
}
contentPane.add(flowPanel);
gridPanel = new JPanel(new GridLayout(2, 2, hGap, vGap));
gridPanel.setBorder(
BorderFactory.createTitledBorder("GridLayout"));
gridPanel.setOpaque(true);
gridPanel.setBackground(Color.WHITE);
for (int i = 8; i < 12; i++) {
buttons[i] = new JButton(Integer.toString(i));
gridPanel.add(buttons[i]);
}
contentPane.add(gridPanel);
gridBagPanel = new JPanel(new GridBagLayout());
gridBagPanel.setBorder(
BorderFactory.createTitledBorder("GridBagLayout"));
gridBagPanel.setOpaque(true);
gridBagPanel.setBackground(Color.WHITE);
buttons[12] = new JButton(Integer.toString(12));
addComp(gridBagPanel, buttons[12], 0, 0, 1, 1
, GridBagConstraints.BOTH, 0.33, 0.5);
buttons[13] = new JButton(Integer.toString(13));
addComp(gridBagPanel, buttons[13], 1, 0, 1, 1
, GridBagConstraints.BOTH, 0.33, 0.5);
buttons[14] = new JButton(Integer.toString(14));
addComp(gridBagPanel, buttons[14], 0, 1, 2, 1
, GridBagConstraints.BOTH, 0.66, 0.5);
buttons[15] = new JButton(Integer.toString(15));
addComp(gridBagPanel, buttons[15], 2, 0, 1, 2
, GridBagConstraints.BOTH, 0.33, 1.0);
contentPane.add(gridBagPanel);
cardPanel = new JPanel(new CardLayout(hGap, vGap));
cardPanel.setBorder(
BorderFactory.createTitledBorder("CardLayout"));
cardPanel.setOpaque(true);
cardPanel.setBackground(Color.WHITE);
cardPanel.add(getPanel(Color.BLUE));
cardPanel.add(getPanel(Color.GREEN));
contentPane.add(cardPanel);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel getPanel(Color bColor) {
JPanel panel = new JPanel(new FlowLayout(
FlowLayout.CENTER, hGap, vGap));
panel.setOpaque(true);
panel.setBackground(bColor.darker().darker());
JButton swapperButton = new JButton("Next");
swapperButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
CardLayout cardLayout = (CardLayout) cardPanel.getLayout();
cardLayout.next(cardPanel);
}
});
panel.add(swapperButton);
return panel;
}
private void addComp(JPanel panel, JComponent comp
, int x, int y, int gWidth
, int gHeight, int fill
, double weightx, double weighty) {
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = gWidth;
gbc.gridheight = gHeight;
gbc.fill = fill;
gbc.weightx = weightx;
gbc.weighty = weighty;
panel.add(comp, gbc);
}
public static void main(String[] args) {
Runnable runnable = new Runnable(){
#Override
public void run() {
new LayoutExample().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
OUTPUT :
There are a number of ways in a Swing GUI to provide a separation between components, and white space around components:
JToolBar has the methods addSeparator() & addSeparator(Dimension).
JMenu uses a spacing component better suited to menus, available through addSeparator().
But more generally, look to:
The spacing as can be defined in the layout constructors.
Borders.
Here is an example of using the layout separator hGap & vGap values & borders (specifically an EmptyBorder) to provide 'white' (actually shown as red to make it very obvious) space. Adjust the spinners to see the result.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
public class WhiteSpace {
private JPanel gui = null;
private BorderLayout mainLayout =
new BorderLayout(0, 0);
private final FlowLayout buttonLayout =
new FlowLayout(FlowLayout.CENTER, 0, 0);
private final JPanel buttonPanel = new JPanel(buttonLayout);
private final SpinnerNumberModel hModel =
new SpinnerNumberModel(0, 0, 15, 1);
private final SpinnerNumberModel vModel =
new SpinnerNumberModel(0, 0, 15, 1);
private final SpinnerNumberModel hBorderModel =
new SpinnerNumberModel(0, 0, 15, 1);
private final SpinnerNumberModel vBorderModel =
new SpinnerNumberModel(0, 0, 15, 1);
private ChangeListener changeListener;
public Container getGui() {
if (gui == null) {
gui = new JPanel(mainLayout);
gui.setBackground(Color.RED);
JTree tree = new JTree();
tree.setVisibleRowCount(10);
for (int ii = tree.getRowCount(); ii > -1; ii--) {
tree.expandRow(ii);
}
gui.add(new JScrollPane(
tree,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
BorderLayout.LINE_START);
gui.add(new JScrollPane(new JTextArea(10, 30)));
gui.add(buttonPanel, BorderLayout.PAGE_START);
changeListener = (ChangeEvent e) -> {
int hGap = hModel.getNumber().intValue();
int vGap = vModel.getNumber().intValue();
int hBorder = hBorderModel.getNumber().intValue();
int vBorder = vBorderModel.getNumber().intValue();
adjustWhiteSpace(hGap, vGap, hBorder, vBorder);
};
addModel("H Gap", hModel);
addModel("V Gap", vModel);
addModel("H Border", hBorderModel);
addModel("V Border", vBorderModel);
}
return gui;
}
private void addModel(String label, SpinnerNumberModel model) {
buttonPanel.add(new JLabel(label));
final JSpinner spinner = new JSpinner(model);
spinner.addChangeListener(changeListener);
buttonPanel.add(spinner);
}
private void adjustWhiteSpace(
int hGap, int vGap, int hBorder, int vBorder) {
mainLayout.setHgap(hGap);
mainLayout.setVgap(vGap);
buttonLayout.setHgap(hGap);
gui.setBorder(new EmptyBorder
(vBorder, hBorder, vBorder, hBorder));
Container c = gui.getTopLevelAncestor();
if (c instanceof Window) {
Window w = (Window) c;
w.pack();
}
}
public static void main(String[] args) {
Runnable r = () -> {
WhiteSpace ws = new WhiteSpace();
Container gui1 = ws.getGui();
JFrame f = new JFrame("White (OK Red) Space");
f.add(gui1);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setResizable(false);
f.pack();
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
When you use BoxLayout, Box.createVerticalGlue() method can help you to make some white space.
Another method is BorderFactory.createEmptyBorder(int top, int left, int bottom, int right). It can help you to make some white space around component.
Thanks for Andrew Thompson's remind.I've revised BoxLayout in recent days and I find that Box.createVerticalGlue() can add some white space depend on the panel's size and you can not set the explicit pixel value of the length of white space.But Box.createVerticalStrut() can do that. Here is a MCTaRE and show the effect of those two methods.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
public class WhiteSpace extends JFrame{
static WhiteSpace whiteSpace;
DemoPanel demoPanel;
boolean withGlue;
JSpinner spinner;
public WhiteSpace(){
initialWindow();
demoPanel = new DemoPanel();
ActionPanel actionPanel = new ActionPanel();
setLayout(new BorderLayout());
getContentPane().add(actionPanel,BorderLayout.NORTH);
getContentPane().add(demoPanel,BorderLayout.CENTER);
setVisible(true);
}
public void initialWindow(){
setSize(220, 300);
setTitle("White Space");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
//Show the window in the middle of the screen
}
/**
* #param args
*/
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
whiteSpace = new WhiteSpace();
}
};
SwingUtilities.invokeLater(runnable);
}
class DemoPanel extends JPanel{
//Show the vertical white space between label1 and label2
JLabel label1;
JLabel label2;
public void initialDemoPanel(){
setBorder(BorderFactory.createTitledBorder(getBorder(), "DemoPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
label1 = new JLabel("This is first line");
label2 = new JLabel("This is second line");
}
public DemoPanel(){
initialDemoPanel();
add(label1);
if(withGlue){
add(Box.createVerticalGlue());
}
add(label2);
}
public DemoPanel(int strutValue){
initialDemoPanel();
add(label1);
add(Box.createVerticalStrut(strutValue));
add(label2);
}
}
class ActionPanel extends JPanel{
public ActionPanel(){
setBorder(BorderFactory.createTitledBorder(getBorder(), "ActionPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray));
setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
JRadioButton glueButton = new JRadioButton("With Glue");
glueButton.addActionListener(new glueButtonListener());
add(glueButton);
add(Box.createHorizontalStrut(10));
//To create horizontal white space
JLabel strutLabel = new JLabel("Strut Value");
add(strutLabel);
spinner = new JSpinner(new SpinnerNumberModel(0,0,50,1));
spinner.addChangeListener(new spinnerListener());
add(spinner);
//public SpinnerNumberModel(Number value,Comparable minimum,Comparable maximum,Number stepSize)
}
}
class glueButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
spinner.setValue(new Integer(0));
withGlue = (withGlue == true ? false:true);
whiteSpace.getContentPane().remove(demoPanel);
demoPanel = new DemoPanel();
whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER);
whiteSpace.getContentPane().validate();
}
}
class spinnerListener implements ChangeListener{
#Override
public void stateChanged(ChangeEvent e) {
int strutValue = (Integer) spinner.getValue();
whiteSpace.getContentPane().remove(demoPanel);
demoPanel = new DemoPanel(strutValue);
whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER);
whiteSpace.getContentPane().validate();
}
}
}
Box.createHorizontalGlue() and Box.createHorizontalStrut(int height) can be used too. Besides, Box.createRigidArea(Dimension d) has the ability too create white space too.
MigLayout has multiple ways of creating space. (A space is called a gap in this layout.)
Gaps can be created at the highest level with layout constraints, it is possible to
create gaps between rows and column and gaps can be also set between individual
components with component constraints. There are also specific gaps around the borders
of a container called insets which have their own specific keyword to be set.
The following example creates all these kinds of gaps:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutGaps2 extends JFrame {
public MigLayoutGaps2() {
initUI();
setTitle("Gaps");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15"));
setContentPane(base);
JPanel pnl1 = new JPanel();
pnl1.setBorder(
BorderFactory.createTitledBorder("Grid gaps")
);
pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3"));
pnl1.add(new JButton("1"));
pnl1.add(new JButton("2"));
pnl1.add(new JButton("3"));
pnl1.add(new JButton("4"));
pnl1.add(new JButton("5"));
pnl1.add(new JButton("6"));
JPanel pnl2 = new JPanel();
pnl2.setBorder(
BorderFactory.createTitledBorder("Column gaps")
);
pnl2.setLayout(new MigLayout("wrap 3", "[]10[]"));
JLabel lbl1 = new JLabel();
lbl1.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel lbl2 = new JLabel();
lbl2.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel lbl3 = new JLabel();
lbl3.setBorder(
BorderFactory.createEtchedBorder()
);
pnl2.add(lbl1, "w 40, h 110");
pnl2.add(lbl2, "w 40, h 110");
pnl2.add(lbl3, "w 40, h 110");
JPanel pnl3 = new JPanel();
pnl3.setBorder(
BorderFactory.createTitledBorder("Row gaps")
);
pnl3.setLayout(new MigLayout("wrap", "", "[]15[]"));
JLabel lbl4 = new JLabel();
lbl4.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel lbl5 = new JLabel();
lbl5.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel lbl6 = new JLabel();
lbl6.setBorder(
BorderFactory.createEtchedBorder()
);
pnl3.add(lbl4, "w 150, h 20");
pnl3.add(lbl5, "w 150, h 20");
pnl3.add(lbl6, "w 150, h 20");
JPanel pnl4 = new JPanel();
pnl4.setBorder(
BorderFactory.createTitledBorder("Component gaps")
);
pnl4.setLayout(new MigLayout());
pnl4.add(new JLabel("Name:"), "gapright 5");
pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20");
base.add(pnl1);
base.add(pnl2);
base.add(pnl3);
base.add(pnl4);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutGaps2 ex = new MigLayoutGaps2();
ex.setVisible(true);
}
});
}
}
We have four panels in the layout. Each of this panels has a MigLayout manager.
JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15"));
This line creates container insets and vertical gaps between panels.
pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3"));
Here we apply gaps for the whole grid structure and also set container gaps.
pnl2.setLayout(new MigLayout("wrap 3", "[]10[]"));
This line creates gaps between columns.
pnl3.setLayout(new MigLayout("wrap", "", "[]15[]"));
Row gaps are defined with this code.
pnl4.add(new JLabel("Name:"), "gapright 5");
pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20");
Finally, it is possible to create gaps between individual components.
JGoodies FormLayout.
Author Karsten Lentzsch has a collection of presentations on UI design. In particular this PDF speaks to the need for aesthetic whitespace. Adding meaningful space while also paying attention to clutter separates the wheat from the chaff.
Whenever I have this issue, I just use JPanels. For example in a GridLayout:
JFrame frame = new JFrame;
frame.setLayout(new GridLayout(2, 0));
//We want the bottom left to be blank
frame.add(new JLabel("Top Left"));
frame.add(new JLabel("Top Right"));
//This is the position we want empty
frame.add(new JPanel());
//Now we can continue with the rest of the script

Categories

Resources