when I compile and run my code everything seems to work fine except the JButton does not appear. I'm adding it to a JPanel that is on the frame. I'm new so I might not know what to lookout for here. Thanks!
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
public class TemperatureConverter extends JFrame{
//declarations
private JLabel celJLabel, farJLabel;
private JTextField celJTextField, farJTextField;
private JSlider sliderJSlider;
private JButton closeButton;
private TitledBorder border;
private JPanel topPanel, bottomPanel;
double celsiusDegrees, farenheitDegrees, sliderValue;
DecimalFormat decimalFormat = new DecimalFormat("#.0");
public TemperatureConverter()
{
createUserInterface();
}
public void createUserInterface()
{
//create the JFrame
Container frame = getContentPane();
frame.setBackground(Color.white);
frame.setLayout(null);
border = new TitledBorder("Convert between C & F");
border.setTitleColor(Color.black);
border.setTitleFont(new Font("Default", Font.ITALIC, 12));
border.setTitleJustification(TitledBorder.LEFT);
border.setTitlePosition(TitledBorder.TOP);
topPanel = new JPanel();
topPanel.setBounds(20,10,360,300);
topPanel.setForeground(Color.black);
topPanel.setBackground(Color.white);
topPanel.setLayout(null);
topPanel.setBorder(border);
frame.add(topPanel);
bottomPanel = new JPanel();
bottomPanel.setBounds(20,310,360,50);
bottomPanel.setForeground(Color.black);
bottomPanel.setBackground(Color.white);
bottomPanel.setLayout(null);
frame.add(bottomPanel);
celJLabel = new JLabel();
celJLabel.setBounds(120, 200, 60, 20);
celJLabel.setBackground(Color.white);
celJLabel.setFont(new Font("Default", Font.PLAIN, 12));
celJLabel.setText("Celcius");
celJLabel.setHorizontalAlignment(JLabel.LEFT);
topPanel.add(celJLabel);
farJLabel = new JLabel();
farJLabel.setBounds(120, 220, 60, 20);
farJLabel.setBackground(Color.white);
farJLabel.setFont(new Font("Default", Font.PLAIN, 12));
farJLabel.setText("Faranheit");
farJLabel.setHorizontalAlignment(JLabel.LEFT);
topPanel.add(farJLabel);
celJTextField = new JTextField();
celJTextField.setBounds(195,200, 50, 15);
celJTextField.setFont(new Font("Default", Font.PLAIN, 12));
celJTextField.setHorizontalAlignment(JTextField.CENTER);
celJTextField.setForeground(Color.black);
celJTextField.setBackground(Color.white);
topPanel.add(celJTextField);
farJTextField = new JTextField();
farJTextField.setBounds(195,225, 50, 15);
farJTextField.setFont(new Font("Default", Font.PLAIN, 12));
farJTextField.setHorizontalAlignment(JTextField.CENTER);
farJTextField.setForeground(Color.black);
farJTextField.setBackground(Color.white);
topPanel.add(farJTextField);
sliderJSlider = new JSlider(JSlider.HORIZONTAL, 0,100,0);
sliderJSlider.setBounds(20, 20, 310, 120);
sliderJSlider.setMajorTickSpacing(10);
sliderJSlider.setMinorTickSpacing(5);
sliderJSlider.setPaintTicks(true);
sliderJSlider.setPaintLabels(true);
sliderJSlider.setForeground(Color.black);
sliderJSlider.setBackground(Color.white);
topPanel.add(sliderJSlider);
sliderJSlider.addChangeListener(
new ChangeListener()
{
public void stateChanged(ChangeEvent event)
{
sliderStateChanged(event);
}
}
);
closeButton = new JButton();
closeButton.setBounds(140, 250, 75, 20);
closeButton.setFont(new Font("Default", Font.PLAIN,12));
closeButton.setText("Close");
closeButton.setForeground(Color.black);
closeButton.setBackground(Color.white);
bottomPanel.add(closeButton);
closeButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
closeActionPerformed(event);
}
}
);
setTitle("Temperature Converter");
setSize(400,400);
setVisible(true);
}
public static void main(String[] args)
{
TemperatureConverter application = new TemperatureConverter();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void sliderStateChanged(ChangeEvent event)
{
farenheitDegrees = sliderJSlider.getValue();
calculateCelsiusTemperature();
}
public void calculateCelsiusTemperature()
{
celsiusDegrees = (farenheitDegrees - 32)*5.0/9.0;
outputTemps();
}
public void outputTemps()
{
celJTextField.setText(decimalFormat.format(celsiusDegrees));
farJTextField.setText(decimalFormat.format(farenheitDegrees));
}
public void closeActionPerformed(ActionEvent event)
{
TemperatureConverter.this.dispose();
}
}
I'd follow the advice from the comments, use a proper layout manager.
The actual fault, is the placement of the close button within the bottom panel.
closeButton.setBounds(140, 250, 75, 20);
This might be a typo or a misunderstanding of the coordinate system, each new panel has its own private system where (0,0) is the top left of at component. The button is at (140, 250), however bottomPanel is only 360 x 50, so it is outside the visible bounds..
Try changing to
closeButton.setBounds(0, 0, 75, 20);
Your first and major mistake is this: topPanel.setLayout(null);. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
The solution is simple: learn about and how to use the layout managers, and then use them. You can find links to the Swing tutorials including those for the layout managers and other Swing resources here: Swing Info
e.g.,
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class TempConverter extends JPanel {
private static final int PREF_W = 400;
private static final int GAP = 5;
private JTextField celJTextField = new JTextField(10);
private JTextField farJTextField = new JTextField(10);
private JSlider sliderJSlider = new JSlider(0, 100, 0);
private JButton closeButton = new JButton("Close");
public TempConverter() {
sliderJSlider.setMajorTickSpacing(10);
sliderJSlider.setMinorTickSpacing(5);
sliderJSlider.setPaintTicks(true);
sliderJSlider.setPaintLabels(true);
JPanel textFieldPanel = new JPanel(new GridBagLayout());
textFieldPanel.add(new JLabel("Celcius:"), createGbc(0, 0));
textFieldPanel.add(celJTextField, createGbc(1, 0));
textFieldPanel.add(new JLabel("Faranheit:"), createGbc(0, 1));
textFieldPanel.add(farJTextField, createGbc(1, 1));
JPanel textFieldWrapperPanel = new JPanel(new GridBagLayout());
textFieldWrapperPanel.add(textFieldPanel);
JPanel conversionPanel = new JPanel(new BorderLayout());
conversionPanel.setBorder(BorderFactory.createTitledBorder("Foo"));
conversionPanel.setLayout(new BorderLayout());
conversionPanel.add(sliderJSlider, BorderLayout.PAGE_START);
conversionPanel.add(textFieldWrapperPanel, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
bottomPanel.add(closeButton);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout());
add(conversionPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
return gbc;
}
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
;
if (isPreferredSizeSet()) {
super.getPreferredSize();
}
int prefW = Math.max(PREF_W, superSize.width);
return new Dimension(prefW, superSize.height);
}
private static void createAndShowGui() {
TempConverter mainPanel = new TempConverter();
JFrame frame = new JFrame("TempConverter");
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();
}
});
}
}
Now you might say that this looks more complicated, and perhaps it is, but what happens when you want to add another JTextField and JLabel to represent the Kelvin temperature scale? For your GUI, you'll need to resize the GUI and recalculate the position of any component that may be effected by adding the new components. For my GUI, you just need to add a few new lines, and the chance of the changes causing a bug in my code is much smaller than that of your changes. e.g. please note the changes below just require 3 lines of code. Everything else remains the same:
public class TempConverter extends JPanel {
private static final int PREF_W = 400;
private static final int GAP = 5;
private JTextField celJTextField = new JTextField(10);
private JTextField farJTextField = new JTextField(10);
private JTextField KelvinJTextField = new JTextField(10); // !!! Added
private JSlider sliderJSlider = new JSlider(0, 100, 0);
private JButton closeButton = new JButton("Close");
public TempConverter() {
sliderJSlider.setMajorTickSpacing(10);
sliderJSlider.setMinorTickSpacing(5);
sliderJSlider.setPaintTicks(true);
sliderJSlider.setPaintLabels(true);
JPanel textFieldPanel = new JPanel(new GridBagLayout());
textFieldPanel.add(new JLabel("Celcius:"), createGbc(0, 0));
textFieldPanel.add(celJTextField, createGbc(1, 0));
textFieldPanel.add(new JLabel("Faranheit:"), createGbc(0, 1));
textFieldPanel.add(farJTextField, createGbc(1, 1));
// !!! added
textFieldPanel.add(new JLabel("Kelvin:"), createGbc(0, 2));
textFieldPanel.add(KelvinJTextField, createGbc(1, 2));
Related
I'm doing this as a challenge for myself. My problem is that when I click on the button, the content pane appears plain even if the JPanel has components in it.
I've tried adding the components on the frame but I get an error: >Cannot read field "parent" because "comp" is null.
I've tried other layout on JFrame and JPanel and still it didn't show.
Here's the full code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
public class test implements ActionListener{
public static void main(String [] args) {
new test();
}
static JPanel mainPanel, cubePanel;
static JFrame frame;
static Container container = new Container();
static JLabel calculatorFor;
static JButton sphereButton, rightCylinderButton, rightConeButton, rectangularPrismButton, triangularPrismButton,
cubeButton, squarePyramidButton, rectangularPyramidButton, ellipsoidButton, tetrahedronButton ,backToPreviousFrameButton;
static Font font = new Font(null, Font.PLAIN, 30);
static JLabel enterValueForEdge;
static JTextField edgeTextField;
static JTextArea surfaceAreaTextArea, surfaceAreaFormulaTextArea, surfaceAreaSolutionTextArea;
static JButton calculateButton;
static double edge;
static DecimalFormat surfaceAreaDecimal;
public test(){
frame = new JFrame("Calculating for Surface Area");
calculatorFor = new JLabel("Calculator for the Surface Area of:");
calculatorFor.setSize(600, 40);
calculatorFor.setLocation(100, 50);
calculatorFor.setFont(font);
calculatorFor.setFocusable(false);
sphereButton = new JButton("Sphere ");
sphereButton.setSize(400, 40);
sphereButton.setLocation(100, 100);
sphereButton.setFont(font);
sphereButton.addActionListener(this);
sphereButton.setFocusable(false);
rightCylinderButton = new JButton("Right Cylinder");
rightCylinderButton.setSize(400, 40);
rightCylinderButton.setLocation(100, 150);
rightCylinderButton.setFont(font);
rightCylinderButton.addActionListener(this);
rightCylinderButton.setFocusable(false);
rightConeButton = new JButton("Right Cone");
rightConeButton.setSize(400, 40);
rightConeButton.setLocation(100, 200);
rightConeButton.setFont(font);
rightConeButton.addActionListener(this);
rightConeButton.setFocusable(false);
rectangularPrismButton = new JButton("Rectangular Prism");
rectangularPrismButton.setSize(400, 40);
rectangularPrismButton.setLocation(100, 250);
rectangularPrismButton.setFont(font);
rectangularPrismButton.addActionListener(this);
rectangularPrismButton.setFocusable(false);
triangularPrismButton = new JButton("Triangular Prism");
triangularPrismButton.setSize(400, 40);
triangularPrismButton.setLocation(100, 300);
triangularPrismButton.setFont(font);
triangularPrismButton.addActionListener(this);
triangularPrismButton.setFocusable(false);
cubeButton = new JButton("Cube");
cubeButton.setSize(400, 40);
cubeButton.setLocation(100, 350);
cubeButton.setFont(font);
cubeButton.addActionListener(this);
cubeButton.setFocusable(false);
squarePyramidButton = new JButton("Square Pyramid");
squarePyramidButton.setSize(400, 40);
squarePyramidButton.setLocation(100, 400);
squarePyramidButton.setFont(font);
squarePyramidButton.addActionListener(this);
squarePyramidButton.setFocusable(false);
rectangularPyramidButton = new JButton("Rectangular Pyramid");
rectangularPyramidButton.setSize(400, 40);
rectangularPyramidButton.setLocation(100, 450);
rectangularPyramidButton.setFont(font);
rectangularPyramidButton.addActionListener(this);
rectangularPyramidButton.setFocusable(false);
ellipsoidButton = new JButton("Ellipsoid");
ellipsoidButton.setSize(400, 40);
ellipsoidButton.setLocation(100, 500);
ellipsoidButton.setFont(font);
ellipsoidButton.addActionListener(this);
ellipsoidButton.setFocusable(false);
tetrahedronButton = new JButton("Tetrahedron");
tetrahedronButton.setSize(400, 40);
tetrahedronButton.setLocation(100, 550);
tetrahedronButton.setFont(font);
tetrahedronButton.addActionListener(this);
tetrahedronButton.setFocusable(false);
backToPreviousFrameButton = new JButton("Back");
backToPreviousFrameButton.setSize(100, 40);
backToPreviousFrameButton.setLocation(900, 600);
backToPreviousFrameButton.setFont(font);
backToPreviousFrameButton.addActionListener(this);
backToPreviousFrameButton.setFocusable(false);
mainPanel = new JPanel();
mainPanel.setBounds(0, 0, 1080, 720);
mainPanel.setLayout(null);
mainPanel.setBackground(Color.decode("#FAF7FC"));
mainPanel.add(calculatorFor);
mainPanel.add(sphereButton);
mainPanel.add(rightCylinderButton);
mainPanel.add(rightConeButton);
mainPanel.add(rectangularPrismButton);
mainPanel.add(triangularPrismButton);
mainPanel.add(cubeButton);
mainPanel.add(squarePyramidButton);
mainPanel.add(rectangularPyramidButton);
mainPanel.add(ellipsoidButton);
mainPanel.add(tetrahedronButton);
mainPanel.add(backToPreviousFrameButton);
frame.getContentPane().add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.decode("#FAF7FC"));
frame.setLayout(new BorderLayout());
frame.setSize(1080,720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public void cubePanel(){
enterValueForEdge = new JLabel("Enter Edge:");
enterValueForEdge.setSize(200, 40);
enterValueForEdge.setLocation(100, 50);
enterValueForEdge.setFont(font);
enterValueForEdge.setFocusable(false);
edgeTextField = new JTextField();
edgeTextField.setSize(400, 40);
edgeTextField.setLocation(300, 50);
edgeTextField.setFont(font);
calculateButton = new JButton("Calculate");
calculateButton.setSize(200, 40);
calculateButton.setLocation(100, 100);
calculateButton.setFont(font);
calculateButton.addActionListener(this);
calculateButton.setFocusable(false);
surfaceAreaFormulaTextArea = new JTextArea("SA = 6a²");
surfaceAreaFormulaTextArea.setSize(400, 40);
surfaceAreaFormulaTextArea.setLocation(100, 150);
surfaceAreaFormulaTextArea.setFont(font);
surfaceAreaFormulaTextArea.setEditable(false);
surfaceAreaTextArea = new JTextArea("SA: ");
surfaceAreaTextArea.setSize(500, 40);
surfaceAreaTextArea.setLocation(100, 200);
surfaceAreaTextArea.setFont(font);
surfaceAreaTextArea.setEditable(false);
surfaceAreaSolutionTextArea = new JTextArea();
surfaceAreaSolutionTextArea.setSize(900, 80);
surfaceAreaSolutionTextArea.setLocation(100, 250);
surfaceAreaSolutionTextArea.setFont(font);
surfaceAreaSolutionTextArea.setEditable(false);
surfaceAreaSolutionTextArea.setLineWrap(true);
backToPreviousFrameButton = new JButton("Back");
backToPreviousFrameButton.setSize(100, 40);
backToPreviousFrameButton.setLocation(900, 600);
backToPreviousFrameButton.setFont(font);
backToPreviousFrameButton.addActionListener(this);
backToPreviousFrameButton.setFocusable(false);
cubePanel = new JPanel();
cubePanel.setBounds(0, 0, 1080, 720);
cubePanel.setLayout(null);
cubePanel.setBackground(Color.decode("#FAF7FC"));
container = new Container();
cubePanel.add(enterValueForEdge);
cubePanel.add(edgeTextField);
cubePanel.add(calculateButton);
cubePanel.add(surfaceAreaFormulaTextArea);
cubePanel.add(surfaceAreaTextArea);
cubePanel.add(surfaceAreaSolutionTextArea);
cubePanel.add(backToPreviousFrameButton);
container.add(cubePanel);
container.setLayout(null);
container.setBackground(Color.decode("#FAF7FH"));
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == sphereButton){
new sphereFrame();
frame.dispose();
}
if(e.getSource() == rightCylinderButton){
new rightCylinderFrame();
frame.dispose();
}
if(e.getSource() == rightConeButton){
new rightConeFrame();
frame.dispose();
}
if(e.getSource() == rectangularPrismButton){
new rectangularPrismFrame();
frame.dispose();
}
if(e.getSource() == triangularPrismButton){
new triangularPrismFrame();
frame.dispose();
}
if(e.getSource() == cubeButton){
frame.getContentPane().removeAll();
frame.add(cubePanel);
frame.repaint();
frame.revalidate();
System.out.println("Remove");
frame.getContentPane().add(container);
}
}
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Laying Out Components Within a Container section.
Here's the GUI I created.
Press the "Cube" button to bring up the page for the cube calculation.
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
The JFrame has a default BorderLayout and holds the main JPanel. The main JPanel uses a CardLayout to display the various calculation JPanels. Using a CardLayout is much easier than managing multiple JFrames and provides a nicer user experience.
I used Swing layout managers to position the Swing components on the various JPanels.
The start JPanel consists of two subordinate JPanels. The title JPanel uses a FlowLayout to display the title. The button JPanel uses a GridLayout to display the various calculation JButtons. You can create complex JPanels by nesting multiple simple JPanels.
The cube calculation JPanel was the only one you had in your code, so it was the only one I created. I made it a method, but you can create a separate class for each of the calculations. The cube calculation JPanel uses a GridBagLayout to create a form-like JPanel. I used lambda expressions to create the ActionListener for each of the JButtons, since they were so simple.
I made the start JPanel button ActionListener a separate class just to get the code away from the for loop that creates the JButtons.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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 javax.swing.SwingUtilities;
public class CardLayoutGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new CardLayoutGUI());
}
private CardLayout cardLayout;
private JTextField edgeTextField, surfaceAreaSolutionTextField;
private JPanel mainPanel;
#Override
public void run() {
JFrame frame = new JFrame("Calculating for Surface Area");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.mainPanel = createMainPanel();
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
cardLayout = new CardLayout();
JPanel panel = new JPanel(cardLayout);
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
panel.add(createStartPanel(), "Start");
panel.add(createCubeCalculationPanel(), "Cube");
return panel;
}
private JPanel createStartPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
panel.add(createTitlePanel(), BorderLayout.NORTH);
panel.add(createButtonPanel(), BorderLayout.CENTER);
return panel;
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
Font font = new Font(Font.DIALOG, Font.PLAIN, 36);
JLabel label = new JLabel("Calculator for the Surface Area of:");
label.setFont(font);
panel.add(label);
return panel;
}
private JPanel createButtonPanel() {
String[] text = { "Sphere", "Right Cylinder", "Right Cone",
"Rectangular Prism", "Triangular Prism", "Cube",
"Square Pyramid", "Rectangular Pyramid", "Ellipsoid",
"Tetrahedron" };
JPanel panel = new JPanel(new GridLayout(0, 3, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
Font font = new Font(null, Font.PLAIN, 24);
ButtonListener listener = new ButtonListener();
for (String s : text) {
JButton button = new JButton(s);
button.addActionListener(listener);
button.setFont(font);
panel.add(button);
}
return panel;
}
private JPanel createCubeCalculationPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
Font titleFont = new Font(null, Font.PLAIN, 32);
Font font = new Font(null, Font.PLAIN, 16);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 5, 5, 5);
gbc.weighty = 1.0;
gbc.gridwidth = 2;
gbc.gridx = 0;
gbc.gridy = 0;
JLabel label = new JLabel("SA = 6a²");
label.setFont(titleFont);
panel.add(label, gbc);
gbc.gridwidth = 1;
gbc.gridy++;
label = new JLabel("Edge:");
label.setFont(font);
panel.add(label, gbc);
gbc.gridx++;
edgeTextField = new JTextField(10);
edgeTextField.setFont(font);
panel.add(edgeTextField, gbc);
gbc.gridx = 0;
gbc.gridy++;
label = new JLabel("SA:");
label.setFont(font);
panel.add(label, gbc);
gbc.gridx++;
surfaceAreaSolutionTextField = new JTextField(10);
surfaceAreaSolutionTextField.setFont(font);
surfaceAreaSolutionTextField.setEditable(false);
panel.add(surfaceAreaSolutionTextField, gbc);
gbc.gridwidth = 2;
gbc.gridx = 0;
gbc.gridy++;
JButton calculateButton = new JButton("Calculate");
calculateButton.addActionListener(event -> {
double edge = Double.valueOf(edgeTextField.getText());
double sa = 6.0 * edge * edge;
surfaceAreaSolutionTextField.setText(Double.toString(sa));
});
calculateButton.setFont(font);
panel.add(calculateButton, gbc);
gbc.gridy++;
JButton backButton = new JButton("Back");
backButton.addActionListener(event -> {
cardLayout.show(mainPanel, "Start");
});
backButton.setFont(font);
panel.add(backButton, gbc);
return panel;
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
String text = button.getText();
cardLayout.show(mainPanel, text);
}
}
}
Try this :
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
public class Test2 implements ActionListener {
public static void main(String[] args) {
new Test2();
}
static JPanel mainPanel, cubePanel;
static JFrame frame;
static Container container = new Container();
static JLabel calculatorFor;
static JButton sphereButton, rightCylinderButton, rightConeButton, rectangularPrismButton, triangularPrismButton,
cubeButton, squarePyramidButton, rectangularPyramidButton, ellipsoidButton, tetrahedronButton, backToPreviousFrameButton;
static Font font = new Font(null, Font.PLAIN, 30);
static JLabel enterValueForEdge;
static JTextField edgeTextField;
static JTextArea surfaceAreaTextArea, surfaceAreaFormulaTextArea, surfaceAreaSolutionTextArea;
static JButton calculateButton;
static double edge;
static DecimalFormat surfaceAreaDecimal;
public Test2() {
frame = new JFrame("Calculating for Surface Area");
calculatorFor = new JLabel("Calculator for the Surface Area of:");
calculatorFor.setSize(600, 40);
calculatorFor.setLocation(100, 50);
calculatorFor.setFont(font);
calculatorFor.setFocusable(false);
sphereButton = new JButton("Sphere ");
sphereButton.setSize(400, 40);
sphereButton.setLocation(100, 100);
sphereButton.setFont(font);
sphereButton.addActionListener(this);
sphereButton.setFocusable(false);
rightCylinderButton = new JButton("Right Cylinder");
rightCylinderButton.setSize(400, 40);
rightCylinderButton.setLocation(100, 150);
rightCylinderButton.setFont(font);
rightCylinderButton.addActionListener(this);
rightCylinderButton.setFocusable(false);
rightConeButton = new JButton("Right Cone");
rightConeButton.setSize(400, 40);
rightConeButton.setLocation(100, 200);
rightConeButton.setFont(font);
rightConeButton.addActionListener(this);
rightConeButton.setFocusable(false);
rectangularPrismButton = new JButton("Rectangular Prism");
rectangularPrismButton.setSize(400, 40);
rectangularPrismButton.setLocation(100, 250);
rectangularPrismButton.setFont(font);
rectangularPrismButton.addActionListener(this);
rectangularPrismButton.setFocusable(false);
triangularPrismButton = new JButton("Triangular Prism");
triangularPrismButton.setSize(400, 40);
triangularPrismButton.setLocation(100, 300);
triangularPrismButton.setFont(font);
triangularPrismButton.addActionListener(this);
triangularPrismButton.setFocusable(false);
cubeButton = new JButton("Cube");
cubeButton.setSize(400, 40);
cubeButton.setLocation(100, 350);
cubeButton.setFont(font);
cubeButton.addActionListener(this);
cubeButton.setFocusable(false);
squarePyramidButton = new JButton("Square Pyramid");
squarePyramidButton.setSize(400, 40);
squarePyramidButton.setLocation(100, 400);
squarePyramidButton.setFont(font);
squarePyramidButton.addActionListener(this);
squarePyramidButton.setFocusable(false);
rectangularPyramidButton = new JButton("Rectangular Pyramid");
rectangularPyramidButton.setSize(400, 40);
rectangularPyramidButton.setLocation(100, 450);
rectangularPyramidButton.setFont(font);
rectangularPyramidButton.addActionListener(this);
rectangularPyramidButton.setFocusable(false);
ellipsoidButton = new JButton("Ellipsoid");
ellipsoidButton.setSize(400, 40);
ellipsoidButton.setLocation(100, 500);
ellipsoidButton.setFont(font);
ellipsoidButton.addActionListener(this);
ellipsoidButton.setFocusable(false);
tetrahedronButton = new JButton("Tetrahedron");
tetrahedronButton.setSize(400, 40);
tetrahedronButton.setLocation(100, 550);
tetrahedronButton.setFont(font);
tetrahedronButton.addActionListener(this);
tetrahedronButton.setFocusable(false);
backToPreviousFrameButton = new JButton("Back");
backToPreviousFrameButton.setSize(100, 40);
backToPreviousFrameButton.setLocation(900, 600);
backToPreviousFrameButton.setFont(font);
backToPreviousFrameButton.addActionListener(this);
backToPreviousFrameButton.setFocusable(false);
mainPanel = new JPanel();
mainPanel.setBounds(0, 0, 1080, 720);
mainPanel.setLayout(null);
mainPanel.setBackground(Color.decode("#FAF7FC"));
mainPanel.add(calculatorFor);
mainPanel.add(sphereButton);
mainPanel.add(rightCylinderButton);
mainPanel.add(rightConeButton);
mainPanel.add(rectangularPrismButton);
mainPanel.add(triangularPrismButton);
mainPanel.add(cubeButton);
mainPanel.add(squarePyramidButton);
mainPanel.add(rectangularPyramidButton);
mainPanel.add(ellipsoidButton);
mainPanel.add(tetrahedronButton);
mainPanel.add(backToPreviousFrameButton);
frame.getContentPane().add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.decode("#FAF7FC"));
frame.setLayout(new BorderLayout());
frame.setSize(1080, 720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public Container cubePanel() {
enterValueForEdge = new JLabel("Enter Edge:");
enterValueForEdge.setSize(200, 40);
enterValueForEdge.setLocation(100, 50);
enterValueForEdge.setFont(font);
enterValueForEdge.setFocusable(false);
edgeTextField = new JTextField();
edgeTextField.setSize(400, 40);
edgeTextField.setLocation(300, 50);
edgeTextField.setFont(font);
calculateButton = new JButton("Calculate");
calculateButton.setSize(200, 40);
calculateButton.setLocation(100, 100);
calculateButton.setFont(font);
calculateButton.addActionListener(this);
calculateButton.setFocusable(false);
surfaceAreaFormulaTextArea = new JTextArea("SA = 6a²");
surfaceAreaFormulaTextArea.setSize(400, 40);
surfaceAreaFormulaTextArea.setLocation(100, 150);
surfaceAreaFormulaTextArea.setFont(font);
surfaceAreaFormulaTextArea.setEditable(false);
surfaceAreaTextArea = new JTextArea("SA: ");
surfaceAreaTextArea.setSize(500, 40);
surfaceAreaTextArea.setLocation(100, 200);
surfaceAreaTextArea.setFont(font);
surfaceAreaTextArea.setEditable(false);
surfaceAreaSolutionTextArea = new JTextArea();
surfaceAreaSolutionTextArea.setSize(900, 80);
surfaceAreaSolutionTextArea.setLocation(100, 250);
surfaceAreaSolutionTextArea.setFont(font);
surfaceAreaSolutionTextArea.setEditable(false);
surfaceAreaSolutionTextArea.setLineWrap(true);
backToPreviousFrameButton = new JButton("Back");
backToPreviousFrameButton.setSize(100, 40);
backToPreviousFrameButton.setLocation(900, 600);
backToPreviousFrameButton.setFont(font);
backToPreviousFrameButton.addActionListener(this);
backToPreviousFrameButton.setFocusable(false);
cubePanel = new JPanel();
cubePanel.setBounds(0, 0, 1080, 720);
cubePanel.setLayout(null);
cubePanel.setBackground(Color.decode("#FAF7FC"));
container = new Container();
cubePanel.add(enterValueForEdge);
cubePanel.add(edgeTextField);
cubePanel.add(calculateButton);
cubePanel.add(surfaceAreaFormulaTextArea);
cubePanel.add(surfaceAreaTextArea);
cubePanel.add(surfaceAreaSolutionTextArea);
cubePanel.add(backToPreviousFrameButton);
container.add(cubePanel);
container.setLayout(null);
container.setBackground(Color.getColor("#FAF7FH"));
return container;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == sphereButton) {
new sphereFrame();
frame.dispose();
}
if (e.getSource() == rightCylinderButton) {
new rightCylinderFrame();
frame.dispose();
}
if (e.getSource() == rightConeButton) {
new rightConeFrame();
frame.dispose();
}
if (e.getSource() == rectangularPrismButton) {
new rectangularPrismFrame();
frame.dispose();
}
if (e.getSource() == triangularPrismButton) {
//new triangularPrismFrame();
frame.dispose();
}
if (e.getSource() == cubeButton) {
frame.getContentPane().removeAll();
frame.add(cubePanel());
frame.repaint();
frame.revalidate();
System.out.println("Remove");
frame.getContentPane().add(container);
}
}
}
I am making a form by using FlowLayout. The GUI of the form is shown below:
Name: <textField>
Age: <textfiedl>
Gender: Male[] Female[]
Email: <textField>
For gender, the options are radio buttons. As you can see, the labels for age and gender should be centered. How can I do this using FlowLayout?
This is one way (of a plethora of ways it might be done). Layout details in titled borders.
Note: For anything to do with selecting a number, it's better to offer the user a spinner.
If the whole form is created using BoxLayout, one oriented as BoxLayout.PAGE_AXIS, then if each "line" of the form is a JPanel that uses FlowLayout, the components that they held should be centered by default, since JPanel uses new FlowLayout(FlowLayout.CENTER, 5, 5) as its default layout (actually it uses new FlowLayout(), but the default values for this constructor are as above -- CENTER orientation with horizontal and vertical gaps of 5).
Another option is to use a GridBagLayout, and alter the constraints' FILL and weighty properties for the component on each row.
For example:
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.*;
public class LayoutExample extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField ageField = new JTextField(10);
private JTextField emailField = new JTextField(10);
private ButtonGroup sexBtnGroup = new ButtonGroup();
private JRadioButton maleBtn = new JRadioButton("Male");
private JRadioButton femaleBtn = new JRadioButton("Female");
public LayoutExample() {
JPanel agePanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
agePanel.add(new JLabel("Age:"));
agePanel.add(ageField);
sexBtnGroup.add(maleBtn);
sexBtnGroup.add(femaleBtn);;
JPanel sexSelectionPanel = new JPanel();
sexSelectionPanel.add(new JLabel("Select Sex:"));
sexSelectionPanel.add(maleBtn);
sexSelectionPanel.add(femaleBtn);
JPanel emailPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
emailPanel.add(new JLabel("Email:"));
emailPanel.add(emailField);
int gap = 10;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(agePanel);
add(Box.createVerticalStrut(5));
add(sexSelectionPanel);
add(Box.createVerticalStrut(5));
add(emailPanel);
}
// make it stretch horizontally to see placement
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
int width = (3 * superSize.width) / 2;
int height = superSize.height;
return new Dimension(width, height);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
LayoutExample mainPanel = new LayoutExample();
JFrame frame = new JFrame("LayoutExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
Example 2 using a GridBagLayout:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.*;
public class LayoutExample2 extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField ageField = new JTextField(10);
private JTextField emailField = new JTextField(10);
private ButtonGroup sexBtnGroup = new ButtonGroup();
private JRadioButton maleBtn = new JRadioButton("Male");
private JRadioButton femaleBtn = new JRadioButton("Female");
public LayoutExample2() {
JPanel sexSelectPanel = new JPanel(new GridLayout(1, 0, 5, 5));
sexBtnGroup.add(maleBtn);
sexSelectPanel.add(maleBtn);
sexBtnGroup.add(femaleBtn);
sexSelectPanel.add(femaleBtn);
int gap = 10;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new GridBagLayout());
add(new JLabel("Age:"), createGbc(0, 0));
add(ageField, createGbc(1, 0));
add(new JLabel("Sex:"), createGbc(0, 1));
add(sexSelectPanel, createGbc(1, 1));
add(new JLabel("Email:"), createGbc(0, 2));
add(emailField, createGbc(1, 2));
}
private static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
int ins = 4;
gbc.insets = new Insets(ins, ins, ins, ins);
gbc.fill = GridBagConstraints.HORIZONTAL;
return gbc;
}
// make it stretch horizontally to see placement
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
int width = (4 * superSize.width) / 3;
int height = superSize.height;
return new Dimension(width, height);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
LayoutExample2 mainPanel = new LayoutExample2();
JFrame frame = new JFrame("LayoutExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
Why GridLayot not working in Swing Java?
I need to place element at concrete cell, but they placing wrong (picture)
How to place elements to concrete cell in Java Swing with grid layout?
My code:
package com.KvaksManYT;
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame {
public GUI() {
super("Test");
setBounds(100, 100, 250, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = this.getContentPane();
container.setLayout(new GridLayout(3, 2, 2, 2));
container.add(but1, onPosition(1, 2));
container.add(but2, onPosition(2, 2));
container.add(but3, onPosition(1, 1));
container.add(but4, onPosition(2, 1));
}
private JButton but1 = new JButton("Press 1");
private JButton but2 = new JButton("Press 2");
private JButton but3 = new JButton("Press 3");
private JButton but4 = new JButton("Press 4");
private GridBagConstraints onPosition(int x, int y) {
GridBagConstraints layConstraints = new GridBagConstraints();
layConstraints.fill = GridBagConstraints.BOTH;
layConstraints.gridx = x;
layConstraints.gridy = y;
return layConstraints;
}
}
The GridBagConstraints is used for Grid Bag Layout, rather than Grid Layout.
You have to start counting at 0 too:
public class GUI extends JFrame {
public GUI() {
super("Test");
setBounds(100, 100, 250, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints layConstraints = new GridBagConstraints();
layConstraints.fill = GridBagConstraints.NONE;
layConstraints.insets = new Insets(3, 2, 2, 2);
Container container = this.getContentPane();
container.setLayout(new GridBagLayout());
container.add(but1, onPosition(0, 1, layConstraints));
container.add(but2, onPosition(1, 1, layConstraints));
container.add(but3, onPosition(0, 0, layConstraints));
container.add(but4, onPosition(1, 0, layConstraints));
}
I have the GUI displaying properly for the most part, except for one thing. The TitledBorder("Numeric Type") does not display the entire title for the right JPanel. I believe it has something to do with the BorderLayout Manager. Instead of displaying "Numeric Type" within the border, just "Numeric..." displays. Any help will be greatly appreciated.
public class P3GUI extends JFrame {
private JLabel originalList;
private JTextField originalSort;
private JLabel sortedList;
private JTextField newSort;
private JPanel panel;
private JButton performSort;
private JRadioButton ascending;
private JRadioButton descending;
private ButtonGroup sort;
private JRadioButton integer;
private JRadioButton fraction;
private ButtonGroup numType;
private JPanel inputPanel, outputPanel, calculatePanel, radioPanel;
private JPanel left, right;
public P3GUI () {
super("Binary Search Tree Sort");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
originalList = new JLabel("Original List");
originalSort = new JTextField(20);
inputPanel = new JPanel();
inputPanel.add(originalList);
inputPanel.add(originalSort);
sortedList = new JLabel("Sorted List");
newSort = new JTextField(20);
newSort.setEditable(false);
outputPanel = new JPanel();
outputPanel.add(sortedList);
outputPanel.add(newSort);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(inputPanel);
panel.add(outputPanel);
add(panel, BorderLayout.NORTH);
performSort = new JButton("Perform Sort");
calculatePanel = new JPanel();
calculatePanel.add(performSort);
add(calculatePanel, BorderLayout.CENTER);
ascending = new JRadioButton("Ascending");
descending = new JRadioButton("Descending");
sort = new ButtonGroup();
sort.add(ascending);
sort.add(descending);
integer = new JRadioButton("Integer");
fraction = new JRadioButton("Fraction");
numType = new ButtonGroup();
numType.add(integer);
numType.add(fraction);
radioPanel = new JPanel();
radioPanel.setLayout(new FlowLayout());
left = new JPanel();
left.setLayout(new GridLayout(2,1));
left.setBorder(BorderFactory.createTitledBorder("Sort Order"));
left.add(ascending);
left.add(descending);
right = new JPanel();
right.setLayout(new GridLayout(2,1));
right.setBorder(BorderFactory.createTitledBorder("Numeric Type"));
right.add(integer);
right.add(fraction);
radioPanel.add(left);
radioPanel.add(right);
add(radioPanel, BorderLayout.SOUTH);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new P3GUI().setVisible(true);
}
});
}
}
The problem is that the right JPanel is too small to display the entire title, and so it gets truncated. I'd suggest placing the bottom two JPanels into another that uses GridLayout, and then place them in such a way that they expand to fit the bottom of your GUI. When spread out, the title has a much greater chance of being fully displayed (but not a guarantee, mind you!).
For example, if you make the main GUI use a BorderLayout, and add this GridLayout using JPanel into the BorderLayout.CENTER position, it will fill it completely. Then the top components, the TextFields and JButton can be added to another JPanel, say one that uses a GridBagLayout, and add that to the main JPanel's BorderLayout.PAGE_START position.
For example, the following code produces this GUI:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class P3GUI2 extends JPanel {
private static final int COLS = 20;
private JTextField originalSort = new JTextField(COLS);
private JTextField newSort = new JTextField(COLS);
private JButton performSort = new JButton("Perform Sort");
private JRadioButton ascending = new JRadioButton("Ascending");
private JRadioButton descending = new JRadioButton("Descending");
private ButtonGroup sort = new ButtonGroup();
private JRadioButton integer = new JRadioButton("Integer");
private JRadioButton fraction = new JRadioButton("Fraction");
private ButtonGroup numType = new ButtonGroup();
public P3GUI2() {
JPanel topPanel = new JPanel(new GridBagLayout());
topPanel.add(new JLabel("Original List:"), createGbc(0, 0));
topPanel.add(originalSort, createGbc(1, 0));
topPanel.add(new JLabel("Sorted List:"), createGbc(0, 1));
topPanel.add(newSort, createGbc(1, 1));
performSort.setMnemonic(KeyEvent.VK_P);
JPanel btnPanel = new JPanel();
btnPanel.add(performSort);
JPanel sortOrderPanel = createTitlePanel("Sort Order");
JPanel numericPanel = createTitlePanel("Numeric Type");
sortOrderPanel.add(ascending);
sortOrderPanel.add(descending);
sort.add(ascending);
sort.add(descending);
numericPanel.add(integer);
numericPanel.add(fraction);
numType.add(integer);
numType.add(fraction);
JPanel radioPanels = new JPanel(new GridLayout(1, 0, 3, 3));
radioPanels.add(sortOrderPanel);
radioPanels.add(numericPanel);
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
setLayout(new BorderLayout(3, 3));
add(topPanel, BorderLayout.PAGE_START);
add(btnPanel, BorderLayout.CENTER);
add(radioPanels, BorderLayout.PAGE_END);
}
private JPanel createTitlePanel(String title) {
JPanel panel = new JPanel(new GridLayout(0, 1, 3, 3));
panel.setBorder(BorderFactory.createTitledBorder(title));
return panel;
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.insets = new Insets(3, 3, 3, 3);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
return gbc;
}
private static void createAndShowGui() {
P3GUI2 mainPanel = new P3GUI2();
JFrame frame = new JFrame("Binary Search Tree Sort");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Or you could place the above btnPanel into the main one BorderLayout.CENTER and then place the radioPanels into the main one BorderLayout.PAGE_END. This will display a GUI of the same appearance but it will expand differently if re-sized.
The preferred size of the panel (as determined by the layout manager) does not consider the size of the text in the TitledBorder so the title can get truncated.
Here is a custom JPanel that can be used with a TitleBorder. The getPreferredSize() method has been customized to use the maximum width of:
the default getPreferredSize() calculation
the width of the text in the TitledBorder
Here is a simple example:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TitledBorderPanel extends JPanel
{
/**
** The preferred width on the panel must consider the width of the text
** used on the TitledBorder
*/
#Override
public Dimension getPreferredSize()
{
Dimension preferredSize = super.getPreferredSize();
Border border = getBorder();
int borderWidth = 0;
if (border instanceof TitledBorder)
{
Insets insets = getInsets();
TitledBorder titledBorder = (TitledBorder)border;
borderWidth = titledBorder.getMinimumSize(this).width + insets.left + insets.right;
}
int preferredWidth = Math.max(preferredSize.width, borderWidth);
return new Dimension(preferredWidth, preferredSize.height);
}
private static void createAndShowGUI()
{
JPanel panel = new TitledBorderPanel();
panel.setBorder( BorderFactory.createTitledBorder("File Options Command List:") );
panel.setLayout( new BoxLayout(panel, BoxLayout.Y_AXIS) );
panel.add( new JLabel("Open") );
panel.add( new JLabel("Close") );
// panel.add( new JLabel("A really wierd file option longer than border title") );
JFrame frame = new JFrame("TitledBorderPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
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