Jpanels with Gridbaglayout inside a JPanel with GridbagLayout problems - java

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? :)

Related

Adding ChartPanel to CardLayout

I have a pretty basic GUI organized with a GridBagLayout. The most complex portion is the bottom where West is populated with ScrollPane and the right is a panel with a CardLayout that has multiple ChartPanels so I can switch between a few graphs.
My issue comes when I start the program.
The resizing issue goes away after I resize the frame in any direction. I have confirmed the chartpanel is the issue because not adding this to the CardLayout panel fixes it. I create a blank ChartPanel and populate it later after some action is taken but this is what I've done:
public class Tester {
public static void main(String[] args) {
JFrame frame = new JFrame("Chipmunk: Variant Data Collection Tool");
JPanel hotspotPanel = new JPanel(new CardLayout());
ChartPanel subHotspotPanel = new ChartPanel(null);
JPanel indelHotspotPanel = new JPanel(new BorderLayout());
JTextPane resultPane = new JTextPane();
JPanel main = new JPanel(new GridBagLayout());
JPanel header = new JPanel(new BorderLayout());
header.setBackground(Color.WHITE);
frame.setLayout(new BorderLayout());
frame.setMinimumSize(new Dimension(875, 600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
resultPane.setOpaque(false);
resultPane.setEditable(false);
GridBagConstraints c = new GridBagConstraints();
DocumentFilter filter = new UppercaseDocumentFilter();
JTextField geneField = new JTextField(10);
((AbstractDocument) geneField.getDocument()).setDocumentFilter(filter);
geneField.setMinimumSize(geneField.getPreferredSize());
JTextField proEffField = new JTextField(10);
proEffField.setMinimumSize(proEffField.getPreferredSize());
String[] mutTypes = { "missense", "nonsense", "frameshift", "nonframeshift"};
JComboBox<String> mutTypeComboBox = new JComboBox<String>(mutTypes);
JButton saveResultsButton = new JButton("Save to TSV");
JPanel glass = (JPanel) frame.getGlassPane();
JButton clearButton = new JButton("Clear");
JButton cosmicButton = new JButton("To COSMIC");
JButton dataButton = new JButton("Show Data");
dataButton.setEnabled(false);
JButton goButton = new JButton("GO");
c.weightx = 1.0;c.gridx = 0;c.gridy = 0;c.anchor = GridBagConstraints.EAST;c.ipadx=5;c.ipady=5;
main.add(new JLabel("Gene: "), c);
c.gridx = 1;c.gridy = 0;c.anchor = GridBagConstraints.WEST;
main.add(geneField, c);
c.gridx = 0;c.gridy = 1;c.anchor = GridBagConstraints.EAST;
main.add(new JLabel("Protein Effect: "), c);
c.gridx = 1;c.gridy = 1;c.anchor = GridBagConstraints.WEST;
main.add(proEffField, c);
c.gridx =0;c.gridy = 2;c.anchor = GridBagConstraints.EAST;
main.add(new JLabel("Mutation Type: "), c);
c.gridx =1;c.gridy = 2;c.anchor = GridBagConstraints.WEST;
main.add(mutTypeComboBox, c);
c.gridx =0;c.gridy = 3;c.anchor = GridBagConstraints.WEST;
main.add(saveResultsButton, c);
c.gridx = 0;c.gridy = 3;c.anchor = GridBagConstraints.EAST;
main.add(goButton, c);
c.gridx = 1;c.gridy = 3;c.anchor = GridBagConstraints.WEST;
main.add(clearButton,c);
c.gridx = 0;c.gridy = 3;c.anchor = GridBagConstraints.CENTER;
main.add(dataButton,c);
c.gridx = 1;c.gridy = 3;c.anchor = GridBagConstraints.EAST;
main.add(cosmicButton,c);
c.gridx = 0; c.gridy =4;c.gridwidth =1; c.weightx = 1.0;c.weighty = 1.0; c.fill = GridBagConstraints.BOTH;
JScrollPane scrollPane = new JScrollPane(resultPane);
main.add(scrollPane, c);
c.gridx = 1; c.gridy =4;c.gridwidth = 1; c.weightx = 1.0;c.weighty = 1.0; c.fill = GridBagConstraints.BOTH;
hotspotPanel.add(subHotspotPanel, "SUBPANEL");
hotspotPanel.add(indelHotspotPanel, "INDELPANEL");
hotspotPanel.add(new JPanel(), "BLANK");
main.add(hotspotPanel, c);
frame.add(header, BorderLayout.NORTH);
frame.add(main, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
Using this example, it's clear that a ChartPanel works correctly in a CardLayout. The example below overrides getPreferredSize(), as shown here, to establish an initial size for the ChartPanel. The use of GridLayout on each card allows the chart to fill the panel as the enclosing frame is resized.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
/**
* #see https://stackoverflow.com/a/36392696/230513
* #see https://stackoverflow.com/a/36243395/230513
*/
public class CardPanel extends JPanel {
private static final Random r = new Random();
private static final JPanel cards = new JPanel(new CardLayout());
private final String name;
public CardPanel(String name) {
super(new GridLayout());
this.name = name;
DefaultPieDataset pieDataset = new DefaultPieDataset();
pieDataset.setValue("One", r.nextInt(10) + 10);
pieDataset.setValue("Two", r.nextInt(20) + 10);
pieDataset.setValue("Three", r.nextInt(30) + 10);
JFreeChart chart = ChartFactory.createPieChart3D(
"3D Pie Chart", pieDataset, true, true, true);
chart.setTitle(name);
this.add(new ChartPanel(chart) {
#Override
public Dimension getPreferredSize() {
return new Dimension(500, (int)(500 * 0.62));
}
});
}
#Override
public String toString() {
return name;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i = 1; i < 9; i++) {
CardPanel p = new CardPanel("Chart " + String.valueOf(i));
cards.add(p, p.toString());
}
JPanel control = new JPanel();
control.add(new JButton(new AbstractAction("\u22b2Prev") {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) cards.getLayout();
cl.previous(cards);
}
}));
control.add(new JButton(new AbstractAction("Next\u22b3") {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) cards.getLayout();
cl.next(cards);
}
}));
f.add(cards, BorderLayout.CENTER);
f.add(control, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

Making GridBagLayout more compact

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);
}
}

