JLabel not showing in my grid of JButtons - java

Creating a game called reversi also known as Othello and I am trying to add the starting position of my Black and Whites counters (using JLabel, labelled 'W' and 'B') in the middle of the board diagonally opposite from each other but for some reason only 2 show up and the other 2 don't show, which I don't understand why.
How do I go about fixing it?
import java.io.*;
import java.util.*;
import java.lang.*;
import java.awt.*;
import javax.swing.*;
public class Reversi
{
// instance variables - replace the example below with your own
private JFrame frame;
private JLabel userName1;
private JLabel userName2;
private JTextField textUsername1;
private JTextField textUsername2;
private JButton startButton;
private JButton [][] squares = new JButton[8][8];
private JLabel whites = new JLabel("W");
private JLabel blacks = new JLabel("B");
/**
*
*/
public Reversi()
{
// initialise instance variables
gui();
}
/**
*
*/
public void gui()
{
frame = new JFrame("Reversi Game");
frame.setSize(800,800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
JPanel userInterface = new JPanel(new GridBagLayout());
userInterface.setBackground(Color.LIGHT_GRAY);
userInterface.setBorder(BorderFactory.createBevelBorder(0));
//userInterface.setPreferredSize(new Dimension(350,700));
GridBagConstraints c = new GridBagConstraints();
//c.anchor = GridBagConstraints.NORTH;
JPanel board = new JPanel();
board.setBackground(Color.GRAY);
board.setBorder(BorderFactory.createBevelBorder(1));
board.setPreferredSize(new Dimension(750, 700));
userName1 = new JLabel("Enter First player: ");
userName2 = new JLabel("Enter Second player: ");
textUsername1 = new JTextField(15);
textUsername2 = new JTextField(15);
startButton = new JButton("START");
c.gridx = 0;
c.gridy = 0;
userInterface.add(userName1, c);
c.gridx = 1;
userInterface.add(textUsername1, c);
c.gridx = 0;
c.gridy = 1;
userInterface.add(userName2, c);
c.gridx = 1;
userInterface.add(textUsername2, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
c.anchor = GridBagConstraints.SOUTH;
userInterface.add(startButton, c);
userInterface.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Players/Scoreboard"));
board.setLayout(new GridLayout(8,8));
for(int i = 0; i< 8; i++){
for (int j = 0; j < 8; j++)
{
squares[i][j] = new JButton();
squares[i][j].setBackground(Color.GREEN);
board.add(squares[i][j]);
}
}
squares[4][3].add(blacks);
squares[4][4].add(whites);
squares[3][4].add(blacks);
squares[3][3].add(whites);
frame.add(board, BorderLayout.CENTER);
JPanel wrapper = new JPanel();
wrapper.add(userInterface);
frame.add(wrapper, BorderLayout.LINE_END);
makeMenuBar();
frame.pack();
frame.setVisible(true);
}
private void makeMenuBar()
{
//Finish coding later
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
JMenu fileMenu = new JMenu("File");
menubar.add(fileMenu);
JMenuItem saveFile = new JMenuItem("Save File");
fileMenu.add(saveFile);
JMenuItem quitGame = new JMenuItem("Quit");
fileMenu.add(quitGame);
quitGame.addActionListener(ev -> {quit(); });
}
private void quit()
{
System.exit(0);
}
}

Each component (i.e. your JLabels (whites and blacks)) can only be added to a container once, if you need to add more labels, even if they have the same String inside, you have to create a new object for those, otherwise these will be shown in the last container you've added them.
squares[4][3].add(blacks);
squares[4][4].add(whites);
squares[3][4].add(blacks); // Only this one is added
squares[3][3].add(whites); // Only this one is added
You'll need something like this, or have an array of JLabels and add them to all your squares, then just call yourJLabelArray[i][j].setText("W") (or "B")
squares[4][3].add(new JLabel("B"));
squares[4][4].add(new JLabel("W"));
squares[3][4].add(new JLabel("B"));
squares[3][3].add(new JLabel("W"));

Related

I want my button not in the same row as my choose buttons in my gui? How will I do that?

How do I add a break to put my "Make pokemon" buttons and textarea not in the same row as my "Pokemon choice." I'm trying to put an empty JLabel, but I don't think it works.
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton(" Make Pokemon ");
private JButton bClear = new JButton(" Clear ");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel();
private JPanel bottomSubPanel = new JPanel();
private GUIListener listener = new GUIListener();
private Choice chSpe = new Choice();
private JLabel lEmp = new JLabel(" ");
private PokemonGUILizylf st;
private final int capacity = 10;
private PokemonGUILizylf[ ] stArr = new PokemonGUILizylf[capacity];
private int count = 0;
private String sOut = new String("");
private JTextArea textArea = new JTextArea(400, 500);
private JTextArea textArea2 = new JTextArea(400, 500);
private JScrollPane scroll = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lEmp = new JLabel(" ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
chSpe.add("Choose");
chSpe.add("Bulbasaur");
chSpe.add("Venusaur");
chSpe.add("Ivysaur");
chSpe.add("Squirtle");
chSpe.add("Wartortle");
chSpe.add("Blastoise");
chSpe.add("Charmander");
chSpe.add("Charmeleon");
chSpe.add("Charizard");
centerSubPanel.add(lSpe);
centerSubPanel.add(chSpe);
centerSubPanel.add(lEmp);
centerSubPanel.add(bDone);
centerSubPanel.add(lNew);
textArea.setPreferredSize(new Dimension(500, 200));
textArea.setEditable(false);
textArea2.setPreferredSize(new Dimension(500, 200));
textArea2.setEditable(false);
textArea.setBackground(Color.white);
textArea.setEditable(false);
scroll.setBorder(null);
centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
bottomSubPanel.add(lMsg);
bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
This is what my GUI looks like:
enter image description here
But it should show like this:
enter image description here
Can someone explain to me how I can do that?
Use a different layout manager (other then default FlowLayout which JPanel uses)
See Laying Out Components Within a Container for more details.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new PokemonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
// private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton("Make Pokemon ");
private JButton bClear = new JButton("Clear");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel(new GridBagLayout());
private JPanel bottomSubPanel = new JPanel();
// private GUIListener listener = new GUIListener();
private JComboBox<String> chSpe = new JComboBox<>();
private JLabel lEmp = new JLabel(" ");
// private PokemonGUILizylf st;
private final int capacity = 10;
// private PokemonGUILizylf[] stArr = new PokemonGUILizylf[capacity];
// private int count = 0;
// private String sOut = new String("");
// private JTextArea textArea = new JTextArea(400, 500);
// private JTextArea textArea2 = new JTextArea(400, 500);
//
// private JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
// JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
// this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
DefaultComboBoxModel<String> chSpeModel= new DefaultComboBoxModel<>();
chSpeModel.addElement("Choose");
chSpeModel.addElement("Bulbasaur");
chSpeModel.addElement("Venusaur");
chSpeModel.addElement("Ivysaur");
chSpeModel.addElement("Squirtle");
chSpeModel.addElement("Wartortle");
chSpeModel.addElement("Blastoise");
chSpeModel.addElement("Charmander");
chSpeModel.addElement("Charmeleon");
chSpeModel.addElement("Charizard");
chSpe.setModel(chSpeModel);
centerSubPanel.setBorder(new EmptyBorder(4, 4, 4, 4));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.LINE_END;
centerSubPanel.add(lSpe, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
centerSubPanel.add(chSpe);
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy++;
centerSubPanel.add(bDone, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
centerSubPanel.add(lNew, gbc);
gbc.gridx++;
gbc.gridheight = gbc.REMAINDER;
centerSubPanel.add(new JScrollPane(new JTextArea(10, 10)), gbc);
// textArea.setEditable(false);
// textArea2.setEditable(false);
//
// textArea.setBackground(Color.white);
// textArea.setEditable(false);
// scroll.setBorder(null);
// centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
// scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
// bottomSubPanel.add(lMsg);
// bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
// bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
}
}
Also, avoid using setPreferredSize, let the layout managers do their job. In the example I'm used insets (from GridBagConstraints) and an EmptyBorder to add some additional space around the components
Also, be careful of using AWT components (ie Choice), they don't always play nicely with Swing. In this case, you should be using JComboBox

Move method from one class to another

So I have a method makeBoard. I want to create a class called Board and move the makeBoard method into class Board, where it still adds the returned panel to the content pane of JFrame. Im not sure how to get the JPanel from Board class onto the JFrame content pane on the reversi class. Not sure how to proceed about this.
package reversi;
import java.io.*;
import java.util.*;
import java.lang.*;
import java.awt.*;
import javax.swing.*;
public class Reversi
{
public JFrame frame;
private JLabel userName1 = new JLabel("Enter First player: ");
private JLabel userName2 = new JLabel("Enter Second player: ");
private JTextField textUsername1 = new JTextField(15);
private JTextField textUsername2 = new JTextField(15);
private JButton startButton = new JButton("START");
private JButton [][] squares = new JButton[8][8];
public Reversi()
{
makeFrame();
makeMenuBar();
}
private void makePlayerPanel()
{
JPanel userInterface = new JPanel(new GridBagLayout());
userInterface.setBackground(Color.LIGHT_GRAY);
userInterface.setBorder(BorderFactory.createBevelBorder(0));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
userInterface.add(userName1, c);
c.gridx = 1;
userInterface.add(textUsername1, c);
c.gridx = 0;
c.gridy = 1;
userInterface.add(userName2, c);
c.gridx = 1;
userInterface.add(textUsername2, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
c.anchor = GridBagConstraints.SOUTH;
userInterface.add(startButton, c);
userInterface.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Players/Scoreboard"));
JPanel wrapper = new JPanel();
wrapper.add(userInterface);
frame.add(wrapper, BorderLayout.LINE_END);
frame.pack();
}
private void makeBoard()
{
JPanel board = new JPanel();
board.setBackground(Color.GRAY);
board.setBorder(BorderFactory.createBevelBorder(1));
board.setPreferredSize(new Dimension(750, 700));
board.setLayout(new GridLayout(8,8));
for(int i = 0; i< 8; i++){
for (int j = 0; j < 8; j++)
{
squares[i][j] = new JButton();
squares[i][j].setBackground(Color.GREEN);
board.add(squares[i][j]);
}
}
frame.add(board, BorderLayout.CENTER);
frame.pack();
}
public void makeFrame()
{
frame = new JFrame("Reversi Game");
frame.setSize(800,800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
makeBoard();
makePlayerPanel();
}
}
i did it like this:
public class Board {
private JButton [][] squares = new JButton[8][8];
public JFrame frame;
public JPanel makeBoard()
{
JPanel board = new JPanel();
board.setBackground(Color.GRAY);
board.setBorder(BorderFactory.createBevelBorder(1));
board.setPreferredSize(new Dimension(750, 700));
board.setLayout(new GridLayout(8,8));
for(int i = 0; i< 8; i++){
for (int j = 0; j < 8; j++)
{
squares[i][j] = new JButton();
squares[i][j].setBackground(Color.GREEN);
board.add(squares[i][j]);
}
}
return board;
}
}
in Reversi do like this:
Board b = new Board();
frame.add(b.makeBoard(), BorderLayout.CENTER);
frame.pack();
public class Board {
public void makeBoard(JPanel board)
{
board.setBackground(Color.GRAY);
board.setBorder(BorderFactory.createBevelBorder(1));
board.setPreferredSize(new Dimension(750, 700));
board.setLayout(new GridLayout(8,8));
for(int i = 0; i< 8; i++){
for (int j = 0; j < 8; j++)
{
squares[i][j] = new JButton();
squares[i][j].setBackground(Color.GREEN);
board.add(squares[i][j]);
}
}
frame.add(board, BorderLayout.CENTER);
frame.pack();
}
}
In Reversi class
public class Reversi
{
....
Board board = new Board();
board.makeBoard(new JPanle());
}

JTextField only shows a slit with GridBagLayout, solutions i found for similar problems didnt work

So have a JFrame which contains 2 JPanels and one Button using the GridBagLayout. But the problem lies with the Panels which also use GridBagLayouts. JPanel p_addIng has has a 3x2 Grid with two JTextFields in the first column one the the size of the first is fine but the second one is way too thin.
Some disclaimers ahead: ing stands for ingredient, gbc for GridBagConstraints, everything with b_var means its a swing component b = JButton, tf = JTextField, p = JPanel, cb = JCombobox.
What i've already tried because of other posts:
gbc_addIng.fill = GridBagConstraints.HORIZONTAL; gbc_addIng.weightx = 1;
i saw also somewhere to use the pack() method but this was for the JFrame and didn't do anything to fix the problem.
Here's the code:
//making a new panel
//initializing the new Panel
p_addIng = new JPanel();
p_addIng.setName("Adding an Ingredient");
p_addIng.setPreferredSize(ingPanelDim);
p_addIng.setLayout(new GridBagLayout());
GridBagConstraints gbc_ing = new GridBagConstraints(0, 0, 1, 1, 1, 0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH
new Insets(0,0,0,0),10, 10);
//the components of the panel
//TextField to set the name of the Ingredient
gbc_ing.gridx = 0; //the position of the component on the panel
gbc_ing.gridy = 0;
tf_ingName = new JTextField();
tf_ingName.setPreferredSize(new Dimension(ingPanelDim.width / 2, ingPanelDim.height/2));
tf_ingName.addActionListener(this);
p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel
//endOfTextFieldIngName
gbc_ing.gridx = 1;
gbc_ing.gridy = 0;
//button to add the ingredient
tf_amnt = new JTextField("Choose amount");
tf_amnt.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
tf_amnt.addActionListener(this);
p_addIng.add(tf_amnt, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 0;
UnitOfMeasurement[] un = {UnitOfMeasurement.g, UnitOfMeasurement.kg, UnitOfMeasurement.Stück, UnitOfMeasurement.L, UnitOfMeasurement.ml, UnitOfMeasurement.cm};
cb_measurement = new JComboBox<UnitOfMeasurement>(un);
cb_measurement.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
cb_measurement.addActionListener(this);
p_addIng.add(cb_measurement, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 0;
gbc_ing.gridy = 1;
b_addIng = new JButton("Add Ingredient");
b_addIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_addIng.addActionListener(this);
p_addIng.add(b_addIng, gbc_ing);
//endOfButtonToAddIng
//button to remove the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 1;
b_removeIng = new JButton("Remove Ingredient");
b_removeIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_removeIng.addActionListener(this);
p_addIng.add(b_removeIng, gbc_ing);
//endOfButtonToRemoveIng
//
frame.pack();
frame.add(p_addIng,gbc_frame);
//
Here ,as wished, is the fully functional class the only thing thats missing is the enumeration UnitOfMeasurement which contains the elements as shown in the list for cb_meausrement:
package WindowDesign;
import Food.UnitOfMeasurement;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
public class StartingWindow implements ActionListener {
//window dimension
private static final int WIDTH = 500;
private static final int HEIGHT = 200;
//
//the JFrame
private JFrame frame;
//JComponents
//adding an Ingredient
private JPanel p_addIng;
private Dimension ingPanelDim = new Dimension(WIDTH/2, HEIGHT/2);
private JButton b_addIng; //a button to add an Ingredient
private JButton b_removeIng;
private JTextField tf_ingName;
private JTextField tf_amnt;
private JComboBox<UnitOfMeasurement> cb_measurement;
//
//adding a Recipe
private JPanel p_addRecipe;
private JButton b_addRecipe; // add a Recipe to the list of Recipes
private JButton b_removeRecipe;
private JButton b_buildRecipe;
private JButton b_clearRecipe;
private JTextField tf_recipeName;
private JTextField tf_ingredient;
private JComboBox<UnitOfMeasurement> cb_measurementR;
//
//
private JButton b_findCombination; //find the right combination of things to buy
private JButton b_exit; //exit the program
public StartingWindow(String name) {
frame = new JFrame(name);
frame.setLayout(new GridBagLayout());
//constraints
GridBagConstraints gbc_frame = new GridBagConstraints();
frame.setSize(WIDTH, HEIGHT);
frame.setBackground(Color.LIGHT_GRAY);
gbc_frame.ipadx = 10;
gbc_frame.ipady = 10;
gbc_frame.weightx = 1;
gbc_frame.fill = GridBagConstraints.BOTH;
//Adding the Panels
gbc_frame.gridx = 0;
gbc_frame.gridy = 0;
implementIngredientPanel(gbc_frame);
gbc_frame.gridx += 1;
gbc_frame.gridy = 0;
implementRecipePanel(gbc_frame);
//
gbc_frame.gridx = 0;
gbc_frame.gridy = 1;
implementStartingPanel(gbc_frame);
/*
b_exit = new JButton("exit");
b_exit.addActionListener(this);
*/
/*
frame.add(b_findCombination);
frame.add(b_addIng);
frame.add(b_addRecipe);
frame.add(b_exit);
*/
frame.setResizable(false);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.requestFocus();
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
//helper function to organize code
private void implementIngredientPanel(GridBagConstraints gbc_frame){
//making a new panel
//initializing the new Panel
p_addIng = new JPanel();
p_addIng.setName("Adding an Ingredient");
p_addIng.setPreferredSize(ingPanelDim);
p_addIng.setLayout(new GridBagLayout());
GridBagConstraints gbc_ing = new GridBagConstraints(0, 0, 1, 1, 1, 0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0,0,0,0),10, 10);
//the components of the panel
//TextField to set the name of the Ingredient
gbc_ing.gridx = 0; //the position of the component on the panel
gbc_ing.gridy = 0;
tf_ingName = new JTextField();
tf_ingName.setPreferredSize(new Dimension(ingPanelDim.width / 2, ingPanelDim.height/2));
tf_ingName.addActionListener(this);
p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel
//endOfTextFieldIngName
gbc_ing.gridx = 1;
gbc_ing.gridy = 0;
//button to add the ingredient
tf_amnt = new JTextField("Choose amount");
tf_amnt.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
tf_amnt.addActionListener(this);
p_addIng.add(tf_amnt, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 0;
UnitOfMeasurement[] un = {UnitOfMeasurement.g, UnitOfMeasurement.kg, UnitOfMeasurement.Stück, UnitOfMeasurement.L, UnitOfMeasurement.ml, UnitOfMeasurement.cm};
cb_measurement = new JComboBox<UnitOfMeasurement>(un);
cb_measurement.setPreferredSize(new Dimension(ingPanelDim.width/4, ingPanelDim.height/2));
cb_measurement.addActionListener(this);
p_addIng.add(cb_measurement, gbc_ing);
//endOfButtonToAddIng
//button to add the ingredient
gbc_ing.gridx = 0;
gbc_ing.gridy = 1;
b_addIng = new JButton("Add Ingredient");
b_addIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_addIng.addActionListener(this);
p_addIng.add(b_addIng, gbc_ing);
//endOfButtonToAddIng
//button to remove the ingredient
gbc_ing.gridx = 2;
gbc_ing.gridy = 1;
b_removeIng = new JButton("Remove Ingredient");
b_removeIng.setPreferredSize(new Dimension(ingPanelDim.width/2, ingPanelDim.height/2));
b_removeIng.addActionListener(this);
p_addIng.add(b_removeIng, gbc_ing);
//endOfButtonToRemoveIng
//
frame.pack();
frame.add(p_addIng,gbc_frame);
//
}
private void implementRecipePanel(GridBagConstraints gbc_frame){
//Adding a Panel to add
p_addRecipe = new JPanel();
p_addRecipe.setName("Adding an Ingredient");
p_addRecipe.setPreferredSize(new Dimension(WIDTH/2, HEIGHT/2));
p_addRecipe.setLayout(new GridBagLayout());
GridBagConstraints gbc_recipe = new GridBagConstraints();
//the components:
//add Button to Add a Recipe
b_addRecipe = new JButton("Add Recipe");
b_addRecipe.addActionListener(this);
p_addRecipe.add(b_addRecipe, gbc_recipe );
//
frame.add(p_addRecipe, gbc_frame);
}
private void implementStartingPanel(GridBagConstraints c){
b_findCombination = new JButton("go shopping!");
b_findCombination.addActionListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
frame.add(b_findCombination, c);
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
}
}
Here is a working example that may or may not be what you're asking for...
package stackoverflow;
import javax.swing.*;
import java.awt.*;
public class IngredientJFrame {
public static void main(String... args) {
IngredientJFrame ingredientJFrame = new IngredientJFrame();
ingredientJFrame.init();
}
public void init() {
JFrame jFrame = new JFrame();
//making a new panel
//initializing the new Panel
JPanel p_addIng = new JPanel();
p_addIng.setLayout(new GridBagLayout());
GridBagConstraints gbc_ing = new GridBagConstraints();
JLabel l_addIng = new JLabel("Add Ingredient");
gbc_ing.gridx = 0;
gbc_ing.gridy = 0;
p_addIng.add(l_addIng, gbc_ing);
JTextField tf_ingName = new JTextField();
gbc_ing.gridx = 1;
gbc_ing.gridy = 0;
gbc_ing.fill = GridBagConstraints.HORIZONTAL;
p_addIng.add(tf_ingName, gbc_ing); //adding the component to the Panel
JLabel tf_amnt = new JLabel("Choose amount");
gbc_ing.gridx = 0;
gbc_ing.gridy = 1;
gbc_ing.fill = GridBagConstraints.NONE;
p_addIng.add(tf_amnt, gbc_ing);
JComboBox cb_measurement = new JComboBox();
gbc_ing.gridx = 1;
gbc_ing.gridy = 1;
gbc_ing.fill = GridBagConstraints.HORIZONTAL;
p_addIng.add(cb_measurement, gbc_ing);
JButton b_addIng = new JButton("Add Ingredient");
gbc_ing.gridx = 0;
gbc_ing.gridy = 2;
gbc_ing.fill = GridBagConstraints.NONE;
p_addIng.add(b_addIng, gbc_ing);
JButton b_removeIng = new JButton("Remove Ingredient");
gbc_ing.gridx = 1;
gbc_ing.gridy = 2;
p_addIng.add(b_removeIng, gbc_ing);
jFrame.pack();
jFrame.add(p_addIng);
jFrame.setSize(500, 500);
jFrame.setVisible(true);
}
}
GridBayLayout (GBL) and GridBagConstraints (GBC) are powerful, but hard to use properly, and easy to screw up.
Here are some pointers on how I use to use these two classes and other tips for making a Swing based UI:
Text, in general, should be displayed using a JLabel. That should help right away with your formatting.
In general with GBL and GBC we don't normally set actual sizes on our components. We allow the components to react to one another and fill the space as needed. Often times using JPanels inside of other JPanels to get the correct flow that we are looking for.
The way that I use GBC is most likely not great, but I hate having to remake that object over and over and over and over again. So, I reused it in my example, you just have to be careful when reusing that object because it is easy to set one particular field and forget to 'unset' it later. Thing insets.
Typically a component has an anonymous inner class that actually does the listening to the component.
but the second one is way too thin.
When using a GridBagLayout when a component can't be displayed at its preferred size, then then it is displayed at its minimum size. The minimum size for a JTextField is 0, so that is what you are seeing.
You have a couple of different problems:
p_addIng.setPreferredSize(ingPanelDim);
You are artificially restricting the size of the panel, which is causing the text field to display at its minimum size. Remove that statement.
Also, you appear to be attempting to have the text field and combo box fill the same space as the button. If you want to do this then you need to have the button span two columns:
//gbc_ing.gridx = 2;
gbc_ing.gridx = 1;
gbc_ing.gridwidth = 2;
Having said the above you seem to miss the point of using a layout manager. You should NOT be attempting to set the preferred size of each component. You define the component and let the layout manager do the work.
For example, when creating a JTextField you should be using:
JTextField textField = new JTextField(10);
to give a suggestion of how big the text field should be.

How to create new and dispose jcomponents multiple times?

(Sorry if this question is not done properly, I'm new. But at least I researched a lot before asking my own question)
Hello. I'm writing a blackjack game in java and it's turning quite massive. My problem is how to handle multiple instances of swing components, I guess you can call it. I can't figure out wether to create the components (such as jpanels and jbuttons) as class level, or in specific methods.
If I create them in their corresponding method, then my action listener can't see them, but if I create them as class level, then they get deleted when I call dispose().
class BlackjackGame extends JFrame implements ActionListener{
public void mainMenu(){
JPanel menuPane = new JPanel(new GridBagLayout()); //Init of main menu
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
JLabel menuTitle = new JLabel("Welcome to Blackjack!");//Main menu-content
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
JButton playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
JButton exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
JButton rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
this.add(menuPane,0);
}
//This is where I get problems
public void actionPerformed (ActionEvent event){
if(event.getSource() == playButton){
//I want the menuPane to disappear, and a transition into the game.
menuPane.dispose();
//Call method for the rest of the game.
}else if(event .getSource() etcetera etcetera){
etcetera etcetera
}
}
}
When done this way, the actionlistener cannot find my components, such as playButton or menuPane. But if I had introduced them as class level objects:
class BlackjackGame extends JFrame implements ActionListener{
JPanel menuPane = new JPanel(new GridBagLayout());
JLabel menuTitle = new JLabel("Welcome to Blackjack!");
JButton playButton = new JButton("Play!");
JButton exitButton = new JButton("Exit!");
JButton rulesButton = new JButton("Set rules.");
public void mainMenu(){
//Rest of code
}
public void actionPerformed(ActionEvent event){
menuPane.dispose();
//Rest of code
}
}
...then as I call menuPane.dispose(), how can I get it back when I want to call mainMenu() again? If I want to go back to the main menu, then I would need to create a new instance of menuPane, as well as all the buttons, but as they are class level and already disposed I can't.
Please help me, and thank you!
PS. I can post my full code as it is atm if it would help.
Edit: Dan's answer has been accepted, as it was indeed the correct answer and it worked for my specific program very well. Thank you and merry christmas!
First, unless I've misunderstood your code, menuPane.dispose() shouldn't work as JPanel does not have a function called dispose()
The best way to do what you want to do if you want to use the same menuPane for the menu. Instead of menuPane.dispose(); use remove(menuPane); and then add(yourOtherPanel);
Working Example
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class BlackjackGame extends JFrame implements ActionListener {
private JPanel menuPane;
private JLabel menuTitle;
private JButton playButton;
private JButton exitButton;
private JButton rulesButton;
private JPanel otherPane;
private JLabel otherTitle;
private JButton otherButton;
public BlackjackGame() {
mainMenu();
otherPanel();
setSize(400, 400);
setVisible(true);
}
private void mainMenu() {
menuPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
menuTitle = new JLabel("Welcome to Blackjack!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
add(menuPane);
}
private void otherPanel() {
otherPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
otherPane.setBackground(new Color(125,0,0));
otherPane.setBounds(620,220,175,250);
otherTitle = new JLabel("Welcome to Second Pane!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
otherPane.add(otherTitle, c);
otherButton = new JButton("Go Back!");
otherButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
otherPane.add(otherButton, c);
}
public void actionPerformed (ActionEvent event) {
if(event.getSource() == playButton) {
remove(menuPane);
add(otherPane);
validate();
repaint();
} else if(event.getSource() == otherButton) {
remove(otherPane);
add(menuPane);
validate();
repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new BlackjackGame());
}
}
Edit for comments
So the java method remove() only removes the object from the container, which in this case is the JFrame. This method does not effect the object it moves so the object can be reused later. Hence why in the code above I can just use the remove() and add() methods without redeclaring or remaking menuPane and otherPane.
As for why I declare the objects like this
`private JPanel menuPane;`
And then initialize like this
menuPane = new JPanel(new GridBagLayout());
This is because I want the ActionListener to be able to see the objects without initializing them straight away. The line private JPanel menuPane; makes the object a global variable and the line menuPane = new JPanel(new GridBagLayout()); makes it into what I am going to use. Doing it this way instead of JPanel menuPane = new JPanel(new GridBagLayout()); also means I can reuse the same variable in multiple methods. For example
private JPanel panel;
private void createPanelOne() {
panel = new JPanel(new FlowLayout());
...
add(panel);
}
private void createPanelTwo() {
panel = new JPanel(new GridBagLayout());
...
add(panel);
}
After doing this, you will have two JPanels in your JFrame and they will be different, but you only need to use one JPanel
This is the other way of declaring it and it makes a local variable. Local variables aren't visible to other methods outside of the method you are using unless you pass them through.
JPanel panel = new JPanel();
I wouldn't say this is a con in the slightest. I think sometimes it is good to use local variables in a method that shouldn't be visible to other methods.
Finally to pass local variables through to other methods you can use arguments in a method you have made. For example
public void setSomeValue(int val) {
someValue = val;
}

Why does GridBagLayout provide strange result?

I want the various components to spread out and fill the entire window.
Have you tried anything else? Yes, I tried GridLayout but then the buttons look huge. I also tried pack() which made the window small instead. The window should be 750x750 :)
What I was trying is this:
These 4 buttons on the top as a thin strip
The scroll pane with JPanels inside which will contain all the video conversion tasks. This takes up the maximum space
A JPanel at the bottom containing a JProgressBar as a thin strip.
But something seems to have messed up somewhere. Please help me solve this
SSCCE
import java.awt.*;
import javax.swing.*;
import com.explodingpixels.macwidgets.*;
public class HudTest {
public static void main(String[] args) {
HudWindow hud = new HudWindow("Window");
hud.getJDialog().setSize(750, 750);
hud.getJDialog().setLocationRelativeTo(null);
hud.getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton addVideo = HudWidgetFactory.createHudButton("Add New Video");
JButton removeVideo = HudWidgetFactory.createHudButton("Remove Video");
JButton startAll = HudWidgetFactory.createHudButton("Start All Tasks");
JButton stopAll = HudWidgetFactory.createHudButton("Stop All Tasks");
buttonPanel.add(addVideo);
buttonPanel.add(startAll);
buttonPanel.add(removeVideo);
buttonPanel.add(stopAll);
JPanel taskPanel = new JPanel(new GridLayout(0,1));
JScrollPane taskScrollPane = new JScrollPane(taskPanel);
IAppWidgetFactory.makeIAppScrollPane(taskScrollPane);
for(int i=0;i<10;i++){
ColorPanel c = new ColorPanel();
c.setPreferredSize(new Dimension(750,100));
taskPanel.add(c);
}
JPanel progressBarPanel = new JPanel();
JComponent component = (JComponent) hud.getContentPane();
component.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
Insets in = new Insets(2,2,2,2);
gbc.insets = in;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 10;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
component.add(buttonPanel,gbc);
gbc.gridy += 1;
gbc.gridheight = 17;
component.add(taskScrollPane,gbc);
gbc.gridy += 17;
gbc.gridheight = 2;
component.add(progressBarPanel,gbc);
hud.getJDialog().setVisible(true);
}
}
Use this
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridbagConstraints.BOTH
Why not simply place three JPanels on top of one JPanel with BorderLayout as Layout Manager, where the middle JPanel with all custom panels with their respective sizes can be accommodated inside a JScrollPane, as shown in the below example :
import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 5/17/13
* Time: 6:09 PM
* To change this template use File | Settings | File Templates.
*/
public class PlayerBase
{
private JPanel contentPane;
private JPanel buttonPanel;
private JPanel centerPanel;
private CustomPanel[] colourPanel;
private JPanel progressPanel;
private JButton addVideoButton;
private JButton removeVideoButton;
private JButton startAllButton;
private JButton stopAllButton;
private JProgressBar progressBar;
private Random random;
public PlayerBase()
{
colourPanel = new CustomPanel[10];
random = new Random();
}
private void displayGUI()
{
JFrame playerWindow = new JFrame("Player Window");
playerWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
addVideoButton = new JButton("Add New Video");
removeVideoButton = new JButton("Remove Video");
startAllButton = new JButton("Start all tasks");
stopAllButton = new JButton("Stop all tasks");
buttonPanel.add(addVideoButton);
buttonPanel.add(removeVideoButton);
buttonPanel.add(startAllButton);
buttonPanel.add(stopAllButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
JScrollPane scroller = new JScrollPane();
centerPanel = new JPanel(new GridLayout(0, 1, 2, 2));
for (int i = 0; i < colourPanel.length; i++)
{
colourPanel[i] = new CustomPanel(new Color(
random.nextInt(255), random.nextInt(255)
, random.nextInt(255)));
centerPanel.add(colourPanel[i]);
}
scroller.setViewportView(centerPanel);
contentPane.add(scroller, BorderLayout.CENTER);
progressPanel = new JPanel(new BorderLayout(5, 5));
progressBar = new JProgressBar(SwingConstants.HORIZONTAL);
progressPanel.add(progressBar);
contentPane.add(progressPanel, BorderLayout.PAGE_END);
playerWindow.setContentPane(contentPane);
playerWindow.pack();
//playerWindow.setSize(750, 750);
playerWindow.setLocationByPlatform(true);
playerWindow.setVisible(true);
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
#Override
public void run()
{
new PlayerBase().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class CustomPanel extends JPanel
{
public CustomPanel(Color backGroundColour)
{
setOpaque(true);
setBackground(backGroundColour);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(750, 100));
}
}
OUTPUT :

Categories