Making GridBagLayout more compact - java

I am trying to accomplish the following with GridBagLayout:
The frame will receive a collection of "fields" (JLabel, JTextField pairs), I want to arrange them in a 'Grid-like' fashion where a row will contain 2 such pairs (JLabel1 JField1 JLabel2 JField2). When a row has these four components, the next components are added to another row.
EDIT: I would like the components to start at the top of the panel
My code produces the following layout. I would like the components to be laid out more compactly (especially the vertical distance)
Here is the code:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test extends JFrame{
private JPanel _panel;
public Test() {
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
this.setResizable(true);
this.setVisible(true);
Dimension size = new Dimension(600,600);
this.setMinimumSize(size);
this.setSize(size);
this.setPreferredSize(size);
_panel = new JPanel();
this.add(_panel);
}
public static void main(String[] args) {
Test t = new Test();
String[] labels = {"label1", "label2","label3","label4","label5"};
String[] fieldValues = {"value1","value2","value3","value4","value5"};
t.createFields(labels,fieldValues);
}
private void createFields(String[] labels, String[] fieldValues) {
_panel.setLayout(new GridBagLayout());
int col = 0;
int row = -1;
for(int i=0; i < labels.length;i++) {
JLabel label = new JLabel(labels[i] + ":", JLabel.TRAILING);
JTextField field = new JTextField(fieldValues[i]);
Dimension size = new Dimension(200,30);
field.setPreferredSize(size);
label.setLabelFor(field);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1;
c.weightx = 1;
c.ipadx = 0;
c.ipady = 0;
c.insets = new Insets(0,0,0,0);
c.anchor = GridBagConstraints.LINE_START;
c.gridx = col%4;
if(i%2 == 0) row++;
c.gridy = row;
_panel.add(label,c);
col++;
c.gridx = col%4;
_panel.add(field,c);
col++;
}
this.setVisible(true);
}

If you don't mind your elements being in center of panel (vertically and horizontally), then remove
c.weighty = 1;
c.weightx = 1;
from your code.
If center is wrong place, add
GridBagConstraints c = new GridBagConstraints();
c.gridx=4;
c.gridy=labels.length;
c.weightx=1;
c.weighty=1;
_panel.add(new JLabel(),c);
after your loop

If you want your GUI to be that size, but have the components in a compact size, then place them in their own JPanel, one that uses GridBagLayout, and then add that JPanel to your main GUI JPanel. If you want the components to fill the width, then have the main JPanel use BorderLayout, and add your GBL using JPanel BorderLayout.NORTH or .SOUTH whatever your need is.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class GridBagExample extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
public GridBagExample() {
super(new BorderLayout());
add(new GridBagUsingPanel(), BorderLayout.NORTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("GridBagExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GridBagExample());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class GridBagUsingPanel extends JPanel {
public static final int COLUMNS = 2;
public static final int ROWS = 3;
private static final int TF_COLS = 10;
private static int inset = 5;
private static final Insets INSETS = new Insets(inset, inset, inset, inset);
private static final Insets EXTRA_INSETS = new Insets(inset, inset, inset, 8 * inset);
private static final int EB_GAP = 10;
public GridBagUsingPanel() {
super(new GridBagLayout());
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
for (int r = 0; r < ROWS; r++) {
for (int c = 0; c < COLUMNS; c++) {
addComponent(r, c);
}
}
}
private void addComponent(int r, int c) {
int count = 1 + r * COLUMNS + c;
JLabel label = new JLabel("label " + count);
JTextField textField = new JTextField("value " + count, TF_COLS);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 2 * c;
gbc.gridy = r;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.insets = INSETS;
gbc.weightx = 0.1;
gbc.weighty = 1.0;
add(label, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
if (c != COLUMNS - 1) {
gbc.insets = EXTRA_INSETS;
}
add(textField, gbc);
}
}

Related

Unable to layout properly with GridBagLayout

I am having issues with GridBagLayout & GridBagConstraints in a GUI I am beginning to build. I have to pictures, one of the current state of the GUI, & one of the desired state of the GUI. I have been trying to reach the desired state but have been unable to :(. Here is the code, & I will also attach the 2 pictures I mentioned above. Moreover, there is an issue with the way that I am formatting the first or second checkbox, but I have been unable to figure out what the issue is.
Driver Class:
import javax.swing.SwingUtilities;
public class Driver {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TheFrame();
}
});
}
}
JFrame Class:
import javax.swing.JFrame;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class TheFrame extends JFrame {
//Declarations
private GridBagConstraints gbc;
private String myString;
private JLabel selectionLab;
private JCheckBox defconLevel1;
private JCheckBox defconLevel2;
private JCheckBox defconLevel3;
private JCheckBox defconLevel4;
private JCheckBox defconLevel5;
public TheFrame() {
super("DEFCON DEACTIVATOR");
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new GridBagLayout());
//Initialization
gbc = new GridBagConstraints();
selectionLab = new JLabel("Please Select DECON Level");
defconLevel1 = new JCheckBox("DEFCON 1");
defconLevel2 = new JCheckBox("DEFCON 2");
defconLevel3 = new JCheckBox("DEFCON 3");
defconLevel4 = new JCheckBox("DEFCON 4");
defconLevel5 = new JCheckBox("DEFCON 5");
//Configuration
//Add to contentPane
//ROW 1
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = gbc.NORTH;
gbc.weighty = 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(selectionLab);
//ROW 2
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel1,gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel2,gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel3,gbc);
gbc.gridx = 3;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel4,gbc);
gbc.gridx = 4;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel5,gbc);
}
}
Updated Code:
Driver Class
import javax.swing.SwingUtilities;
public class Driver {
//Declarations
private static SelectionPanel selectionPanel;
private static HeaderPanel headerPanel;
private static TheFrame frame = new TheFrame(selectionPanel,headerPanel);
// public Driver() {
//
// }
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Driver();
}
});
}
}
TheFrame Class
import javax.swing.JFrame;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class TheFrame extends JFrame {
//Declarations
private GridBagConstraints gbc;
private SelectionPanel selectionPanel;
private HeaderPanel headerPanel;
public TheFrame(SelectionPanel selectionPanel, HeaderPanel headerPanel) {
super("DEFCON DEACTIVATOR");
this.selectionPanel = selectionPanel;
this.headerPanel = headerPanel;
//Initialization
gbc = new GridBagConstraints();
selectionPanel = new SelectionPanel();
headerPanel = new HeaderPanel();
this.getContentPane().setLayout(new GridBagLayout());
//Configuration
//Add to contentPane
gbc.anchor = gbc.NORTH; //Content-Pane GLOBAL
gbc.insets = new Insets(0,0,0,0); //Content-Pane GLOBAL
gbc.weightx = 0; //Content-Pane GLOBAL
gbc.weighty = 0.05;
gbc.gridx = 0;
gbc.gridy = 0;
this.getContentPane().add(headerPanel,gbc);
gbc.weighty = 1;
gbc.gridx = 0;
gbc.gridy = 1;
this.getContentPane().add(selectionPanel,gbc);
//Finalize JFrame Last Steps Configurations
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
SelectionPanel Class
import java.awt.Insets;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class SelectionPanel extends JPanel {
//Declarations
private JCheckBox defconLevel1;
private JCheckBox defconLevel2;
private JCheckBox defconLevel3;
private JCheckBox defconLevel4;
private JCheckBox defconLevel5;
private GridBagConstraints gbc;
public SelectionPanel() {
//Initializations
defconLevel1 = new JCheckBox("DEFCON 1");
defconLevel2 = new JCheckBox("DEFCON 2");
defconLevel3 = new JCheckBox("DEFCON 3");
defconLevel4 = new JCheckBox("DEFCON 4");
defconLevel5 = new JCheckBox("DEFCON 5");
gbc = new GridBagConstraints();
//Configuration
this.setLayout(new GridBagLayout());
//Add
//ROW 1
gbc.insets = new Insets(0,0,0,0); //Content-Pane Global
//gbc.anchor = gbc.EAST; //Makes Elements chain-follow each other
gbc.gridy = 0;
gbc.gridx = 0;
this.add(defconLevel1,gbc);
gbc.gridx = 1;
this.add(defconLevel2,gbc);
gbc.gridx = 2;
this.add(defconLevel3,gbc);
gbc.gridx = 3;
this.add(defconLevel4,gbc);
gbc.gridx = 4;
this.add(defconLevel5,gbc);
}
}
HeaderPanel Class
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class HeaderPanel extends JPanel {
private JLabel headerLab;
private GridBagConstraints gbc;
public HeaderPanel() {
//Initialize
headerLab = new JLabel("PLEASE SELECT DEFCON LEVEL");
gbc = new GridBagConstraints();
//Configure
this.setLayout(new GridBagLayout());
//Add
gbc.gridx = 0;
gbc.gridy = 0;
this.add(headerLab,gbc);
}
}
Present Picture:
Wished Design:
Updated Image:
The constraint for the label also needs:
gbc.gridwitdh = 5;
This will allow the label to take up the same horizontal space as the 5 checkboxes, allowing each check box to be displayed in its own column.
You will then need to reset the gridwidth to 1 before adding the other components.
Another option might be to use a Titled Border on your panel. Then you can just use a FlowLayout for adding all the check boxes. This is an easier solution since you don't need to worry about all the GridBagConstraints.
Edit:
Read the section from the Swing tutorial on How to Use GridBagLayout for information about all the constraints.
The first thing you need to do is actually use the constraints for the label otherwise setting the gridwidth won't do anything as the default constrainsts will be used:
//this.getContentPane().add(selectionLab);
add(selectionLab, gbc);
It still won't look correct because you will then need to understand the proper values to be used with the following constraints:
weighty
anchor
weightx
I'll let you play with the constraints one at a time to see what happens as you change the constraint. The tutorial link will help with the different values.

Jpanels with Gridbaglayout inside a JPanel with GridbagLayout problems

I'm trying to get the CardLayout working correctly. - I have the first "card" in my deck", which i've called firstPanel (Gridbaglayout). Inside that panel i want some other panels with the same layout (Gridbaglayout) which ofc has some components.
as example under here - I'm showing one of the JPanels with Gridbaglayout that i want inside my firstPanel (Jpanel) called textFieldForPlayers.
I hope you understand what i mean. if not i'll try to explain it more detailed. :)
public void run() {
deck.setLayout(cl);
c = new GridBagConstraints();
firstPanel.setLayout(new GridBagLayout());
secondPanel.setLayout(new GridBagLayout());
thirdPanel.setLayout(new GridBagLayout());
GamePanel gamePanel = new GamePanel();
c.gridx = 0;
c.gridy = 0;
firstPanel.add(textFieldForPlayers(humanPLayers), c);
c.gridx = 0;
c.gridy = 1;
firstPanel.add(botPreferences(), c);
c.gridx = 0;
c.gridy = 2;
firstPanel.add(next = new JButton("Next"), c);
c.gridx = 0;
c.gridy = 0;
secondPanel.add(new JLabel("Bot preferences"), c);
c.gridx = 0;
c.gridy = 0;
thirdPanel.add(gamePanel, c);
deck.add(firstPanel, "1");
deck.add(secondPanel, "2");
deck.add(thirdPanel, "3");
cl.show(deck, "1");
events();
}
private JPanel textFieldForPlayers(int hplayers) {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
c = new GridBagConstraints();
JLabel text = new JLabel("Name of the human players");
c.gridx = 0;
c.gridy = 0;
panel.add(text, c);
boxes = new ArrayList<>();
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
for (int i = 1; i <= hplayers; i++) {
boxes.get(i).setPreferredSize(new Dimension(165, 18));
c.gridx = 1;
c.gridy = i;
panel.add(boxes.get(i), c);
c.gridx = 0;
c.gridy = i;
panel.add(new JLabel("Player " + i + ": "), c);
}
return panel;
}
Picture 3 - This is what it looks like now
Picture 4 - Should be - 1 in the top, 2 in the middle and 3 in the bottom. All of them centeret.
Your CardLayout, cl, is not behaving as a true CardLayout, suggesting something is wrong with code not shown. Myself, I try to modularize my gui creation, including using a separate utility method to help create gridbagconstraints if any complex constraints are needed.
For example:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
#SuppressWarnings("serial")
public class GridBagEg extends JPanel {
public static final int PLAYER_COUNT = 5;
private CardLayout cardLayout = new CardLayout();
private JPanel deckPanel = new JPanel(cardLayout);
private NextAction nextAction = new NextAction("Next");
private PlayerPanel playerPanel = new PlayerPanel(PLAYER_COUNT);
private BotDifficultyPanel botDifficultyPanel = new BotDifficultyPanel();
public GridBagEg() {
deckPanel.add(playerPanel, PlayerPanel.NAME);
deckPanel.add(botDifficultyPanel, BotDifficultyPanel.NAME);
JPanel nextBtnPanel = new JPanel();
nextBtnPanel.add(new JButton(nextAction));
setLayout(new BorderLayout());
add(deckPanel, BorderLayout.CENTER);
add(nextBtnPanel, BorderLayout.PAGE_END);
}
private class NextAction extends AbstractAction {
public NextAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.next(deckPanel);
}
}
private static void createAndShowGui() {
GridBagEg mainPanel = new GridBagEg();
JFrame frame = new JFrame("GridBagEg");
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(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class BotDifficultyPanel extends JPanel {
public static final String NAME = "bot difficulty panel";
public static final String[] LEVELS = {"Easy", "Mid-level", "Difficult", "Holy Mother of God Difficulty"};
private JComboBox<String> difficultyCombo = new JComboBox<>(LEVELS);
public BotDifficultyPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(new JLabel("Bot Difficulty:"), gbc);
gbc.gridx = 1;
gbc.insets = new Insets(0, 10, 0, 0);
add(difficultyCombo, gbc);
}
public String getSelectedDifficulty() {
String selection = (String) difficultyCombo.getSelectedItem();
return selection;
}
}
#SuppressWarnings("serial")
class PlayerPanel extends JPanel {
public static final String NAME = "player panel";
private static final String TITLE = "Name of Human Players";
private static final int EB_GAP = 10;
private static final int FIELD_COLUMNS = 15;
private static final int INS_GAP = 5;
private int playerMaxCount = 0;
private List<JTextField> playerFields = new ArrayList<>();
public PlayerPanel(int playerMaxCount) {
this.playerMaxCount = playerMaxCount;
Border outsideBorder = BorderFactory.createTitledBorder(TITLE);
Border insideBorder = BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP);
setBorder(BorderFactory.createCompoundBorder(outsideBorder, insideBorder));
setLayout(new GridBagLayout());
for (int i = 0; i < playerMaxCount; i++) {
JTextField playerField = new JTextField(FIELD_COLUMNS);
playerFields.add(playerField);
add(new JLabel("Player " + i + ":"), createGbc(0, i));
add(playerField, createGbc(1, i));
}
}
public String getFieldName(int index) {
if (index < 0 || index >= playerFields.size()) {
String text = "for playerFields index of " + index;
throw new IllegalArgumentException(text);
} else {
return playerFields.get(index).getText();
}
}
public int getPlayerMaxCount() {
return playerMaxCount;
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
// if x is 0, anchor to the left otherwise to the right
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(INS_GAP, INS_GAP, INS_GAP, INS_GAP);
if (x == 0) {
gbc.insets.right = 4 * INS_GAP; // increase gap in between
}
return gbc;
}
}
Like:
CardLayout cl = new CardLayout();
JPanel contentPane = new JPanel();
JPanel firstPanel = new JPanel();
JPanel secondPanel = new JPanel();
contentPane.setlayout(cl);
firstPanel.add(new JButton("1"));
secondPanel.add(new JButton("2"));
contentPane.add(firstPanel, "1");
contentPane.add(secondPanel, "2");
cl.show(contentPane, "1");
So now the contentPane contains 2 JPanels inside it. and now we would be seeing everything on firstPanel right? :)

JTextArea height is only 1 line when using GridBayLayout

I am doing a program that finds words in a text file. I am using GridBagLayout for the position of the elements. When I run the program the text area shows with just one line. Even though it is set JTextArea results = new JTextArea(30, 30)
This is what it shows at the moment:
I am trying to do something like this:
Java code:
public class WordFinder extends JFrame {
private WordList words = new WordList();
private static final int WINDOW_WIDTH = 380;
private static final int WINDOW_HEIGHT = 380;
private static final int TEXT_WIDTH = 30;
private JLabel findLabel = new JLabel("Find:");
private JLabel wordsContaining = new JLabel("words containing");
private JTextField findWord = new JTextField(TEXT_WIDTH);
private JButton clear = new JButton("Clear");
private JTextArea results = new JTextArea(30, 30);
private JScrollPane scroll = new JScrollPane(results);
private JFileChooser chooseFile = new JFileChooser();
private JPanel pane = new JPanel(new GridBagLayout());
public WordFinder() {
super("Word Finder");
// Initialize the menu bar
//initMenu();
results.setEditable(false);
pane.setLayout(new GridBagLayout());
pane.setBorder(new EmptyBorder(15, 20, 0, 10));
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.PAGE_START;
results.setLineWrap(true);
results.setWrapStyleWord(true);
scroll.setViewportView(results);
// Add label "Find"
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
pane.add(findLabel, c);
// Add text field
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 1;
c.gridy = 0;
pane.add(findWord, c);
// Add clear button
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = .1;
c.gridx = 2;
c.gridy = 0;
pane.add(clear, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 2;
c.insets = new Insets(5, 5, 0, 0);
pane.add(wordsContaining, c);
// Add text area
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1;
c.gridx = 1;
c.gridy = 3;
c.insets = new Insets(0, 3, 0, 5);
pane.add(scroll, c);
add(pane);
setVisible(true);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run () {
new WordFinder().show();
}
});
}
}
Any ideas in what am I missing? or perhaps I am doing something wrong?
Change c.fill = GridBagConstraints.HORIZONTAL; to c.fill = GridBagConstraints.BOTH;
Use pack instead of setSize
For example
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class WordFinder extends JFrame {
private static final int WINDOW_WIDTH = 380;
private static final int WINDOW_HEIGHT = 380;
private static final int TEXT_WIDTH = 30;
private JLabel findLabel = new JLabel("Find:");
private JLabel wordsContaining = new JLabel("words containing");
private JTextField findWord = new JTextField(TEXT_WIDTH);
private JButton clear = new JButton("Clear");
private JTextArea results = new JTextArea(30, 30);
private JScrollPane scroll = new JScrollPane(results);
private JFileChooser chooseFile = new JFileChooser();
private JPanel pane = new JPanel(new GridBagLayout());
public WordFinder() {
super("Word Finder");
// Initialize the menu bar
//initMenu();
results.setEditable(false);
pane.setLayout(new GridBagLayout());
pane.setBorder(new EmptyBorder(15, 20, 0, 10));
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.PAGE_START;
results.setLineWrap(true);
results.setWrapStyleWord(true);
scroll.setViewportView(results);
// Add label "Find"
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
pane.add(findLabel, c);
// Add text field
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 1;
c.gridy = 0;
pane.add(findWord, c);
// Add clear button
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = .1;
c.gridx = 2;
c.gridy = 0;
pane.add(clear, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 2;
c.insets = new Insets(5, 5, 0, 0);
pane.add(wordsContaining, c);
// Add text area
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
c.gridx = 1;
c.gridy = 3;
c.insets = new Insets(0, 3, 0, 5);
pane.add(scroll, c);
add(pane);
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new WordFinder().setVisible(true);
}
});
}
}
The problem you're having is caused by a combination of using the fill property GridBagConstraints.HORIZONTAL and setSize. When you use setSize, the size of the container is smaller then the JScrollPane's preferredSize and the layout manager is resorting to it's minimumSize instead.
By using GridBagConstraints.BOTH, you are allowing the layout manager to expand the component to fill the entire available space of the cell, regardless

