JFrame GridBagLayout component positioning - java

So, I was using null layout but was told it was a terrible idea and so decided to use GridBagLayout, as it's supposedly the easiest to customise. I'm having trouble with positioning my components, I am really confused as to how I can get a label to the top middle of the screen, my table in the middle, and my login button to the bottom right. Does anyone know how to do this?
Here's my code:
import javafx.geometry.HorizontalDirection;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
public class Main
{
JFrame window = new JFrame("PE Fixture"); //JFrame variables
JPanel container = new JPanel();
JPanel guestFixturesPanel = new JPanel();
JPanel loginPanel = new JPanel();
JPanel adminFixturesPanel = new JPanel();
JPanel createPanel = new JPanel();
String[] columns = {"Sport", "Location", "Date", "Result"};
String[][] data = {{"Football", "AQA Highschool", "12.11.13", "5 - 0"},
{"Tennis", "Wembley", "26.11.14.", "TBC"}};
CardLayout cardLayout = new CardLayout();
GridBagConstraints c = new GridBagConstraints();
public Main()
{
container.setLayout(cardLayout);
guestFixturesPanel.setLayout(new GridBagLayout()); //GUEST FIXTURES PANEL COMPONENTS
JButton loginButton = new JButton("Login");
c.gridx = 0;
c.gridy = 2;
c.insets = new Insets(0, 0, 10, 0);
guestFixturesPanel.add(loginButton, c);
JTable fixturesTable = new JTable(data, columns)
{
public boolean isCellEditable(int data, int columns)
{
return false;
}
};
fixturesTable.setPreferredScrollableViewportSize(new Dimension(500, 300));
fixturesTable.setFillsViewportHeight(true);
JScrollPane scrollTable = new JScrollPane(fixturesTable);
c.gridx = 0;
c.gridy = 0;
c.ipady = 700;
c.ipadx = 400;
guestFixturesPanel.add(scrollTable, c);
JLabel fixturesLabel = new JLabel("FIXTURES");
fixturesLabel.setFont(new Font("TimesRoman", Font.PLAIN, 50));
fixturesLabel.setForeground(Color.WHITE);
c.gridx = 0;
c.gridy = 0;
guestFixturesPanel.add(fixturesLabel, c);
container.add(guestFixturesPanel, "2"); //LABELS EACH COMPONENT WITH A NUMBER
container.add(loginPanel, "3");
container.add(adminFixturesPanel, "4");
container.add(createPanel, "5");
guestFixturesPanel.setBackground(Color.DARK_GRAY); //Colours each panel
loginPanel.setBackground(Color.DARK_GRAY);
adminFixturesPanel.setBackground(Color.DARK_GRAY);
createPanel.setBackground(Color.DARK_GRAY);
cardLayout.show(container, "1");
window.add(container); //Creates the frame of the program.
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(500, 860);
window.setResizable(false);
window.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main();
}
});
}
}
EDIT:
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
public class Main
{
String[] columns = {"Sport", "Location", "Date", "Result"};
String[][] data = {{"Football", "AQA Highschool", "12.11.13", "5 - 0"},
{"Tennis", "Wembley", "26.11.14.", "TBC"}};
private void createAndShowGUI()
{
CardLayout layout = new CardLayout();
JPanel guestCard = new JPanel(layout);
JPanel guestTitle = new JPanel(new FlowLayout(FlowLayout.CENTER)); //GUEST TOP PANEL
JLabel fixturesLabel = new JLabel("FIXTURES");
fixturesLabel.setFont(new Font("TimesRoman", Font.PLAIN, 50));
fixturesLabel.setForeground(Color.WHITE);
guestTitle.add(fixturesLabel);
JTable fixturesTable = new JTable(data, columns) //GUEST MID PANEL
{
public boolean isCellEditable(int data, int columns)
{
return false;
}
};
fixturesTable.setPreferredScrollableViewportSize(new Dimension(350, 450));
fixturesTable.setFillsViewportHeight(true);
JScrollPane scrollTable = new JScrollPane(fixturesTable);
JPanel guestBot = new JPanel(new FlowLayout(FlowLayout.RIGHT)); //GUEST BOT PANEL
JButton loginButtonGuest = new JButton("Login");
guestBot.add(loginButtonGuest);
JPanel loginCard = new JPanel(layout); //LOGIN TOP PANEL
JPanel loginTitle = new JPanel(new FlowLayout(FlowLayout.CENTER));
JLabel loginLabel = new JLabel("LOGIN");
loginLabel.setFont(new Font("TimesRoman", Font.PLAIN, 50));
loginLabel.setForeground(Color.WHITE);
loginTitle.add(loginLabel);
JPanel container = new JPanel(new BorderLayout(8,8)); //ADDS CARDS TO CONTAINER
container.add(guestCard, "2");
container.add(loginCard, "3");
guestCard.add(guestTitle, BorderLayout.NORTH); //ADDS COMPONENTS TO CARDS
guestCard.add(scrollTable, BorderLayout.CENTER);
guestCard.add(guestBot, BorderLayout.SOUTH);
loginCard.add(loginTitle, BorderLayout.NORTH);
container.setBackground(Color.DARK_GRAY); //COLOURS CARDS
guestTitle.setBackground(Color.DARK_GRAY);
scrollTable.setBackground(Color.DARK_GRAY);
guestBot.setBackground(Color.DARK_GRAY);
layout.show(container, "1");
JFrame window = new JFrame("PE Fixtures"); //CREATES WINDOW
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
window.setSize(400, 700);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main().createAndShowGUI();
}
});
}
}
ERROR:
"C:\Program Files\Java\jdk1.7.0_51\bin\java" -Didea.launcher.port=7533 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 13.0.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_51\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext\zipfs.jar;C:\Users\Harry\Desktop\Computer Science Projects\PE Fixtures v2.0\out\production\PE Fixtures v2.0;C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 13.0.2\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain Main
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: cannot add to layout: unknown constraint: 2
at java.awt.BorderLayout.addLayoutComponent(BorderLayout.java:463)
at java.awt.BorderLayout.addLayoutComponent(BorderLayout.java:424)
at java.awt.Container.addImpl(Container.java:1120)
at java.awt.Container.add(Container.java:966)
at Main.createAndShowGUI(Main.java:48)
at Main.access$000(Main.java:8)
at Main$2.run(Main.java:77)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