Java GUI: How do I have more than one button on a row using GridBagLayout

I'm fairly new to java and I'm having a problem trying to put more than one button on a row,
at the moment I'm adding both buttons to the panel, but I don't know how to separate their x locations, i.e. they are both being added directly on to of each other.
Do I need to create a new layout or can I find a solution using what I have at the moment?
public class Question1 {
public static void main (String[] args){
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame{
MyFrame(String title){
super(title);
}
private JPanel mainPanel;
private GridBagConstraints cText = new GridBagConstraints();
private GridBagConstraints cButton = new GridBagConstraints();
private GridBagLayout gbLayout = new GridBagLayout();
void init(){
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10,20,10,20));
this.setContentPane(mainPanel);
cText.anchor = GridBagConstraints.WEST;
cText.weightx = 0.0;
cText.gridx = 0;
cText.gridy = 0;
JTextField tf = new JTextField(20);
gbLayout.setConstraints(tf,cText);
mainPanel.add(tf);
cButton.gridwidth = 4;
cButton.weightx = 0.0;
cButton.gridx = 0;
cButton.gridy = 1;
JButton b = new JButton("Submit");
gbLayout.setConstraints(b,cButton);
mainPanel.add(b);
b = new JButton("Cancel");
gbLayout.setConstraints(b,cButton);
mainPanel.add(b);
this.pack();
this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE) ;
this.setVisible(true);
}
Just increment the gridx value:
JButton b = new JButton("Submit");
// gbLayout.setConstraints(b,cButton);
mainPanel.add(b, cButton);
b = new JButton("Cancel");
cButton.gridx++;
// gbLayout.setConstraints(b,cButton);
mainPanel.add(b, cButton);
Also you need to use the constraints created when adding your component to the grid bag layout using container.
e.g.,
import java.awt.*;
import javax.swing.*;
public class Question1 {
public static void main(String[] args) {
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame {
private static final int GAP = 2;
MyFrame(String title) {
super(title);
}
private JPanel mainPanel;
private GridBagLayout gbLayout = new GridBagLayout();
void init() {
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
this.setContentPane(mainPanel);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
gbc.gridwidth = 2;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
JTextField tf = new JTextField(20);
mainPanel.add(tf, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
JButton b = new JButton("Submit");
mainPanel.add(b, gbc);
b = new JButton("Cancel");
gbc.gridx++;
mainPanel.add(b, gbc);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
Try the following code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Question1 {
public static void main(String[] args) {
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame {
MyFrame(String title) {
super(title);
}
private JPanel mainPanel;
private GridBagConstraints cText = new GridBagConstraints();
private GridBagConstraints cButton = new GridBagConstraints();
private GridBagLayout gbLayout = new GridBagLayout();
void init() {
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
this.setContentPane(mainPanel);
cText.anchor = GridBagConstraints.WEST;
cText.weightx = 0.0;
cText.gridx = 0;
cText.gridy = 0;
JTextField tf = new JTextField(20);
gbLayout.setConstraints(tf, cText);
mainPanel.add(tf);
cButton.gridwidth = 4;
cButton.weightx = 0.0;
cButton.gridx = 0;
cButton.gridy = 1;
JPanel demoPanel = new JPanel();
JButton b = new JButton("Submit");
gbLayout.setConstraints(demoPanel, cButton);
demoPanel.add(b);
b = new JButton("Cancel");
// gbLayout.setConstraints(b,cButton);
demoPanel.add(b);
mainPanel.add(demoPanel);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
I have just put the two buttons inside a JPanel and put the JPanel inside the GridBagLayout Panel !

Fixed size of buttons

There is a JPanel with buttons and textField. TextField filters unnecessary buttons by name. But after delete the size of rest buttons is changing.
The height of buttons must not change after filtering in the textField. How to achieve this?
public class TestViewer {
public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {
public void run() {
JDialog dialog = new TestDialog();
dialog.setLocationRelativeTo(null);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Type text and press Enter");
dialog.setSize(300, 700);
dialog.setVisible(true);
dialog.setLocationRelativeTo(null);
dialog.setModal(true);
}
});
}
}
class TestDialog extends JDialog {
public TestDialog() {
getContentPane().add(new JPan
el(), BorderLayout.CENTER);
getContentPane().add(createBtnPanel(), BorderLayout.CENTER);
}
private JPanel createBtnPanel() {
int n = 100;
Final String ArrButtonNames[] = new String[n];
for (int h = 0; h < ArrButtonNames.length; h++) {
if ((h%2)==0){
ArrButtonNames[h]="Filter"+h;
}
else{
ArrButtonNames[h]="Button"+h;
}
}
final JButton ArrButton[] = new JButton[n];
final JPanel btnPanel = new JPanel(new GridLayout(0, ArrButtonNames.length, 1,1));
btnPanel.setLayout(new GridLayout(0, 1));
final JTextField textField = new JTextField();
textField.setColumns(23);
btnPanel.add(textField);
for (int i = 0; i < ArrButtonNames.length; i++) {
String btnString = ArrButtonNames[i];
JButton button = new JButton(btnString);
Dimension d = button.getPreferredSize();
d.setSize(d.getWidth(), d.getHeight()*1);
button.setPreferredSize(d);
button.setSize(d);
button.setMinimumSize(d);
button.setMaximumSize(d);
btnPanel.add(button);
ArrButton[i] = button;
}
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int k = 0; k < ArrButtonNames.length; k++) {
if(ArrButtonNames[k].indexOf(textField.getText())==-1) {
btnPanel.remove(ArrButton[k]);
btnPanel.revalidate();
btnPanel.repaint();
}
}
}
});
JPanel MainPanel = new JPanel();
MainPanel.setLayout(new BorderLayout());
MainPanel.add(btnPanel, BorderLayout.NORTH);
final JScrollPane scrollPane = new JScrollPane(btnPanel);
MainPanel.add(scrollPane, BorderLayout.CENTER);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
return MainPanel;
}
}
You have that effect, because you use GridLayout, which resize components to fill whole cell.
For your purposes I recommend you to use GridBagLayout, that can do what you want.
Try to use next code for filling your btnPanel instead of yours:
final JButton ArrButton[] = new JButton[n];
final JPanel btnPanel = new JPanel();
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx=0;
c.gridy=0;
btnPanel.setLayout(new GridBagLayout());
final JTextField textField = new JTextField();
btnPanel.add(textField,c);
for (int i = 0; i < ArrButtonNames.length; i++) {
String btnString = ArrButtonNames[i];
JButton button = new JButton(btnString);
c.gridy ++;
btnPanel.add(button,c);
ArrButton[i] = button;
}
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
c.gridy ++;
btnPanel.add(new JLabel(""),c);
And it looks like:
ALso use pack() method instead of setSize(...), and don't use setPreferedSize(...) and others size methods read about that here.

Aligning panels with GridBagLayout

I'm not exactly new to java (I've been using it for a year now) but this is my first go at swing. I'm trying to make a very simple chat client to learn both socket and swing at once. My question is "What must I do to align my panels correctly?". I've tried a lot of things (Though I don't have it in my code). Usually I work something like this out on my own, but I'm to the point I need to ask for help. Do I need to change the wieghtx, weighty? What I want the client to look like is something like this.
This is what it currently looks like.
Here is my code.
package com.client.core;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
GridBagConstraints c = new GridBagConstraints();
//Main Panel
JPanel window = new JPanel();
window.setLayout(new GridBagLayout());
window.setBackground(Color.black);
//Panels
JPanel display = new JPanel();
JPanel chat = new JPanel();
chat.setLayout(new GridBagLayout());
JPanel users = new JPanel();
display.setBackground(Color.blue);
c.gridx = 0;
c.gridy = 0;
c.insets= new Insets(5,5,5,5);
window.add(display, c);
chat.setBackground(Color.red);
c.gridx = 0;
c.gridy = 3;
c.gridheight = 2;
c.gridwidth = 1;
c.insets= new Insets(5,5,5,5);
window.add(chat, c);
users.setBackground(Color.green);
c.gridx = 2;
c.gridy = 0;
c.insets= new Insets(5,5,5,5);
window.add(users, c);
//Buttons
//Text fields
JTextArea text = new JTextArea("DEREADFADSFEWFASDFSADFASDF");
c.gridx = 0;
c.gridy = 0;
chat.add(text);
JTextField input = new JTextField("type here to chat", 50);
c.gridx = 0;
c.gridy = 1;
c.insets= new Insets(5,5,5,5);
chat.add(input);
add(window);
}
static class ActLis implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
}
If you wanted something like this as an output :
You can take help from this code example, though you can remove the last ButtonPanel if you don't need that :
package to.uk.gagandeepbali.swing.messenger.gui;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JTextField;
public class ChatPanel extends JPanel
{
private JButton backButton;
private JButton exitButton;
private JButton sendButton;
private JTextPane chatPane;
private JTextPane namePane;
private JTextField chatField;
private GridBagConstraints gbc;
private final int GAP = 10;
private final int SMALLGAP = 1;
public ChatPanel()
{
gbc = new GridBagConstraints();
}
protected void createGUI()
{
setOpaque(true);
setBackground(Color.WHITE);
setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
centerPanel.setOpaque(true);
centerPanel.setBackground(Color.WHITE);
centerPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, 0, GAP));
centerPanel.setLayout(new GridBagLayout());
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 5;
gbc.weightx = 0.8;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
chatPane = new JTextPane();
JScrollPane scrollerChat = new JScrollPane();
scrollerChat.setBorder(BorderFactory.createTitledBorder("Chat"));
scrollerChat.setViewportView(chatPane);
centerPanel.add(scrollerChat, gbc);
gbc.gridx = 5;
gbc.gridwidth = 2;
gbc.weightx = 0.2;
namePane = new JTextPane();
JScrollPane scrollerName = new JScrollPane(namePane);
scrollerName.setBorder(BorderFactory.createTitledBorder("Names"));
centerPanel.add(scrollerName, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
gbc.gridwidth = 5;
gbc.weightx = 0.8;
gbc.weighty = 0.1;
gbc.fill = GridBagConstraints.HORIZONTAL;
chatField = new JTextField();
chatField.setOpaque(true);
chatField.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("")
, BorderFactory.createEmptyBorder(SMALLGAP, SMALLGAP, SMALLGAP, SMALLGAP)));
centerPanel.add(chatField, gbc);
gbc.gridx = 5;
gbc.gridwidth = 2;
gbc.weightx = 0.2;
sendButton = new JButton("Send");
sendButton.setBorder(BorderFactory.createTitledBorder(""));
centerPanel.add(sendButton, gbc);
JPanel bottomPanel = new JPanel();
bottomPanel.setOpaque(true);
bottomPanel.setBackground(Color.WHITE);
bottomPanel.setBorder(
BorderFactory.createTitledBorder(""));
bottomPanel.setLayout(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.setOpaque(true);
buttonPanel.setBackground(Color.WHITE);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, 0, GAP));
backButton = new JButton("Back");
exitButton = new JButton("Exit");
buttonPanel.add(backButton);
buttonPanel.add(exitButton);
bottomPanel.add(buttonPanel, BorderLayout.CENTER);
add(centerPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
public JTextPane getChatPane()
{
return chatPane;
}
public JTextPane getNamePane()
{
return namePane;
}
public JTextField getChatField()
{
return chatField;
}
public JButton getExitButton()
{
return exitButton;
}
public JButton getBackButton()
{
return backButton;
}
public JButton getSendButton()
{
return sendButton;
}
}
What you could do, and probably gives the desired result
JPanel somethingHere = ...;
JPanel chat = ...;
JPanel userList = ...;
JPanel leftPanel = new JPanel( new BorderLayout() );
leftPanel.add( somethingHere, BorderLayout.CENTER );
leftPanel.add( chat, BorderLayout.SOUTH );
JPanel total = new JPanel( new BorderLayout() );
total.add( leftPanel, BorderLayout.CENTER );
total.add( userList, BorderLayout.EAST );
Way simpler then messing with GridBagLayout
Here is what I came out with thus far. The red box is where I plan to add a simple 2D avatar interface with LWJGL.
Here is the code for it
package com.client.core;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
//Main Panels
JPanel window = new JPanel(new BorderLayout());
JPanel center = new JPanel(new BorderLayout());
JPanel right = new JPanel(new BorderLayout());
//Panels
JPanel display = new JPanel( new BorderLayout());
display.setBackground(Color.red);
JPanel chat = new JPanel();
chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
chat.setBackground(Color.blue);
JPanel users = new JPanel(new BorderLayout());
users.setBackground(Color.green);
//TextFields
JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50);
chatBox.setEditable(false);
JTextField chatWrite = new JTextField();
JScrollPane userList = new JScrollPane();
JTextField userSearch = new JTextField(10);
userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
users.add(userList);
users.add(userSearch, BorderLayout.NORTH);
chat.add(chatBox);
chat.add(chatWrite);
chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
//Menu bar
JMenuBar menu = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem exit = new JMenuItem("Exit");
JMenuItem ipconnect = new JMenuItem("Connect to IP");
file.add(ipconnect);
file.add(exit);
menu.add(file);
//Main window adding
right.add(users);
center.add(display, BorderLayout.CENTER);
center.add(chat, BorderLayout.SOUTH);
window.add(center, BorderLayout.CENTER);
window.add(right, BorderLayout.EAST);
window.add(menu, BorderLayout.NORTH);
add(window);
//Listeners
chatWrite.addKeyListener(new KeyLis());
ipconnect.addActionListener(new ActLis());
exit.addActionListener(new ActLis());
}
static class KeyLis implements KeyListener{
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
System.out.println("Message recieved.");
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
static class ActLis implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand() == "Exit"){
System.exit(0);
} else if(e.getActionCommand() == "Connect to IP"){
System.out.println("Connecting....");
JFrame frameip = new JFrame();
JPanel panelip = new JPanel();
JButton buttonip = new JButton("Hello");
frameip.add(panelip);
panelip.add(buttonip);
JDialog ippop = new JDialog(frameip, "Enter IP", false);
}
}
}
}
I had to build a similar layout using a GridBagLayout. The code below shows how I achieved it.
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GridBagLayoutTest {
public GridBagLayoutTest() {
JFrame jframe = new JFrame();
jframe.setLayout(new GridBagLayout());
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(800, 600);
jframe.setVisible(true);
// Left
JPanel leftPanel = new JPanel(new GridBagLayout());
leftPanel.setBackground(Color.YELLOW);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.weightx = .7f;
gridBagConstraints.weighty = 1f;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
jframe.add(leftPanel, gridBagConstraints);
JPanel leftTopPanel = new JPanel(new FlowLayout());
leftTopPanel.setBackground(Color.RED);
GridBagConstraints gridBagConstraints0 = new GridBagConstraints();
gridBagConstraints0.fill = GridBagConstraints.BOTH;
gridBagConstraints0.weightx = 1f;
gridBagConstraints0.weighty = .7f;
gridBagConstraints0.gridx = 0;
gridBagConstraints0.gridy = 0;
leftPanel.add(leftTopPanel, gridBagConstraints0);
JPanel leftMiddlePanel = new JPanel(new FlowLayout());
leftMiddlePanel.setBackground(Color.BLACK);
gridBagConstraints0 = new GridBagConstraints();
gridBagConstraints0.fill = GridBagConstraints.BOTH;
gridBagConstraints0.weightx = 1f;
gridBagConstraints0.weighty = .2f;
gridBagConstraints0.gridx = 0;
gridBagConstraints0.gridy = 1;
leftPanel.add(leftMiddlePanel, gridBagConstraints0);
JPanel leftBottomBottomPanel = new JPanel(new FlowLayout());
leftBottomBottomPanel.setBackground(Color.PINK);
gridBagConstraints0 = new GridBagConstraints();
gridBagConstraints0.fill = GridBagConstraints.BOTH;
gridBagConstraints0.weightx = 1f;
gridBagConstraints0.weighty = .1f;
gridBagConstraints0.gridx = 0;
gridBagConstraints0.gridy = 2;
leftPanel.add(leftBottomBottomPanel, gridBagConstraints0);
// Right
JPanel rightPanel = new JPanel();
rightPanel.setBackground(Color.GREEN);
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.weightx = .3f;
gridBagConstraints.weighty = 1f;
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
jframe.add(rightPanel, gridBagConstraints);
}
public static void main (String args[]) {
new GridBagLayoutTest();
}

Categories

Resources