JCheckboxes and JButton not showing randomly

I have a basic gui (it doesn't need to look pretty, it just needs to work. It's a gui to display several algorithms I'm implementing for my thesis.) but the checkboxes and button won't show up randomly. Sometimes they appear, sometimes they don't. I honestly have no clue why this could be happening and I'm pretty scrub at swing, so I'm lost.
EDIT: Here's what i want my gui to look like:
//import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;
import javax.swing.ButtonGroup;
import javax.swing.*; //notice javax
public class MapWindowController extends JFrame implements ActionListener, ItemListener
{
private static final int WIDTH = 600, HEIGHT = 800;
private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
private static final int NUM_MAP_TYPE = 2;
private static final int NUM_ALGORITHM_TYPE = 4;
private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;
private JButton run;
private JCheckBox[] map_type;
private JCheckBox[] algorithm_type;
JPanel panel = new JPanel();
JPanel settings_panel = new JPanel();
MapView map_view = new MapView(MAP_IMAGE_SIZE);
SettingsButtonsPanel settings = new SettingsButtonsPanel();
MapModel map_model = new MapModel(ACTUAL_MAP_SIZE, map_view);
ButtonGroup bgMap;
ButtonGroup bgAlgorithm;
public MapWindowController()
{
setLocationRelativeTo(null);
setTitle("HPA* Test");
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(panel);
panel.setBounds(0, 0, 600, 800);
panel.setLayout(null);
/*GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;*/
instantiateSettingsPanel();
//panel.add(settings);
/*c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;*/
panel.add(map_view);
map_view.setBounds(0,200,600,600);
//button_panel.setBounds(0,0);
map_view.repaint();
}
public void instantiateSettingsPanel() {
settings_panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//this.setLayout(null);
map_type = new JCheckBox[NUM_MAP_TYPE];
map_type[0] = new JCheckBox("Sparse");
map_type[0].setSelected(true);
map_type[1] = new JCheckBox("Maze");
map_type[1].setSelected(false);
algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];
algorithm_type[0] = new JCheckBox("A*");
algorithm_type[0].setSelected(true);
algorithm_type[1] = new JCheckBox("HPA*");
algorithm_type[1].setSelected(false);
algorithm_type[2] = new JCheckBox("TA*");
algorithm_type[2].setSelected(true);
algorithm_type[3] = new JCheckBox("PTHPA*");
algorithm_type[3].setSelected(false);
bgMap = new ButtonGroup( );
bgAlgorithm = new ButtonGroup( );
settings_panel.setMaximumSize(new Dimension(600,200));
for(int i = 0; i < NUM_MAP_TYPE; i++)
{
bgMap.add(map_type[i]);
map_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = i+1;
settings_panel.add(map_type[i], c);
}
for(int i = 0; i < NUM_ALGORITHM_TYPE; i++)
{
bgAlgorithm.add(algorithm_type[i]);
algorithm_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = i+1;
settings_panel.add(algorithm_type[i], c);
}
run = new JButton("Run");
run.addActionListener(this);
settings_panel.add(run);
panel.add(settings_panel);
settings_panel.setBounds(0,0,SETTINGS_WIDTH,SETTINGS_HEIGHT);
}
public void itemStateChanged(ItemEvent e)
{
Object source = e.getItemSelectable();
//if(source == )
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String algorithm = "A*";
String map = "Sparse";
for(int i = 0; i < algorithm_type.length; i++) {
if(algorithm_type[i].isSelected()) {
algorithm = algorithm_type[i].getText();
break;
}
}
for(int i = 0; i < map_type.length; i++) {
if(map_type[i].isSelected()) {
map = map_type[i].getText();
break;
}
}
if(source == run) {
if(map.equals("Sparse"))
map_model.createRandomObstaclesSparse(10, 1);
else
map_model.createRandomObstaclesMaze(1);
map_model.startPathfinding(algorithm, 0, true);
map_view.setMapScale(ACTUAL_MAP_SIZE);
map_view.setMapModel(map_model);
}
}
}
Your first mistake is using a null layout, your second mistake is calling setVisible before the UI is completed.
Your basic idea is sound, separating the various areas of responsibility into separate components, this will make you life much easier.
Basically, I used a GridBagLayout as it allows you to define fill weights for each component, providing a 1/4 of the vertical space to the buttons and the remainder to the map...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MapWindowController extends JFrame implements ActionListener, ItemListener {
private static final int WIDTH = 600, HEIGHT = 800;
private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
private static final int NUM_MAP_TYPE = 2;
private static final int NUM_ALGORITHM_TYPE = 4;
private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;
private JButton run;
private JCheckBox[] map_type;
private JCheckBox[] algorithm_type;
JPanel content = new JPanel();
JPanel settings_panel = new JPanel();
private JPanel mapPane = new JPanel(new BorderLayout());
ButtonGroup bgMap;
ButtonGroup bgAlgorithm;
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) {
}
new MapWindowController();
}
});
}
public MapWindowController() {
setLocationRelativeTo(null);
setTitle("HPA* Test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
content.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weighty = 0.25;
gbc.weightx = 1;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
content.add(settings_panel, gbc);
gbc.gridy++;
gbc.weighty = 0.75;
content.add(mapPane, gbc);
try {
mapPane.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/Map.png")))));
} catch (IOException ex) {
ex.printStackTrace();
}
add(content);
/*GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;*/
instantiateSettingsPanel();
//panel.add(settings);
/*c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;*/
pack();
setLocationByPlatform(true);
setVisible(true);
}
public void instantiateSettingsPanel() {
settings_panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//this.setLayout(null);
map_type = new JCheckBox[NUM_MAP_TYPE];
map_type[0] = new JCheckBox("Sparse");
map_type[0].setSelected(true);
map_type[1] = new JCheckBox("Maze");
map_type[1].setSelected(false);
algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];
algorithm_type[0] = new JCheckBox("A*");
algorithm_type[0].setSelected(true);
algorithm_type[1] = new JCheckBox("HPA*");
algorithm_type[1].setSelected(false);
algorithm_type[2] = new JCheckBox("TA*");
algorithm_type[2].setSelected(true);
algorithm_type[3] = new JCheckBox("PTHPA*");
algorithm_type[3].setSelected(false);
bgMap = new ButtonGroup();
bgAlgorithm = new ButtonGroup();
settings_panel.setMaximumSize(new Dimension(600, 200));
for (int i = 0; i < NUM_MAP_TYPE; i++) {
bgMap.add(map_type[i]);
map_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = i + 1;
settings_panel.add(map_type[i], c);
}
for (int i = 0; i < NUM_ALGORITHM_TYPE; i++) {
bgAlgorithm.add(algorithm_type[i]);
algorithm_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = i + 1;
settings_panel.add(algorithm_type[i], c);
}
run = new JButton("Run");
run.addActionListener(this);
settings_panel.add(run);
}
public void itemStateChanged(ItemEvent e) {
Object source = e.getItemSelectable();
//if(source == )
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String algorithm = "A*";
String map = "Sparse";
for (int i = 0; i < algorithm_type.length; i++) {
if (algorithm_type[i].isSelected()) {
algorithm = algorithm_type[i].getText();
break;
}
}
for (int i = 0; i < map_type.length; i++) {
if (map_type[i].isSelected()) {
map = map_type[i].getText();
break;
}
}
if (source == run) {
// if (map.equals("Sparse")) {
// map_model.createRandomObstaclesSparse(10, 1);
// } else {
// map_model.createRandomObstaclesMaze(1);
// }
// map_model.startPathfinding(algorithm, 0, true);
// map_view.setMapScale(ACTUAL_MAP_SIZE);
// map_view.setMapModel(map_model);
}
}
}
Don't use setSize of setBounds on a window, instead, use pack to automatically set the optimal size of the window based on it's contents preferred size.