I am really confused as to how I can get a label to the top middle of
the screen, my table in the middle, and my login button to the bottom
right.
As you can see GridBagLayout is not the simplest layout manager (too much troubles and not really too much power). To lay out this little amount of components I'd suggest you use a Nested Layout approach:
Use BorderLayout to lay out the "main" panel components (label, table and button).
Use FlowLayout to center the label inside a top panel and place the button at the right in a bottom panel.
Example
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Demo {
private void createAndShowGUI() {
JLabel label = new JLabel("Title");
label.setFont(label.getFont().deriveFont(Font.BOLD | Font.ITALIC, 18));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
topPanel.add(label);
DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0);
model.addRow(new Object[]{"Property # 1", "Value # 1"});
model.addRow(new Object[]{"Property # 2", "Value # 2"});
model.addRow(new Object[]{"Property # 3", "Value # 3"});
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
JButton button = new JButton("Log In");
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.add(button);
JPanel content = new JPanel(new BorderLayout(8, 8));
content.add(topPanel, BorderLayout.NORTH);
content.add(scrollPane, BorderLayout.CENTER);
content.add(bottomPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
Screenshot
In addition
For more complex GUI designs you may want to try one of these third-party layout managers suggested in this answer:
MigLayout
DesignGridLayout
FormLayout

Related

JButton size and JScrollPane not working well together

I am thoroughly confused. I have a pretty decent understanding of how each layout manger works and what each one is used for, but I'm not understanding what combination of layout managers and JPanels are necessary to make what I need work.
What I am trying to accomplish
I have a top bar, and a bottom bar of a container panel NORTH and SOUTH of a BorderLayout.
Within the Center panel, I want an unknown number of buttons 1 or more. Regardless of how many buttons there are they all need to be the same size, if there are dozens then scrolling should start happening once the buttons pass the window size limit.
What I am getting
Depending on the combination of layout mangers and how many nested JPanels I use and all sorts of trouble shooting, I get one massive button filling the entire CENTER element. I get 2 buttons that are the right size, but spread way apart (gap filling the CENTER space), or I get a dozen buttons that are the right size with no scroll.
I can solve any one of these, but then the other breaks. IE if I get a bunch of correctly sized buttons that properly scroll, then when I replace them with a single button its one massive button. Or if I get a single properly sized button then the larger quantity won't scroll etc.
My Code
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.io.*;
public class TestCode extends JFrame {
private final JFrame frame;
public TestCode(){
frame = new JFrame();
JLabel title = new JLabel("Test Title");
JPanel windowContainer = new JPanel();
JPanel topPanel = new JPanel();
final JPanel middlePanel = new JPanel();
JPanel bottomPanel = new JPanel();
JButton searchButton = new JButton("Search");
JButton browseButton = new JButton("Browse...");
JButton testButton = new JButton("Button 1");
JButton exitButton = new JButton("Exit");
final JTextField searchBar = new JTextField("Search database...");
topPanel.setLayout(new GridLayout(2,0));
topPanel.add(title);
title.setHorizontalAlignment(JLabel.CENTER);
topPanel.setPreferredSize(new Dimension(getWidth(), 100));
// This is a subset of the top section. Top part is two panels, bottom panel is two cells (grid)
JPanel topPanelSearch = new JPanel();
topPanelSearch.setLayout(new GridLayout(0,2));
topPanelSearch.add(searchBar);
topPanelSearch.add(searchButton);
topPanel.add(topPanelSearch);
// PROBLEM AREA STARTS
// middlePanel.setLayout(new FlowLayout());
middlePanel.setLayout(new GridLayout(0, 1, 10, 10));
// middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.PAGE_AXIS));
JPanel innerContainer = new JPanel();
innerContainer.setLayout(new BoxLayout(innerContainer, BoxLayout.PAGE_AXIS));
// innerContainer.setLayout(new FlowLayout());
// innerContainer.setLayout(new GridLayout(0, 1, 10, 10));
for(int i = 0; i < 2; i++){
JButton button = new JButton("Button ");
button.setPreferredSize(new Dimension(400, 100));
JPanel test = new JPanel();
test.add(button);
innerContainer.add(test);
}
JScrollPane midScroll = new JScrollPane(innerContainer);
middlePanel.add(midScroll);
// PROBLEM AREA ENDS
bottomPanel.setLayout(new GridLayout(0, 3));
bottomPanel.setPreferredSize(new Dimension(getWidth(), 100));
bottomPanel.add(testButton);
bottomPanel.add(browseButton);
bottomPanel.add(exitButton);
windowContainer.setLayout(new BorderLayout());
windowContainer.add(topPanel, BorderLayout.NORTH);
windowContainer.add(middlePanel, BorderLayout.CENTER);
windowContainer.add(bottomPanel, BorderLayout.SOUTH);
frame.add(windowContainer);
frame.setTitle("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(480, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args){
TestCode test = new TestCode();
}
}
Visual of some of the fail results
I want the leftmost picture, but buttons should be stacked neatly (like the middle picture) when there are only a few results, and scrollable when there are lots.
What am I doing wrong?
Try with GridBagLayout and a filler component that takes the remaining vertical space and therefore forces the buttons upwards.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class GridbagButtons extends JFrame {
private final JScrollPane jscrpButtons;
private final JPanel jpButtons;
public GridbagButtons() {
setLayout(new BorderLayout());
jpButtons = new JPanel(new GridBagLayout());
jscrpButtons = new JScrollPane(jpButtons);
add(jscrpButtons, BorderLayout.CENTER);
// add a custom number of buttons
int numButtons = 10;
for (int i = 0; i < numButtons; i++) {
JButton jbButton = new JButton("Button");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = i;
jpButtons.add(jbButton, gbc);
}
// add a vertical filler as last component to "push" the buttons up
GridBagConstraints gbc = new GridBagConstraints();
Filler verticalFiller = new Filler(
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, Integer.MAX_VALUE));
gbc.gridx = 0;
gbc.gridy = numButtons;
gbc.fill = java.awt.GridBagConstraints.VERTICAL;
gbc.weighty = 1.0;
jpButtons.add(verticalFiller, gbc);
setSize(300, 200);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridbagButtons().setVisible(true);
}
});
}
}

