I have a gui which has a Panel that contains a sequence of labels and TextFields and uses a spring layout(this is the mainPanel) and another Panel that just contains a button(buttonPanel). I am trying to make my mainPanel to have a vertical scrollbar as well. I would like to implement my GUI such that within the JFrame I have 2 panels. The mainPanel appears on the top of the frame and the buttonPanel appears below the mainPanel.
My problem is I am not able to make the Panels appear such that the buttonPanel is below the mainPanel and I am also not sure how to add a scrollbar to the mainPanel. Any help would be appreciated.
EDIT : I was able to solve my issue regarding the JPanels, now my only problem is that I cant get my mainPanel to scroll. I've added my most recent code below :
Here is the code I have so far:
public static void main(String args[]) {
JFrame frame = new JFrame("SpringLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scroll = new JScrollPane();
Container contentPane = frame.getContentPane();
JButton next = new JButton("Next");
JPanel buttonPanel = new JPanel();
buttonPanel.add(next);
SpringLayout layout = new SpringLayout();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(layout);
contentPane.setLayout(new BorderLayout());
int j = 25;
for(int i =0;i<150;i++){
JLabel label = new JLabel("Enter Name " + i );
JTextField text = new JTextField(15);
mainPanel.add(label);
mainPanel.add(text);
layout.putConstraint(SpringLayout.WEST, label, 10, SpringLayout.WEST,
contentPane);
layout.putConstraint(SpringLayout.NORTH, label, j, SpringLayout.NORTH,
contentPane);
layout.putConstraint(SpringLayout.NORTH, text, j, SpringLayout.NORTH,
contentPane);
layout.putConstraint(SpringLayout.WEST, text, 20, SpringLayout.EAST,
label);
j+=30;
}
//mainPanel.setSize(500,800);
scroll.setPreferredSize(new Dimension(500,500));
scroll.setViewportView(mainPanel);
contentPane.add(scroll);
contentPane.add(buttonPanel,BorderLayout.SOUTH);
//mainWindow.add(contentPane);
frame.setSize(500, 600);
frame.setVisible(true);
}
To make it scrollable I just needed to increase the preferred size of my mainPanel such that it would be bigger than the scrollbar.
public static void main(String args[]) {
JFrame frame = new JFrame("SpringLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scroll = new JScrollPane();
Container contentPane = frame.getContentPane();
JButton next = new JButton("Next");
JPanel buttonPanel = new JPanel();
buttonPanel.add(next);
SpringLayout layout = new SpringLayout();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(layout);
contentPane.setLayout(new BorderLayout());
int j = 25;
for(int i =0;i<18;i++){
JLabel label = new JLabel("Enter Name " + i );
JTextField text = new JTextField(15);
mainPanel.add(label);
mainPanel.add(text);
layout.putConstraint(SpringLayout.WEST, label, 10, SpringLayout.WEST,
contentPane);
layout.putConstraint(SpringLayout.NORTH, label, j, SpringLayout.NORTH,
contentPane);
layout.putConstraint(SpringLayout.NORTH, text, j, SpringLayout.NORTH,
contentPane);
layout.putConstraint(SpringLayout.WEST, text, 20, SpringLayout.EAST,
label);
j+=30;
}
mainPanel.setPreferredSize(new Dimension(mainPanel.getWidth(), 1500));
scroll.setPreferredSize(new Dimension(500,500));
scroll.setViewportView(mainPanel);
contentPane.add(scroll);
contentPane.add(buttonPanel,BorderLayout.SOUTH);
//mainWindow.add(contentPane);
frame.setSize(500, 600);
frame.setVisible(true);
}
I can't comment something, to try and compare
notice in this moment I don't understand why SpringLayout and JFrame#pack() doesn't build proper GUI based on PreferredSize, bump in this looks like as (in this moment) my issue too
code with hardcoded JFrame.setSize() instead of proper JFrame#pack()
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
public class Main {
public Main() {
JFrame frame = new JFrame("SpringLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton next = new JButton("Next");
JPanel buttonPanel = new JPanel();
buttonPanel.add(next);
SpringLayout layout = new SpringLayout();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(layout);
int j = 25;
for (int i = 0; i < 5; i++) {
JLabel label = new JLabel("Enter Name");
JTextField text = new JTextField(15);
layout.putConstraint(SpringLayout.WEST, label, 10, SpringLayout.WEST,
mainPanel);
layout.putConstraint(SpringLayout.NORTH, label, j, SpringLayout.NORTH,
mainPanel);
layout.putConstraint(SpringLayout.NORTH, text, j, SpringLayout.NORTH,
mainPanel);
layout.putConstraint(SpringLayout.WEST, text, 20, SpringLayout.EAST,
label);
j += 30;
mainPanel.add(label);
mainPanel.add(text);
}
frame.add(mainPanel, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Main mn = new Main();
}
});
}
}
This is how I would do it:
public static void main(String args[]) {
JFrame frame = new JFrame("SpringLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
JButton next = new JButton("Next");
JPanel buttonPanel = new JPanel();
buttonPanel.add(next);
GridBagLayout layout = new GridBagLayout();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(layout);
contentPane.setLayout(new BorderLayout());
GridBagConstraints gbc = new GridBagConstraints();
int j = 25;
for (int i = 0; i < 50; i++) {
JLabel label = new JLabel("Enter Name (" + i + ")");
JTextField text = new JTextField(15);
gbc.gridx = 0;
gbc.gridy = i;
mainPanel.add(label, gbc);
gbc.gridx = 1;
mainPanel.add(text, gbc);
}
contentPane.add(new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);
contentPane.add(buttonPanel, BorderLayout.SOUTH);
frame.setSize(500, 800);
frame.setVisible(true);
}
Few modifications:
* use GridBagLayout instead of SpringLayout (just because I don't know SpringLayout)
* wrap your mainPanel inside a JScrollPane
Does not look and feel exactly like your example. GridBagConstraints can be tuned.
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 trying to center components using a GridBagLayout in the same manner that a Box centers components when you use Box.createVerticalGlue(). I initially did use a vertical Box:
Box box = Box.createVerticalBox();
box.add(Box.createVerticalGlue());
box.add(add);
box.add(remove);
box.add(edit);
box.add(Box.createVerticalGlue());
JPanel internalPanel = new JPanel(new BorderLayout());
internalPanel.add(keywordsScrollPane, BorderLayout.CENTER);
internalPanel.add(box, BorderLayout.EAST);
But as you can see, it looks sloppy because my buttons are different sizes:
I decided to switch to GridBagLayout so I can utilize GridBagConstraints.fill. This approach fixes my button width issue, but I cannot figure out how to vertically center the buttons. I changed the grid size and placed the buttons in the middle three rows, but the buttons were still appearing at the top of the panel. I tried making use of GridBagConstraints.anchor and GridBagConstraints.weighty as well. The latter almost worked, but there are very large margins between the buttons:
I am looking for the buttons to be grouped together as they were in my Box approach. How can I achieve this with a GridBadLayout?
I am using a class I created called ConstraintsBuilder which works exactly as you would expect. It's for creating GridBagContraints with nice one-liners. Here is all the (relevant) code for your viewing pleasure:
public class KeywordsDialog extends JDialog implements ActionListener, ListSelectionListener {
private JList<String> keywords;
private JScrollPane keywordsScrollPane;
private JButton add;
private JButton remove;
private JButton edit;
private Set<String> keywordsList;
public KeywordsDialog(Window parent, Collection<String> keywordsList) {
super(parent);
this.keywordsList = keywordsList == null ? new HashSet<String>() : new HashSet<String>(keywordsList);
if (keywordsList != null && !keywordsList.isEmpty()) {
this.keywords = new JList<String>(toListModel(keywordsList));
} else {
this.keywords = new JList<String>(new DefaultListModel<String>());
}
this.keywordsScrollPane = new JScrollPane(keywords);
this.add = new JButton("Add");
this.remove = new JButton("Remove");
this.edit = new JButton("Edit");
this.edit.setEnabled(false);
this.add.setEnabled(false);
ConstraintsBuilder builder = LayoutUtils.gridBagConstraintsBuilder();
JPanel internalPanel = new JPanel(new GridBagLayout());
internalPanel.add(this.keywordsScrollPane, builder.gridX(0).gridY(0).gridHeight(3).margins(0, 0, 0, 5)
.fill(GridBagConstraints.BOTH).weightX(1D).weightY(1D).build());
internalPanel.add(this.add,
builder.reset().gridX(1).gridY(0).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());
internalPanel.add(this.remove,
builder.reset().gridX(1).gridY(1).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());
internalPanel.add(this.edit,
builder.reset().gridX(1).gridY(2).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());
this.keywords.setBorder(BorderFactory.createTitledBorder("Keywords"));
internalPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
this.setLayout(new BorderLayout());
this.add(internalPanel, BorderLayout.CENTER);
Dimension screen = GuiHelper.getScreenSize(parent);
this.setSize((int) (screen.getWidth() / 4), (int) (screen.getHeight() / 3));
this.setLocationRelativeTo(parent);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
// ...
}
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the How to Use GridBagLayout section.
The easiest way to create this GUI is to treat the JTextArea separately from the JButton area.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ExampleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ExampleGUI());
}
#Override
public void run() {
JFrame frame = new JFrame("Example GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTextArea(), BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JScrollPane createTextArea() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JTextArea textArea = new JTextArea(10, 30);
textArea.setText("keyword");
panel.add(textArea, BorderLayout.CENTER);
return new JScrollPane(panel);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 5, 5, 5);
gbc.gridy = 0;
JButton button = new JButton("Add");
panel.add(button, gbc);
gbc.gridy++;
button = new JButton("Remove");
panel.add(button, gbc);
gbc.gridy++;
button = new JButton("Edit");
panel.add(button, gbc);
return panel;
}
}
I would make the GUI simpler. Put the three buttons into a JPanel that uses a GridLayout, one declared to use 1 column and variable number of rows, one with a desired spacing between buttons, here, 5 pixels: JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 5, 5)); and then put that JPanel into the center of a another JPanel, and GridBagLayout without constraints works well for this:
JPanel sidePanel = new JPanel(new GridBagLayout());
sidePanel.add(buttonPanel);
and put that JPanel into the right side of a border layout using JPanel. For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooSwing01 extends JPanel {
public FooSwing01() {
JTextArea textArea = new JTextArea(20, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 5, 5));
int maxButtons = 3;
for (int i = 0; i < maxButtons; i++) {
buttonPanel.add(new JButton("Button " + (i + 1)));
}
JPanel sidePanel = new JPanel(new GridBagLayout());
sidePanel.add(buttonPanel);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
add(scrollPane);
add(sidePanel, BorderLayout.LINE_END);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.add(new FooSwing01());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
I am having one main JPanel in which I had used several other panels. I want to add a scroll pane to my panel so that when child panel go out of frame they should be scrollable, but I am unable to achieve this.
How to achieve correct scrolling functionality for panels within a panel?
Code inside my child panel:
public class Page13111SubPanel extends JPanel {
/**
* Create the panel.
*/
public Page13111SubPanel() {
// setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
setSize(1000,130);
setLayout(new GridLayout(3, 3, 40, 35));
JLabel label= new JLabel();
label.setText("Vehicle Companies:asdddddddddddddddd1");
label.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label);
JLabel label1= new JLabel();
label1.setText("Vehicle Companies:asdddddddddddddddd2");
label1.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label1);
JLabel label2= new JLabel();
label2.setText("Vehicle Companies:asdddddddddddddddd3");
label2.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label2);
JLabel label3= new JLabel();
label3.setText("Vehicle Companies:asdddddddddddddddd4");
label3.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label3);
// JLabel label3= new JLabel();
// label3.setText("Vehicle Companies:asdddddddddddddddd4");
// label3.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
// add(label3);
JLabel label4= new JLabel();
label4.setText("Vehicle Companies:asdddddddddddddddd5");
label4.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label4);
JLabel label5= new JLabel();
label5.setText("Vehicle Companies:asdddddddddddddddd6");
label5.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label5);
JLabel label6= new JLabel();
label6.setText("Vehicle Companies:asdddddddddddddddd7");
label6.setFont(new Font("Monotype Corsiva", Font.ITALIC, 20));
add(label6);
}
}
Code inside my main panel:
public class Page1311Test extends JPanel {
// private JTable table;
public JScrollPane pane=null;
public JPanel panel=null;
public JButton back=null;
/**
* Create the panel.
*/
public Page1311Test() {
JPanel panel=new JPanel();
panel.setLayout(new GridLayout(7,1,1,40));
Page13111SubPanel[] panel1=new Page13111SubPanel[7];
panel1[0]=new Page13111SubPanel();
panel.add(panel1[0]);
panel1[1]=new Page13111SubPanel();
panel.add(panel1[1]);
panel1[2]=new Page13111SubPanel();
panel.add(panel1[2]);
panel1[3]=new Page13111SubPanel();
panel.add(panel1[3]);
panel1[4]=new Page13111SubPanel();
panel.add(panel1[4]);
panel1[5]=new Page13111SubPanel();
panel.add(panel1[5]);
panel1[6]=new Page13111SubPanel();
panel.add(panel1[6]);
pane=new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(pane);
}
public static void main(String[] args) {
JFrame frame=new JFrame();
frame.setExtendedState(frame.MAXIMIZED_BOTH);
frame.setLocation(0, 0);
frame.add(new Page1311Test());
frame.setVisible(true);
}
}
Changing the main panel from FlowLayout (the default) to a layout that uses the child components of the panel to fill the available space (used GridLayout here) solves the problem. E.G.
import java.awt.*;
import javax.swing.*;
public class Page1311Test extends JPanel {
public JScrollPane pane = null;
public JPanel panel = null;
/**
* Create the panel.
*/
public Page1311Test() {
setLayout(new GridLayout());
//JPanel panel = new JPanel(); //shadowed class attribute
panel = new JPanel(new GridLayout(0, 1, 1, 40));
for (int ii = 0; ii < 17; ii++) {
panel.add(new Page13111SubPanel(ii));
}
pane = new JScrollPane(panel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(pane);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setExtendedState(frame.MAXIMIZED_BOTH);
frame.setLocation(0, 0);
frame.add(new Page1311Test());
frame.pack();
frame.setVisible(true);
}
}
class Page13111SubPanel extends JPanel {
/**
* Create the panel.
*/
public Page13111SubPanel(int num) {
//setSize(1000, 130); // Don't set sizes using 'magic numbers'
setLayout(new GridLayout(3, 3, 40, 35));
add(new JLabel(num + " Vehicle Companies:asdddddddddddddddd1"));
add(new JLabel("Vehicle Make:"));
add(new JLabel("Vehicle Model"));
add(new JLabel("Vehicle Number"));
add(new JLabel("Vehicle Driver:"));
add(new JLabel("Vehicle Wheels"));
add(new JLabel("Vehicle Air Con"));
}
}
I am guessing the problem lies in your GridLayout and setSize calls. When you call, essentially your layout manager is going to overwrite you setSize call.
In the following example, I set the preferred and minimum sizes and the scroll pane works fine.
JFrame frame = new JFrame("Grids of Grids");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 3));
for(int i = 0; i<9; i++){
JPanel localGrid = new JPanel();
localGrid.setMinimumSize(new Dimension(250, 250));
localGrid.setPreferredSize(new Dimension(250, 250));
localGrid.setLayout(new GridLayout(5, 5));
for(int j = 0; j<25; j++){
localGrid.add(new JLabel("" + i + ":: " + j));
}
panel.add(localGrid);
}
JScrollPane scroll = new JScrollPane(panel);
frame.add(scroll);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Otherwise, your scrollable area will actuall be pretty small because the layouts will try to fit it into the available space.
I think your problem is that the main Panel is not scrollable, therefore you cannot scroll at all.
Try using a JScrollPane there and take a look at this tutorial to get more information about JScrollPanes. There are also lots of information about other GUI-Objects like Frames and Panels, so I think you can find a solution for your problem!
As the title said, I'm trying to put 4 different JLabels at each of the corners of a JFrame. I want them to stay there forever even if I try to resize the JFrame
I've tried using a layout manager but I just can't get it right.
ImageIcon icon;
JLabel labelNW = new JLabel();
JLabel labelNE = new JLabel();
JLabel labelSW = new JLabel();
JLabel labelSE = new JLabel();
URL buttonURL = InputOutputTest.class.getResource("images/square_dot.gif");
if(buttonURL != null){
icon = new ImageIcon(buttonURL);
labelNW.setIcon(icon);
labelNE.setIcon(icon);
labelSW.setIcon(icon);
labelSE.setIcon(icon);
}
window.add(labelNW, BorderLayout.NORTH);
//window.add(labelNE, BorderLayout.EAST);
//window.add(labelSW, BorderLayout.WEST);
window.add(labelSE, BorderLayout.SOUTH);
This code takes care of the north and south of the left side. I'm probably approaching this wrong though.
I also tried GridLayout (2,2) but they weren't at the corners and there's a huge gap on the right side.
You will want to nest JPanels each using its own layout. In fact you could do this by nesting JPanels that all use BorderLayout.
Going to check if GridBagLayout can do it in one shot.... hang on...
Yep GridBagLayout does it too:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class GridBagExample {
public static void main(String[] args) {
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(
0, 0, 0, 0), 0, 0);
mainPanel.add(new JLabel("Left Upper"), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHEAST;
mainPanel.add(new JLabel("Right Upper"), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.SOUTHWEST;
mainPanel.add(new JLabel("Left Lower"), gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.SOUTHEAST;
mainPanel.add(new JLabel("Right Lower"), gbc);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
Edit
Now for the BorderLayout example:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class BorderLayoutExample {
public static void main(String[] args) {
JPanel northPanel = new JPanel(new BorderLayout());
northPanel.add(new JLabel("North East"), BorderLayout.EAST);
northPanel.add(new JLabel("North West"), BorderLayout.WEST);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(new JLabel("South East"), BorderLayout.EAST);
southPanel.add(new JLabel("South West"), BorderLayout.WEST);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(northPanel, BorderLayout.NORTH);
mainPanel.add(southPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("BorderLayout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
I find that only GroupLayout gives me the control I need for precisely laid out components. This should do the trick. You need to make sure the gap in between has a very large Maximum value (i.e. Short.MAX_VALUE), but you can set the minimum and preferred sizes to whatever you want.
public class LabelFrame extends JFrame {
public LabelFrame() {
JPanel contentPane = new JPanel();
JLabel labelNW = new JLabel();
JLabel labelNE = new JLabel();
JLabel labelSW = new JLabel();
JLabel labelSE = new JLabel();
URL buttonURL = InputOutputTest.class.getResource("images/square_dot.gif");
if(buttonURL != null){
icon = new ImageIcon(buttonURL);
labelNW.setIcon(icon);
labelNE.setIcon(icon);
labelSW.setIcon(icon);
labelSE.setIcon(icon);
}
GroupLayout layout = new GroupLayout(contentPane);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(labelNW)
.addComponent(labelSW))
.addGap(20,50,Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(Alignment.TRAILING)
.addComponent(labelNE)
.addComponent(labelSE))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(labelNW)
.addComponent(labelNE))
.addGap(20,50,Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(Alignment.TRAILING)
.addComponent(labelSW)
.addComponent(labelSE))
);
contentPane.setLayout(layout);
setContentPane(contentPane);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
LabelFrame frame = new LabelFrame();
frame.setVisible(true);
}
});
}
}
I've tried using a layout manager..
Layout managers are wonderful at what they do, but are perhaps the wrong tool for this job. Consider using a custom border instead. Here is an example.
Consider the following figure:
I need to develop a swing GUI the looks like this. I simply named them jLabel's but there a few images and jLabels in it. The default awt background visible is a JPanel and each red background visible is a serperate JPanel. Now I need them to get stacked as shown above. I tried a number of LayoutManagers and still it doesn't work.
The important point here is that the number of red colored divs are not constant. If there is only one red colored div then it must be displayed at the top, not at the center. As far as i know GridBagLayout should work, but it centers the single red colored jpanel available. All the layout managers are centering them but not stacking them from top to bottom.
Even with anchor set to NORTH then the panels will still be centered. You could work around it by adding a dummy panel to fill the remaining space. Personally I'd stay well away from GridBagLayout though.
JFrame frame = new JFrame();
JPanel content = new JPanel();
content.setBorder(BorderFactory.createLineBorder(Color.red));
frame.setContentPane(content);
frame.getContentPane().setLayout(new GridBagLayout());
frame.setSize(400, 300);
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
GridBagConstraints con = new GridBagConstraints();
con.gridy = i;
con.gridx = 0;
con.anchor = GridBagConstraints.NORTHWEST;
con.ipady = 10;
frame.getContentPane().add(panel, con);
}
// dummy panel to use up the space (force others to top)
frame.getContentPane().add(
new JPanel(),
new GridBagConstraints(0, 3, 1, 1, 1, 1,
GridBagConstraints.NORTHWEST,
GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0,
0));
frame.setVisible(true);
GroupLayout example (my favourite layout manager).
JFrame frame = new JFrame();
JPanel content = new JPanel();
frame.setContentPane(content);
frame.getContentPane().setLayout(
new BoxLayout(content, BoxLayout.Y_AXIS));
frame.setSize(400, 300);
GroupLayout gLayout = new GroupLayout(content);
content.setLayout(gLayout);
ParallelGroup hGroup = gLayout.createParallelGroup();
gLayout.setHorizontalGroup(hGroup);
SequentialGroup vGroup = gLayout.createSequentialGroup();
gLayout.setVerticalGroup(vGroup);
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
hGroup.addComponent(panel);
vGroup.addComponent(panel, GroupLayout.PREFERRED_SIZE,
GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
vGroup.addGap(10);
}
frame.setVisible(true);
you can use Vertical BoxLayout, for example:
http://www.java-tips.org/java-se-tips/javax.swing/how-to-use-swing-boxlayout.html
nobody tell us that all JComponents must be visible, for example
from code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel(new GridLayout(0, 1));
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel b = new JPanel(new GridLayout(0, 4));
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
//b.setPreferredSize(new Dimension(600, 20));
for (int i = 0; i < 4; i++) {
JLabel l = new JLabel("label" + i + 1);
b.add(l);
if (i == 2) {
l.setVisible(false);
}
}
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
checkPack.setSelected(true);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
You should try the MigLayout it is simple yet powerful. Below I tell miglayout to grow elements, and fill all possible space, then after each element I tell it to go to a new line (wrap). You can find examples and tutorial on MigLayout page http://www.miglayout.com/:
import net.miginfocom.swing.MigLayout;
public class PanelLearning extends JPanel {
public PanelLearning() {
setLayout(new MigLayout("", "[grow, fill]", ""));
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
add(panel, "span, wrap");
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Login");
frame.setVisible(true);
frame.setContentPane(new PanelLearning());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}
}
Make sure GridBagConstraints.anchor = GridBagConstraints.NORTH when you add components to the panel.