setLocation of Label

I have all of the labels working correctly but the userLabel[3] is not positioning properly
No matter what I do, the label "Color:" always shows up on the frame with a x-coordinate of 0 and a y-coordinate that is half way down the frame.
JLabel[] userLabel = new JLabel[4];
for(int p = 0; p < userLabel.length; p++){
userLabel[p] = new JLabel();
userLabel[p].setSize(100,50);
frameSetUp.add(userLabel[p]);
}
userLabel[0].setText("Width of Frame:");
userLabel[1].setText("Height of Frame:");
userLabel[2].setText("# OF Balls:");
userLabel[3].setText("Color:");
userLabel[0].setLocation(10,35);
userLabel[1].setLocation(10,85);
userLabel[2].setLocation(10,135);
userLabel[3].setLocation(0,0); //no matter what coordinates I change this too, it wont reposition
Image:
[IMG]http://i41.tinypic.com/23jfo9l.png[/IMG]
http://i41.tinypic.com/23jfo9l.png
Don't use setLocation, setBounds, null layouts or absolute positioning.
Instead use the layout managers including perhaps nested JPanels, each using its own layout manager to achieve pleasing easy to maintain GUI's.
For more help, show a picture of what you're trying to achieve, what you actually are achieving, and post a minimal working example, code that is small, that compiles and runs, and shows us your problem.
e.g.,
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class InputForm extends JPanel {
private static final int COLUMNS = 10;
private static final int GAP = 3;
private static final Insets LABEL_INSETS = new Insets(GAP, GAP, GAP, 15);
private static final Insets TEXTFIELD_INSETS = new Insets(GAP, GAP, GAP, GAP);
private String[] labelTexts;
private Map<String, JTextField> fieldMap = new HashMap<String, JTextField>();
public InputForm(String[] labelTexts) {
this.labelTexts = labelTexts;
setLayout(new GridBagLayout());
for (int i = 0; i < labelTexts.length; i++) {
String text = labelTexts[i];
JTextField field = new JTextField(COLUMNS);
fieldMap.put(text, field);
addLabel(text, i);
addTextField(field, i);
}
}
public String[] getLabelTexts() {
return labelTexts;
}
private void addTextField(JTextField field, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.gridx = 1;
gbc.gridy = row;
gbc.anchor = GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = TEXTFIELD_INSETS;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
add(field, gbc);
}
private void addLabel(String text, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.gridx = 0;
gbc.gridy = row;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = LABEL_INSETS;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
add(new JLabel(text), gbc);
}
public String getFieldText(String key) {
String text = "";
JTextField field = fieldMap.get(key);
if (field != null) {
text = field.getText();
}
return text;
}
private static void createAndShowGui() {
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Color:" };
InputForm inputForm = new InputForm(labelTexts);
int result = JOptionPane.showConfirmDialog(null, inputForm, "Input Form",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
for (String text : labelTexts) {
System.out.printf("%20s %s%n", text, inputForm.getFieldText(text));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which will display like so:
The beauty of this code, is if you wish to add another field, say a line thickness field, and want to add it so that it is second to last, then the only change needed to the code would be to change this:
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Color:" };
to this:
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Line Thickness:", "Color:" };
Which results in:
No need to have to calculate how to change the Color label or JTextField's locations as the layout manager does all the hard work for you.
Finally got the answer try increasing the size of the JLabel array by 1 and run it will work fine
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Labelss{
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setBounds(50, 50, 700, 550);
JLabel[] userLabel = new JLabel[6];
for(int p = 0; p < userLabel.length; p++){
userLabel[p] = new JLabel();
}
userLabel[0].setBounds(10,35,100,50);
userLabel[1].setBounds(10,85,100,50);
userLabel[2].setBounds(10,135,100,50);
userLabel[3].setBounds(10,185,100,50);
userLabel[4].setBounds(10,235,100,50);
userLabel[0].setText("Width of Frame:");
userLabel[1].setText("Height of Frame:");
userLabel[2].setText("# OF Balls:");
userLabel[3].setText("Color:");
userLabel[4].setText("Stack overflow:");
for(int p = 0; p < userLabel.length; p++){
frame.add(userLabel[p]);
}
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Categories

Resources