How to give a preffered size to the JButton?

import javax.swing.*;
import java.awt.*;
class MainGui{
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut = new JButton("New Game");
JButton continueBut = new JButton("Continue");
JButton exitBut = new JButton("Exit");
JLabel backImage = new JLabel(new ImageIcon("C:\\Users\\BSK\\Desktop\\game5.jpg"));
public MainGui(){
frame.setSize(600,800);
frame.setVisible(true);
frame.setResizable(false);
setButtonSize();
frame.setLayout(new BorderLayout());
frame.setContentPane(backImage);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.Y_AXIS));
insertBlankArea(frame);
frame.getContentPane().add(newBut);
insertBlankArea(frame);
frame.getContentPane().add(continueBut);
insertBlankArea(frame);
frame.getContentPane().add(exitBut);
frame.setSize(799,800);
}
public void insertBlankArea(JFrame frame){
frame.getContentPane().add(Box.createRigidArea(new Dimension(280,155)));
}
public void setButtonSize(){
Dimension dim = new Dimension(100,100);//here is the problem,i am not getting the desired dimension and the size of buttons remains the default.
newBut.setPreferredSize(dim);
continueBut.setPreferredSize(dim);
exitBut.setPreferredSize(dim);
}
public static void main(String[] args) {
MainGui mainGui = new MainGui();
}
}
So iam not getting the defined size for the buttons but when i set frame.setResizable(false); then when i stretch the screen the button's height increases but its width still remains the same.
So please tell me what is going wrong?
You should take a look at A Visual Guide to Layout Managers and choose the most appropriate one for your situation. You should also avoid explicitly setting sizes (ie: setSize, setMinimumSize, setMaximumSize, and setPreferredSize) because those methods are the responsibility of the layout manager. You may also be interested in reading this question on whether or not the use of the different set size methods should be avoided or not.
Finally, you should not be calling your MainGUI class outside of the Event Dispatch Thread (EDT). Most Swing GUI-related methods are not thread safe and therefore require being executed in the EDT. Below is a corrected version of your main method:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainGui mainGui = new MainGui();
}
});
}
Just reading your short descrption, I have no idea what your problem is. But based solely on the question title
"How to give a preffered size to the JButton?"
Don't. Let the the layout manager handle this for you. If you want a bigger button, you can use JButton.setMargins(Insets) and/or JButton.setFont(Font) where you specify a bigger font.
If you want you button stretched or not to stretch, You need to select an appropriate layout manager, that will or won't respect the buttons preferred size. For instance, BorderLayout and GridLayout won't respect preferred sizes and will stretch the button the fit, and FlowLayout, BoxLayout, and GridBagLayout will respect the preferred size. As you can see here
See example with GridBagLayout
import javax.swing.*;
import java.awt.*;
class MainGui {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut = new JButton("New Game");
JButton continueBut = new JButton("Continue");
JButton exitBut = new JButton("Exit");
JLabel backImage = new JLabel(new ImageIcon(
getClass().getResource("images.jpg")));
public MainGui() {
backImage.setLayout(new BorderLayout());
frame.setContentPane(backImage);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.setOpaque(false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
mainPanel.add(newBut, gbc);
gbc.gridy = 1;
mainPanel.add(continueBut, gbc);
gbc.gridy = 2;
mainPanel.add(exitBut, gbc);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.setSize(250, 275);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
MainGui mainGui = new MainGui();
}
});
}
}
And here's with nesting panels which will give the same result
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class MainGui {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut = new JButton("New Game");
JButton continueBut = new JButton("Continue");
JButton exitBut = new JButton("Exit");
JLabel backImage = new JLabel(new ImageIcon(
getClass().getResource("images.jpg")));
public MainGui() {
backImage.setLayout(new GridLayout(3,1));
frame.setContentPane(backImage);
JPanel p1= new JPanel(new GridBagLayout());
p1.setOpaque(false);
p1.add(newBut);
JPanel p2 = new JPanel(new GridBagLayout());
p2.setOpaque(false);
p2.add(continueBut);
JPanel p3 = new JPanel(new GridBagLayout());
p3.setOpaque(false);
p3.add(exitBut);
frame.add(p1);
frame.add(p2);
frame.add(p3);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 275);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
MainGui mainGui = new MainGui();
}
});
}
}

