Providing white space in a Swing GUI
There are a number of ways in a Swing GUI to provide a separation between components, and white space around components:
JToolBar
has the methodsaddSeparator()
&addSeparator(Dimension)
.JMenu
uses a spacing component better suited to menus, available throughaddSeparator()
.
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);
}
}
Weird white space in a java JFrame
The problem is because a JScrollPane
also has a border.
In this case you can remove it with:
JScrollPane scroll = new JScrollPane(textArea);
scroll.setBorder(null);
And adding the JScrollPane
to your frame as:
frame.getContentPane().add(textArea, BorderLayout.CENTER);
But that will remove the border between the button and the text area
So you need to create a MatteBorder
on the top of your JButton
:
button.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.white));
So it will look like this:
I had forgotten to place how I ran your code in my own main
method, because you forgot to add it as part of your MCVE:
It will place the program on the Event Dispatch Thread (EDT)
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ConsoleWindow();
}
});
}
Swing - After setVisible(false) white space remains
I used BoxLayout and my problem solved :
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));
GUI: how to properly set layout
GridBagLayout
as proposed in this answer can give all the control you need for the left part.
If you are willing to sacrifice some control for the sake of simplicity, you can get away with two FlowLayout
panels inside a GridLayout
:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
class Grid extends JFrame
{
private JTextField t1, t2;
private JCheckBox c1, c2;
private JButton b1, b2, b3;
private JPanel topPanel, bottomPanel;
private JPanel eastPanel, centerPanel;
private JLabel l1, l2;
public Grid()
{
c1 = new JCheckBox("Snap to Grid");
l1 = new JLabel("X:");
t1 = new JTextField("8",3);
topPanel = new JPanel();//uses flow layout by default
topPanel.add(c1); topPanel.add(l1); topPanel.add(t1);
c2 = new JCheckBox("Show Grid");
l2 = new JLabel("Y:");
t2 = new JTextField("8",3);
bottomPanel = new JPanel();
bottomPanel.add(c2); bottomPanel.add(l2); bottomPanel.add(t2);
centerPanel = new JPanel(new GridLayout(2,1));
centerPanel.add(topPanel);
centerPanel.add(bottomPanel);
add(centerPanel,BorderLayout.CENTER);
b1 = new JButton("Ok");
b2 = new JButton("Cancel");
b3 = new JButton("Help");
eastPanel = new JPanel(new GridLayout(3,1));
eastPanel.add(b1);
eastPanel.add(b2);
eastPanel.add(b3);
add(eastPanel, BorderLayout.EAST);
}
public static void main(String[] args) {
Grid app = new Grid();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(300,150);
app.setVisible(true);
}
}
More examples of applying this strategy: 1 2 and 3
Have Swing GUI elements, without large spaces
You need to use a layout manager that works the way you expect it to. There are several managers included with Java and I recommend you start here:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
This will give you a good visual introduction to the various layout managers and should give you the foundation you need to pick the right one.
Related Topics
How to Access the Java Method in a C++ Application
Nullpointerexception Accessing Views in Oncreate()
How to Pass a Bitmap Object from One Activity to Another
Json Array Iteration in Android/Java
Android Studio Gradle Project "Unable to Start the Daemon Process /Initialization of Vm"
How to Execute Python Script from Java (Via Command Line)
Why Use Getters and Setters/Accessors
Understanding Checked VS Unchecked Exceptions in Java
How to Retrieve and Display Images from a Database in a Jsp Page
How to Solve "Java.Lang.Noclassdeffounderror"
Is Short Circuit Evaluation Guaranteed in C++ as It Is in Java
How to Check Internet Access on Android? Inetaddress Never Times Out
Inner Class Can Access But Not Update Values - Asynctask
Android Activity Classnotfoundexception - Tried Everything
Java Using Much More Memory Than Heap Size (Or Size Correctly Docker Memory Limit)
Rjava Load Error in Rstudio/R After "Upgrading" to Osx Yosemite
Difference Between Public, Protected, Package-Private and Private in Java