JScrollPane in Jlist

hello goodevening to all i have a problem on my program with the ScrollPane in my JList i cant put an JScrollPane in my list because i am using a panel instead of Container this is my code so far its all runnable the problem is if you enter a high number in the number of times the some output will not be able to see because of the size of my list . so this is the code
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MultCen extends JFrame implements ActionListener
{
public static void main(String args [])
{
MultCen e = new MultCen();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.setVisible(true);
e.setSize(300,450);
}
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
JButton b = new JButton("Okay");
JButton c = new JButton("Clear");
JList list = new JList();
JLabel lab = new JLabel();
DefaultListModel m = new DefaultListModel();
public MultCen()
{
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel l = new JLabel("Enter a number :");
JLabel l1 = new JLabel("How many times :");
l.setBounds(10,10,130,30);
l1.setBounds(10,40,130,30);
t1.setBounds(140,10,130,25);
t2.setBounds(140,40,130,25);
b.setBounds(60,90,75,30);
c.setBounds(150,90,75,30);
list.setBounds(30,140,220,220);
panel.add(t1);
panel.add(t2);
panel.add(l);
panel.add(l1);
panel.add(list);
panel.add(b);
panel.add(c);
getContentPane().add(panel);
b.addActionListener(this);
c.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == b)
{
int t3 = Integer.parseInt(t1.getText());
int t4 = Integer.parseInt(t2.getText());
m.addElement("The multiplication Table of "+t3);
for (int cc =1 ; cc <=t4; cc++ )
{
lab.setText(t3+"*"+cc+" = "+(t3*cc));
m.addElement(lab.getText());
list.setModel(m);
}
}
if(e.getSource() == c)
{
t1.setText("");
t2.setText("");
m.removeAllElements();
}
}
}
JScrollPane does not work with null Layout. Use BoxLayout or any other resizeable layout instead. This is the limitation of setLayout(null).
Use Layout managers. You've asked a lot of questions here and I'm sure a few you have been advised not to use null layout. Again here is the tutorial Laying out components Within a container. Learn to use them so you don't run into the million possible problems on the road ahead. This kind of problem being one of them.
here's an example of how you could achieve the same thing with layout managers, and some empty borders for white space.
With Layout Manager
Without Layout Manger
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class MultCen extends JFrame {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MultCen e = new MultCen();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.setVisible(true);
e.pack();
}
});
}
JTextField t1 = new JTextField(10);
JTextField t2 = new JTextField(10);
JButton b = new JButton("Okay");
JButton c = new JButton("Clear");
JLabel lab = new JLabel();
DefaultListModel m = new DefaultListModel();
public MultCen() {
JPanel topPanel = new JPanel(new GridLayout(2, 2, 0, 5));
JLabel l = new JLabel("Enter a number :");
JLabel l1 = new JLabel("How many times :");
topPanel.add(l);
topPanel.add(t1);
topPanel.add(l1);
topPanel.add(t2);
JPanel buttonPanel = new JPanel();
buttonPanel.add(b);
buttonPanel.add(c);
buttonPanel.setBorder(new EmptyBorder(10, 0, 10, 0));
JList list = new JList();
JScrollPane scroll = new JScrollPane(list);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setPreferredSize(new Dimension(300, 300));
JPanel panel = new JPanel(new BorderLayout());
panel.add(topPanel, BorderLayout.NORTH);
panel.add(buttonPanel, BorderLayout.CENTER);
panel.add(scroll, BorderLayout.SOUTH);
panel.setBorder(new EmptyBorder(10, 15, 10, 15));
getContentPane().add(panel);
}
}
Side Notes
Run Swing apps from the Event Dispatch Thread. See Initial Threads
When you do decide to use layout managers, just pack() your frame instead of setSize()
Use better variable names.
See Extends JFrame vs. creating it inside the the program

Why aren't the Jpanels working?

I am trying to write a program with JPanels and for the life of me, I can't seem to get the JPanels to go into the proper positions. I don't have a clue what I am doing wrong.
Here is some of the code I have so far:
package mainGUIWindowFrames;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class CustomerWindow extends JFrame
{
//Attribute
private JTextField textTF;
private JButton copyButton;
private JLabel copyLabel;
private Border panelEdge;
//Constructor
public CustomerWindow()
{
this.setBounds(100,100,800,600);
panelEdge = BorderFactory.createEtchedBorder();
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
mainPanel.add(createCustomerPanel(), BorderLayout.NORTH);
mainPanel.add(createCustomerInfoPanel(), BorderLayout.EAST);
mainPanel.add(createSearchPanel(), BorderLayout.WEST);
}
//Operational Methods
public JPanel createCustomerPanel()
{
JPanel customerPanel = new JPanel();
JLabel customerL = new JLabel("Clients",SwingConstants.CENTER);
customerL.setForeground(Color.blue);
customerL.setFont(new Font("Copperplate Gothic Bold",Font.BOLD,48));
customerPanel.add(customerL);
customerPanel.setBorder(panelEdge);
return customerPanel;
}
public JPanel createCustomerInfoPanel()
{
JPanel infoPanel = new JPanel();
infoPanel.setBorder(panelEdge);
JLabel infoL = new JLabel("Clients",SwingConstants.CENTER);
infoL.setForeground(Color.blue);
infoL.setFont(new Font("Copperplate Gothic Bold",Font.BOLD,48));
infoPanel.add(infoL);
//add a text field
textTF = new JTextField(50);
infoPanel.add(textTF);
//add a button
copyButton = new JButton("Copy Text");
copyButton.addActionListener(new ButtonListener());
infoPanel.add(copyButton);
copyLabel = new JLabel("-----------------");
infoPanel.add(copyLabel);
return infoPanel;
}
public JPanel createSearchPanel()
{
JPanel lowerPanel = new JPanel();
JLabel label = new JLabel("Text Transferred from JList:");
//the spot where the data shows up
lowerPanel.add(label);
return lowerPanel;
}
The only Panel that shows up is the CreateCustomerPanel(). I have no idea what I need to do to get the other two panels to work.
If you could help me out that would be great!!
well I eventually wound up solving it by creating another panel and moving the panels I had out of the main constructor.
public CustomerWindow() {
panelEdge = BorderFactory.createEtchedBorder();
}
public JPanel createNorthPanel()
{
JPanel customerPanel = new JPanel();
JLabel customerL = new JLabel("Clients",SwingConstants.CENTER);
customerL.setForeground(Color.blue);
customerL.setFont(new Font("Copperplate Gothic Bold",Font.BOLD,48));
customerPanel.add(customerL);
customerPanel.setBorder(panelEdge);
return customerPanel;
}
//Operational Methods
public JPanel createCustomerPanel()
{
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
mainPanel.add(createNorthPanel(), BorderLayout.NORTH);
mainPanel.add(createCustomerInfoPanel(), BorderLayout.EAST);
mainPanel.add(createSearchPanel(), BorderLayout.WEST);
return mainPanel;
}
public JPanel createCustomerInfoPanel()
{
JPanel infoPanel = new JPanel();
Box vBox = Box.createVerticalBox();
infoPanel.setBorder(panelEdge);
JLabel infoL = new JLabel("Clients",SwingConstants.CENTER);
infoL.setForeground(Color.blue);
infoL.setFont(new Font("Copperplate Gothic Bold",Font.BOLD,48));
infoPanel.add(infoL);
//add a text field
clientId = new JTextField(10);
vBox.add(clientId);
vBox.add(Box.createVerticalStrut(25));
fName = new JTextField(10);
vBox.add(fName);
vBox.add(Box.createVerticalStrut(25));
lName = new JTextField(10);
vBox.add(lName);
vBox.add(Box.createVerticalStrut(25));
address = new JTextField(10);
vBox.add(address);
vBox.add(Box.createVerticalStrut(25));
postalCode = new JTextField(10);
vBox.add(postalCode);
vBox.add(Box.createVerticalStrut(25));
number = new JTextField(10);
vBox.add(number);
vBox.add(Box.createVerticalStrut(25));
type = new JTextField(10);
vBox.add(type);
infoPanel.add(vBox);
return infoPanel;
Ive still got a lot of work to do but thanks to all those who helped me out!!
Based on your example, nothing should show up, as you've not added mainPanel to anything.
Once I did that, I was able to get
to show up...
Modified code example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
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.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
public class CustomerWindow extends JFrame {
//Attribute
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
CustomerWindow frame = new CustomerWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private JTextField textTF;
private JButton copyButton;
private JLabel copyLabel;
private Border panelEdge;
//Constructor
public CustomerWindow() {
this.setBounds(100, 100, 800, 600);
panelEdge = BorderFactory.createEtchedBorder();
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
mainPanel.add(createCustomerPanel(), BorderLayout.NORTH);
mainPanel.add(createCustomerInfoPanel(), BorderLayout.EAST);
mainPanel.add(createSearchPanel(), BorderLayout.WEST);
add(mainPanel);
}
//Operational Methods
public JPanel createCustomerPanel() {
JPanel customerPanel = new JPanel();
JLabel customerL = new JLabel("Clients", SwingConstants.CENTER);
customerL.setForeground(Color.blue);
customerL.setFont(new Font("Copperplate Gothic Bold", Font.BOLD, 48));
customerPanel.add(customerL);
customerPanel.setBorder(panelEdge);
return customerPanel;
}
public JPanel createCustomerInfoPanel() {
JPanel infoPanel = new JPanel();
infoPanel.setBorder(panelEdge);
JLabel infoL = new JLabel("Clients", SwingConstants.CENTER);
infoL.setForeground(Color.blue);
infoL.setFont(new Font("Copperplate Gothic Bold", Font.BOLD, 48));
infoPanel.add(infoL);
//add a text field
textTF = new JTextField(50);
infoPanel.add(textTF);
//add a button
copyButton = new JButton("Copy Text");
// copyButton.addActionListener(new ButtonListener());
infoPanel.add(copyButton);
copyLabel = new JLabel("-----------------");
infoPanel.add(copyLabel);
return infoPanel;
}
public JPanel createSearchPanel() {
JPanel lowerPanel = new JPanel();
JLabel label = new JLabel("Text Transferred from JList:");
//the spot where the data shows up
lowerPanel.add(label);
return lowerPanel;
}
}
You didn't add the mainpanel in the constructor.
add(mainPanel);

How to resize a JPanel to fit a JFrame in "docknorth" with no interference to remaining JPanels

I am doing a little test of a demo Swing GUI. In this demo, the JFrame is composed of 3 "master" JPanels. If you will, the first (jp1) is composed of JLabels, and the other two are composed of several other JPanels. I am using MigLayout.
Here is my sample code:
// All the jPanels
JFrame frame = new JFrame();
frame.setLayout(new MigLayout());
JPanel jp1 = new JPanel();
jp1.setLayout(new MigLayout());
jp1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp2 = new JPanel();
jp2.setLayout(new MigLayout());
jp2.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp3 = new JPanel();
jp3.setLayout(new MigLayout());
jp3.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp4 = new JPanel();
jp4.setLayout(new MigLayout());
jp4.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp5 = new JPanel();
jp5.setLayout(new MigLayout());
jp5.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp6 = new JPanel();
jp6.setLayout(new MigLayout());
jp6.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel jp7 = new JPanel();
jp7.setLayout(new MigLayout());
jp7.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel bigPanel1 = new JPanel();
bigPanel1.setLayout(new MigLayout());
bigPanel1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
JPanel bigPanel2 = new JPanel();
bigPanel2.setLayout(new MigLayout());
bigPanel2.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
//All the labels to be added to JPanel jp1
JLabel label1 = new JLabel();
label1.setText("LABEL1");
JLabel label2 = new JLabel();
label2.setText("LABEL2");
JLabel label3 = new JLabel();
label3.setText("LABEL3");
JLabel label4 = new JLabel();
label4.setText("LABEL4");
jp1.add(label1);
jp1.add(label2);
jp1.add(label3);
jp1.add(label4,"wrap");
bigPanel1.add(jp2);
bigPanel1.add(jp6);
bigPanel1.add(jp3,"grow,wrap");
bigPanel2.add(jp4);
bigPanel2.add(jp7);
bigPanel2.add(jp5,"grow,wrap");
frame.getContentPane().add(jp1,"dock north, wrap");
frame.getContentPane().add(bigPanel1,"span,grow,wrap");
frame.getContentPane().add(bigPanel2,"span,grow,wrap");
frame.pack();
frame.setVisible(true);
Which results in this output:GUI OUTPUT
What I want to achieve is being able to add labels into the 1st JPanel (jp1) without messing with the remainder JPanels width.
Additionally, I want to make the several JPanels inside a bigPanel to occupy its full width, as well as in jp2,jp6 and jp3 to fill bigPanel1.
How should I do this? Thanks in advance.
I have never used MigLayout, and personally dont see the reason if it can be done using default java LayoutManager.
Okay so I used a combination FlowLayout and GridBagLayout to achieve this, along with gc.fill=GridBagConstraints.NONE and gc.anchor=GridBagConstraints.WEST for those panels which we dont want to fill the contentpane width, also updated as per your comment to stop the JPanel/JFrame from growing larger than the given max width when more JLabels are added this was done using a JScrollPane:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class Test {
public Test() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new GridBagLayout());
final JPanel labelPanel = new JPanel();
labelPanel.setBorder(new LineBorder(Color.black));
for (int i = 0; i < 5; i++) {
labelPanel.add(new JLabel("Label" + (i + 1)));
}
final int maxWidth = 200;
final JScrollPane jsp = new JScrollPane(labelPanel) {
#Override
public Dimension getPreferredSize() {
//we set the height by checking if we exceeed the wanted ith thus a scrollbar will appear an we must incoprate that or labels wont be shpwn nicely
return new Dimension(maxWidth, labelPanel.getPreferredSize().width < maxWidth ? (labelPanel.getPreferredSize().height + 5) : ((labelPanel.getPreferredSize().height + getHorizontalScrollBar().getPreferredSize().height) + 5));
}
};
JPanel otherPanel = new JPanel();
otherPanel.add(new JLabel("label"));
otherPanel.setBorder(new LineBorder(Color.black));
JPanel otherPanel2 = new JPanel();
otherPanel2.add(new JLabel("label 1"));
otherPanel2.add(new JLabel("label 2"));
otherPanel2.setBorder(new LineBorder(Color.black));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 1.0;
gc.weighty = 1.0;
gc.gridx = 0;
gc.gridy = 0;
frame.add(jsp, gc);
gc.fill = GridBagConstraints.NONE;
gc.anchor = GridBagConstraints.WEST;
gc.gridy = 1;
frame.add(otherPanel, gc);
gc.anchor = GridBagConstraints.WEST;
gc.gridy = 2;
frame.add(otherPanel2, gc);
frame.pack();
frame.setVisible(true);
frame.revalidate();
frame.repaint();
}
public static void main(String[] args) {
//Create Swing components on EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
I have use BorderLayout and FlowLayout to manage the layouts. The frame has two JPanel's and one JPanel in it has two more JPanel's. All the internal panels use FlowLayout to align the JLabels. To arrange these panels on the JFrame I have used BorderLayout.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class LayoutTest {
public LayoutTest() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new GridBagLayout());
JPanel motherPanel = new JPanel(new BorderLayout());
JPanel topPanel = new JPanel(new BorderLayout());
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
motherPanel.add(topPanel, BorderLayout.NORTH);
motherPanel.add(bottomPanel, BorderLayout.CENTER);
JPanel topUpperPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel topBottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
topUpperPanel.setBorder(new LineBorder(Color.BLACK));
topBottomPanel.setBorder(new LineBorder(Color.BLACK));
bottomPanel.setBorder(new LineBorder(Color.BLACK));
topPanel.add(topUpperPanel, BorderLayout.PAGE_START);
topPanel.add(topBottomPanel, BorderLayout.CENTER);
for(int i = 0; i < 3; i++) {
JLabel label = new JLabel("Label-" + String.valueOf(i));
label.setBorder(new LineBorder(Color.BLACK));
topUpperPanel.add(label);
}
for(int i = 0; i < 2; i++) {
JLabel label = new JLabel("Label-" + String.valueOf(i));
label.setBorder(new LineBorder(Color.BLACK));
topBottomPanel.add(label);
}
for(int i = 0; i < 5; i++) {
JLabel label = new JLabel("Label-" + String.valueOf(i));
label.setBorder(new LineBorder(Color.BLACK));
bottomPanel.add(label);
}
frame.add(motherPanel);
frame.setTitle("Layout Manager");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LayoutTest();
}
});
}
}
P.S: I would suggest you to separate the panels such that there will be "whithout no interference with remaining JPanels."

Categories