How to reset Minesweeper game board in Java.Swing - java

I have been trying to get my code to reset after hitting the okay button with slider, however, I have had no such luck. Does anyone have an idea on how I can incorporate this into my code?
P.S. The reset must be in Class Field.
package GUI;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class GameDisplay extends JPanel {
private static final long serialVersionUID = 1L;
private boolean activated;
public GameDisplay(Model.Field field) {
setLayout(new GridLayout(GUI.SizeDialog.currentRows, GUI.SizeDialog.currentColumns));
for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
add(field.Cells[i][j]);
}
}
}
public boolean isActive() {
return activated;
}
public void setActive(boolean activated) {
this.activated = activated;
}
}
Field
package Model;
import java.awt.Dimension;
import java.util.ArrayList;
import GUI.SizeDialog;
public class Field {
private int difficultyFactor;
public static final int EASY = 1;
public static final int NORMAL = 2;
public static final int HARD = 3;
public Cell[][] Cells;
public Field() {
Cells = new Cell[GUI.SizeDialog.currentRows][GUI.SizeDialog.currentColumns];
for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
Cells[i][j]= new Cell();
}
}
}
public void reset(){
Cells = new Cell[GUI.SizeDialog.currentRows][GUI.SizeDialog.currentColumns];
for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
Cells[i][j]= new Cell();
}
}
}
public void setDifficultyFactor(int level) {
switch (level) {
case EASY:
difficultyFactor = EASY;
break;
case NORMAL:
difficultyFactor = NORMAL;
break;
case HARD:
difficultyFactor = HARD;
break;
default:
difficultyFactor = NORMAL;
}
}
}
SizeDialog
package GUI;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Hashtable;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import Model.Field;
public class SizeDialog extends JDialog {
private static final long serialVersionUID = 1L;
private Model.Field field;
private GUI.GameDisplay GameDisplay;
public static Integer currentRows = 4;
public static Integer currentColumns = 4;
public SizeDialog() {
JPanel dialogBoxPanel = new JPanel();
BorderLayout dialogLayout = new BorderLayout();
dialogBoxPanel.setLayout(dialogLayout);
JSlider rowCount = new JSlider(4, 10, 4);
JSlider columnCount = new JSlider(4, 10, 4);
Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
labelTable.put(new Integer(4), new JLabel("4"));
labelTable.put(new Integer(10), new JLabel("10"));
rowCount.setLabelTable(labelTable);
rowCount.setPaintLabels(true);
columnCount.setLabelTable(labelTable);
columnCount.setPaintLabels(true);
JLabel row = new JLabel();
JLabel column = new JLabel();
JPanel rowPanel = new JPanel();
JPanel columnPanel = new JPanel();
JLabel rowPosition = new JLabel();
rowPosition.setText("Rows: 4");
JLabel columnPosition = new JLabel();
columnPosition.setText("Columns: 4");
rowCount.addChangeListener(getCurrentRows(rowCount, "row", rowPosition));
columnCount.addChangeListener(getCurrentColumns(columnCount, "column", columnPosition));
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
field.reset();
SizeDialog.this.dispose();
}
});
rowPanel.add(rowPosition, BorderLayout.WEST);
rowPanel.add(row, BorderLayout.CENTER);
rowPanel.add(rowCount, BorderLayout.EAST);
columnPanel.add(columnPosition, BorderLayout.WEST);
columnPanel.add(column, BorderLayout.CENTER);
columnPanel.add(columnCount, BorderLayout.EAST);
dialogBoxPanel.add(rowPanel, BorderLayout.NORTH);
dialogBoxPanel.add(columnPanel, BorderLayout.CENTER);
dialogBoxPanel.add(okButton, BorderLayout.SOUTH);
setContentPane(dialogBoxPanel);
setMinimumSize(new Dimension(300, 150));
setLocationRelativeTo(null);
}
private ChangeListener getCurrentColumns(final JSlider columnCount, final String string, final JLabel columnPosition) {
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JSlider theSlider = (JSlider) changeEvent.getSource();
if (!theSlider.getValueIsAdjusting()) {
int sliderValue = theSlider.getValue();
columnPosition.setText("columns:" + sliderValue);
SizeDialog.currentColumns = sliderValue;
}
}
};
return changeListener;
}
private ChangeListener getCurrentRows(final JSlider rowCount, final String string, final JLabel rowPosition) {
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JSlider theSlider = (JSlider) changeEvent.getSource();
if (!theSlider.getValueIsAdjusting()) {
int sliderValue = theSlider.getValue();
rowPosition.setText("Rows:" + sliderValue);
SizeDialog.currentRows = sliderValue;
}
}
};
return changeListener;
}
}
MainFrame
package GUI;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static JPanel centerPanel;
public static final String EASY = "Easy";
public static final String NORMAL = "Normal";
public static final String HARD = "Hard";
public MainFrame(JPanel centerPanel) {
// Setup of Main
super("The True/False Game");
this.centerPanel = centerPanel;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setup();
}
private void setup() {
// Setup of centerPanel
add(centerPanel);
pack();
}
public JMenuBar setUpMenuBar(ActionListener listener) {
// create the necessary menu items and menus
JMenuBar menuBar = new JMenuBar();
JMenu settingsMenu = new JMenu("Settings");
JMenuItem size = new JMenuItem("Size");
size.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object valueBox = new SizeDialog();
((Window) valueBox).setVisible(true);
}
});
JMenu difficultyMenu = new JMenu("Difficulty Level");
ButtonGroup levelGroup = new ButtonGroup();
JCheckBoxMenuItem easyDifficultyItem = new JCheckBoxMenuItem(EASY);
JCheckBoxMenuItem normalDifficultyItem = new JCheckBoxMenuItem(NORMAL);
JCheckBoxMenuItem hardDifficultyItem = new JCheckBoxMenuItem(HARD);
easyDifficultyItem.setSelected(true); // Default difficulty setting
// this button group ensures that only one check box is selected
levelGroup.add(easyDifficultyItem);
levelGroup.add(normalDifficultyItem);
levelGroup.add(hardDifficultyItem);
difficultyMenu.add(easyDifficultyItem);
difficultyMenu.add(normalDifficultyItem);
difficultyMenu.add(hardDifficultyItem);
settingsMenu.add(size);
settingsMenu.add(difficultyMenu);
menuBar.add(settingsMenu);
// use a single listener to handle all menu item selections
for (int i = 0; i < menuBar.getMenuCount(); ++i) {
for (JMenuItem item : getMenuItems(menuBar.getMenu(i))) {
item.addActionListener(listener);
}
}
return menuBar;
}
// this recursion works because JMenu is a subclass of JMenuItem!
private static List<JMenuItem> getMenuItems(JMenuItem item) {
List<JMenuItem> items = new ArrayList<>();
if (item instanceof JMenu) {
JMenu menu = (JMenu) item;
for (int i = 0; i < menu.getItemCount(); ++i) {
items.addAll(getMenuItems(menu.getItem(i)));
}
} else {
items.add(item);
}
return items;
}
}
App
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuBar;
import Model.Cell;
import Model.Field;
import GUI.MainFrame;
import GUI.SizeDialog;
public class App {
// Main Objects
private static GUI.MainFrame MainFrame;
private static GUI.GameDisplay GameDisplay;
private static Model.Field field;
public static GUI.SizeDialog SizeDialog;
public static void main(String[] args) {
// Setup of the Main Objects
field = new Model.Field();
GameDisplay = new GUI.GameDisplay(field);
MainFrame = new MainFrame(GameDisplay);
MainFrame.setMinimumSize(new Dimension(500, 500));
MainFrame.getContentPane().add(GameDisplay);
// Setup of the Menu Bar
JMenuBar menuBar = MainFrame.setUpMenuBar(menuListener);
MainFrame.setJMenuBar(menuBar);
// Show the Mainframe in the center of the desktop screen
MainFrame.setLocationRelativeTo(null);
MainFrame.setVisible(true);
}
// listener for the menu items in MainFrame
private static ActionListener menuListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case GUI.MainFrame.EASY:
field.setDifficultyFactor(Field.EASY);
GameDisplay.setActive(true);
break;
case GUI.MainFrame.NORMAL:
field.setDifficultyFactor(Field.NORMAL);
GameDisplay.setActive(true);
break;
case GUI.MainFrame.HARD:
field.setDifficultyFactor(Field.HARD);
GameDisplay.setActive(true);
break;
}
}
};
};

An instance of your Field class is currently being created in the App class. Your private field field in the SizeDialog class is currently not being set to the instance known to the App class. A solution for this problem is to provide the Field instance as a parameter.
A possible solution is as follows:
App:
public class App {
// Main Objects
private static GUI.MainFrame MainFrame;
private static GUI.GameDisplay GameDisplay;
private static Model.Field field;
public static GUI.SizeDialog SizeDialog;
public static void main(String[] args) {
// Setup of the Main Objects
field = new Model.Field();
GameDisplay = new GUI.GameDisplay(field);
MainFrame = new MainFrame(GameDisplay, field);
/* the rest of your code */
}
/* more App code */
}
MainFrame:
public class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static JPanel centerPanel;
public static final String EASY = "Easy";
public static final String NORMAL = "Normal";
public static final String HARD = "Hard";
private Model.Field field;
public MainFrame(JPanel centerPanel, Model.Field field) {
this.field = field;
/* the rest of your code */
}
public JMenuBar setUpMenuBar(ActionListener listener) {
// create the necessary menu items and menus
JMenuBar menuBar = new JMenuBar();
JMenu settingsMenu = new JMenu("Settings");
JMenuItem size = new JMenuItem("Size");
size.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object valueBox = new SizeDialog(field);
((Window) valueBox).setVisible(true);
}
});
/* the rest of your code */
}
/* more MainFrame code */
}
SizeDialog:
public class SizeDialog extends JDialog {
private static final long serialVersionUID = 1L;
private final Model.Field field;
private GUI.GameDisplay GameDisplay;
public static Integer currentRows = 4;
public static Integer currentColumns = 4;
public SizeDialog(final Model.Field field) {
this.field = field;
/* the rest of your code */
}
/* more SizeDialog code */
}
EDIT: As mentioned in this answer, objects that are referenced in anonymous classes must be final.

Related

Click Event - Accessing a boolean variable from another class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Stuck on a problem that requires grabbing a boolean variable from another class.
I have the following for-loop, boolean and if-else statements
import java.awt.*;
import javax.swing.*;
import java.awt.Color.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.Random;
public class Checkers extends JFrame
{
Random random = new Random();
private final int ROWS = 2;
private final int COLS = 5;
private final int GAP = 2;
private final int NUM = ROWS * COLS;
private int i;
private int score;
private JPanel pane = new JPanel(new GridLayout(ROWS,COLS, GAP,GAP));
private JPanel pane2 = new JPanel();
private JPanel pane3 = new JPanel();
private JButton btn1 = new JButton("Play A Game");
private JButton btn2 = new JButton("Exit");
private JButton btn3 = new JButton("Easy");
private JButton btn4 = new JButton("Intermediate");
private JButton btn5 = new JButton("Difficult");
private JLabel lbl1 = new JLabel ("score: " + score);
private JLabel gameLost = new JLabel("You lose! You got: " + score + " points");
private JButton btnRestart = new JButton("Restart");
private MyPanel [] panel = new MyPanel[NUM];
private Color col1 = Color.RED;
private Color col2 = Color.WHITE;
private Color col3 = Color.GREEN;
private Color tempColor;
private boolean isPanelDisabled;
//Starts the checkers GUI, calling the constructor below this.
public static void main(String[] args){
new Checkers();
}
//Sets the dimensions of the GUI, visibility, background color and
//contents via the setBoard();
public Checkers()
{
super("Checkers");
setSize(600,600);
setVisible(true);
setBackground(Color.BLACK);
setBoard();
}
//Makes the grid, contains a conditional boolean, adds the panels to grid based on i value.
//sets Colours accordingly
public void setBoard()
{
boolean isPanelDisabled = false;
for (int i = 0; i < panel.length; i++) {
panel[i] = new MyPanel(this);
pane.add(panel[i]);
if (i % COLS == 0) {
tempColor = col1;
}
if (i == 9 || i <8) {
panel[i].setBackground(col1);
}
if(i == 8){
isPanelDisabled = true;
panel[i].setBackground(col3);
}
}
//pane background colour and the size of this pane.
pane.setBackground(Color.BLACK);
pane.setPreferredSize(new Dimension(300,300));
//pane background colour and size of this pane.
pane2.setBackground(Color.white);
pane2.setPreferredSize(new Dimension(300,300));
//directions on the board where these panes appear.
add(pane, BorderLayout.WEST);
add(pane2, BorderLayout.EAST);
pane2.add(lbl1);
pane2.add(btnRestart);
btnRestart.addActionListener( e -> restartBoard());
pane2.setLayout(new BoxLayout(pane2, BoxLayout.PAGE_AXIS));
}
//increments the score for the user based on current points.
public void incrementScore(){
if (score != 5){
score++;
lbl1.setText("Score: " + Integer.toString(score));
}
else if(score == 5){
lbl1.setText("Congratulations!, you've won!, your score is:" + score);
}
}
}
and this mouseClicked Event
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
public class MyPanel extends JPanel implements MouseListener, ActionListener {
private final Checkers checkers;
private boolean isPanelDisabled;
//MyPanel Constructor that initiates a instance of checkers.
public MyPanel(Checkers checkers) {
this.checkers = checkers;
addMouseListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
}
// Sets the panel colours according to their int number and the boolean condiiton.
#Override
public void mouseClicked(MouseEvent e) {
if (isPanelDisabled == true){
setBackground(Color.CYAN);
}
else{
setBackground(Color.BLACK);
checkers.incrementScore();
}
}
My Expected result of this should be that if the user clicks the 8th panel in that grid, then the color of that panel will be cyan when pressed and not black, but it cant access the boolean variable? where am i going wrong here?
Your question involves communication between objects of different classes, and there are several ways to do this, but most basic is to call a method of an object in one class to the other.
First lets set up the problem,... I've created classes called MyPanel2 and Checkers2, to distinguish them from yours.
Say in MyPanel2 we have a Checkers2 field and a boolean field called selected that is set to false:
private Checkers2 checkers;
private boolean selected = false;
along with appropriate boolean getter and setter:
public void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
And say within the Checkers2 class you have a 10 instances of MyPanel2 held within an array, and you want the user to be able to "select" instances of the class, but only allow 7 of them to be selected, and assume that you want to user the set up that you're currently using, you could give the main class, a method, public boolean isPanelDisabled(), and have the MyPanel2 class call this method to determine if selection is allowed. So within MyPanel2 you could have a MouseListener with something like:
#Override
public void mousePressed(MouseEvent e) {
if (selected) {
return;
}
// call the Checkers2 boolean method to check
if (checkers.isPanelDisabled()) {
setBackground(DISABLED_COLOR);
} else {
setBackground(SELECTED_COLOR);
setSelected(true);
}
}
Within Checkers2 .isPanelDisabled() method you'd iterate through the array of MyPanel2 instances to see how many have been selected, something like this could work:
public boolean isPanelDisabled() {
int count = 0;
for (MyPanel2 panel2 : myPanels) {
if (panel2.isSelected()) {
count++;
}
}
return count >= MAX_COUNT;
}
The whole MCVE testable code could look like:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Checkers2 extends JFrame {
private static final int MAX_COUNT = 7;
private final int ROWS = 2;
private final int COLS = 5;
private final int GAP = 2;
private final int NUM = ROWS * COLS;
private MyPanel2[] myPanels = new MyPanel2[NUM];
public Checkers2() {
super("Checkers");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel gridPanel = new JPanel(new GridLayout(ROWS, COLS, 1, 1));
gridPanel.setBackground(Color.BLACK);
gridPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for (int i = 0; i < myPanels.length; i++) {
MyPanel2 myPanel = new MyPanel2(this);
gridPanel.add(myPanel);
myPanels[i] = myPanel;
}
JButton resetButton = new JButton("Reset");
resetButton.setMnemonic(KeyEvent.VK_R);
resetButton.addActionListener(evt -> {
for (MyPanel2 myPanel2 : myPanels) {
myPanel2.reset();
}
});
JButton exitButton = new JButton("Exit");
exitButton.setMnemonic(KeyEvent.VK_X);
exitButton.addActionListener(evt -> System.exit(0));
JPanel buttonPanel = new JPanel();
buttonPanel.add(resetButton);
add(gridPanel);
add(buttonPanel, BorderLayout.PAGE_END);
pack();
setLocationRelativeTo(null);
}
public boolean isPanelDisabled() {
int count = 0;
for (MyPanel2 panel2 : myPanels) {
if (panel2.isSelected()) {
count++;
}
}
return count >= MAX_COUNT;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Checkers2().setVisible(true);
});
}
}
class MyPanel2 extends JPanel {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
private static final int GR = 240;
public static final Color BASE_COLOR = new Color(GR, GR, GR);
public static final Color DISABLED_COLOR = Color.CYAN;
public static final Color SELECTED_COLOR = Color.BLACK;
private Checkers2 checkers;
private boolean selected = false;
public MyPanel2(Checkers2 checkers) {
setBackground(BASE_COLOR);
this.checkers = checkers;
setPreferredSize(new Dimension(PREF_W, PREF_H));
addMouseListener(new MyMouse());
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
public void reset() {
setBackground(BASE_COLOR);
setSelected(false);
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (selected) {
return;
}
if (checkers.isPanelDisabled()) {
setBackground(DISABLED_COLOR);
} else {
setBackground(SELECTED_COLOR);
setSelected(true);
}
}
}
}
Another Option is to take all the logic out of MyPanel and put it into the main program, something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class Checkers3 extends JPanel {
private static final int MAX_COUNT = 7;
private final int ROWS = 2;
private final int COLS = 5;
private final int GAP = 2;
private final int NUM = ROWS * COLS;
private MyPanel3[] myPanels = new MyPanel3[NUM];
public Checkers3() {
JPanel gridPanel = new JPanel(new GridLayout(ROWS, COLS, 1, 1));
gridPanel.setBackground(Color.BLACK);
gridPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
MyMouse myMouse = new MyMouse();
for (int i = 0; i < myPanels.length; i++) {
MyPanel3 myPanel = new MyPanel3();
myPanel.addMouseListener(myMouse);
gridPanel.add(myPanel);
myPanels[i] = myPanel;
}
JButton resetButton = new JButton("Reset");
resetButton.setMnemonic(KeyEvent.VK_R);
resetButton.addActionListener(evt -> {
for (MyPanel3 myPanel : myPanels) {
myPanel.reset();
}
});
JButton exitButton = new JButton("Exit");
exitButton.setMnemonic(KeyEvent.VK_X);
exitButton.addActionListener(evt -> System.exit(0));
JPanel buttonPanel = new JPanel();
buttonPanel.add(resetButton);
setLayout(new BorderLayout());
add(gridPanel);
add(buttonPanel, BorderLayout.PAGE_END);
}
public boolean isPanelDisabled() {
int count = 0;
for (MyPanel3 panel : myPanels) {
if (panel.isSelected()) {
count++;
}
}
return count >= MAX_COUNT;
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
MyPanel3 myPanel = (MyPanel3) e.getSource();
if (myPanel.isSelected()) {
return; // it's already selected
} else if (isPanelDisabled()) {
myPanel.setSelected(false);
} else {
myPanel.setSelected(true);
}
}
}
private static void createAndShowGui() {
Checkers3 mainPanel = new Checkers3();
JFrame frame = new JFrame("Checkers");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class MyPanel3 extends JPanel {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
private static final int GR = 240;
public static final Color BASE_COLOR = new Color(GR, GR, GR);
public static final Color DISABLED_COLOR = Color.CYAN;
public static final Color SELECTED_COLOR = Color.BLACK;
private boolean selected = false;
public MyPanel3() {
setBackground(BASE_COLOR);
setPreferredSize(new Dimension(PREF_W, PREF_H));
}
public void setSelected(boolean selected) {
this.selected = selected;
Color background = selected ? SELECTED_COLOR : DISABLED_COLOR;
setBackground(background);
}
public boolean isSelected() {
return selected;
}
public void reset() {
setSelected(false);
setBackground(BASE_COLOR);
}
}
But the BEST option is to put all logic within a separate model class (or classes) and make the GUI's as dumb as possible.

Remove Specific Component from JPanel - Java

I currently have multiples of a JPanel (ItemPanel) within a JPanel (FlipPanel) within my JFrame. An ItemPanel is added to FlipPanel when a JButton in a separate panel (FlipFormPanel) is pressed. I have a JButton on ItemPanel labelled "Cancel" and I would like to remove the specific ItemPanel whose Cancel JButton was pressed. What I currently have only removes the ItemPanel whose button was selected, but after that no other buttons will remove any more ItemPanels.
How can I fix my code to do what I'm trying to accomplish?
My code for each class is below. I tried to remove as much of the extraneous material as possible to avoid cluttering the task at hand. I believe the issue is located in FlipPanel under the methods addItemPanel(, setItemListener(, and in the ItemPanelListener and ItemPanelEvent classes. Thanks for any help provided.
FlipPanel:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
public class FlipPanel extends JPanel {
private JPanel mainPanel;
private JScrollPane scrollPane;
private ItemPanel itemPanel;
private JPanel titlePanel;
private JLabel titleLabel;
private List<ItemPanel> itmPnls = new ArrayList<ItemPanel>();
private int count;
public FlipPanel() {
setLayout(new BorderLayout());
mainPanel = new JPanel();
scrollPane = new JScrollPane(mainPanel);
add(scrollPane, BorderLayout.CENTER);
mainPanel.setLayout(new MigLayout("align center, fillx", "fill", ""));
titlePanel = new JPanel();
mainPanel.add(titlePanel, "wrap, gapbottom 13, gaptop 7");
titlePanel.setLayout(new GridBagLayout());
titleLabel = new JLabel("CURRENT FLIPS");
Font labelFont = titleLabel.getFont();
titleLabel.setFont(new Font(labelFont.getName(), Font.BOLD, 25));
titlePanel.setBorder(BorderFactory.createMatteBorder(0, 0, 3, 0, Color.BLACK));
titlePanel.add(titleLabel);
count = 0;
}
public void addItemPanel(String item, String buyPrice, String sellPrice,
String quantity, String pcBuyPrice, String pcSellPrice) {
this.itemPanel = new ItemPanel(count, item, buyPrice, sellPrice, quantity,
pcBuyPrice, pcSellPrice);
mainPanel.add(itemPanel, "wrap");
itmPnls.add(itemPanel);
count++;
setItemListener(this.itemPanel);
}
public void setItemListener(ItemPanel iP) {
iP.setItemPanelListener(new ItemPanelListener() {
public void itemPanelEventOccurred(ItemPanelEvent e) {;
System.out.println("Remove");
System.out.println("Current Position: " + e.getPosition());
mainPanel.remove(itmPnls.get(e.getPosition()));
System.out.println("Positions:");
for (int i = 0; i < count; i++) {
System.out.println(itmPnls.get(i).getPosition());
}
if(e.getPosition() < count - 1) {
for (int i = e.getPosition() + 1; i < count; i++) {
itmPnls.get(i).setPosition(i);
}
}
count--;
revalidate();
repaint();
System.out.println("Positions:");
for (int i = 0; i < count; i++) {
System.out.println(itmPnls.get(i).getPosition());
}
setItemListener(itmPnls.get(0));
}
});
}
ItemPanel:
import javax.swing.JPanel;
public class ItemPanel extends JPanel {
private int position;
private String item;
private String buyPrice;
private String sellPrice;
private String quantity;
private String pcBuyPrice;
private String pcSellPrice;
private JButton logBtn;
private JButton editBtn;
private JButton cancelBtn;
private ItemPanelListener itemPanelListener;
public ItemPanel(int position, String item, String buyPrice, String sellPrice,
String quantity, String pcBuyPrice, String pcSellPrice) {
this.position = position;
this.item = item;
this.buyPrice = buyPrice;
this.sellPrice = sellPrice;
this.quantity = quantity;
this.pcBuyPrice = pcBuyPrice;
this.pcSellPrice = pcSellPrice;
Dimension dim = getPreferredSize();
dim.height = 100;
setPreferredSize(dim);
setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
logBtn = new JButton("Log Item");
editBtn = new JButton("Edit Item");
cancelBtn = new JButton("Cancel Item");
setupLabels();
setupCancelItemButton();
layoutComponents();
}
public int getPosition() {
return position;
}
public void setPosition(int pos) {
position = pos;
}
public void setupCancelItemButton() {
cancelBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ItemPanelEvent ev = new ItemPanelEvent(this);
if (itemPanelListener != null) {
itemPanelListener.itemPanelEventOccurred(ev);
}
}
});
}
public void setItemPanelListener(ItemPanelListener listener) {
this.itemPanelListener = listener;
}
ItemPanelListener:
import java.util.EventListener;
public interface ItemPanelListener extends EventListener {
public void itemPanelEventOccurred(ItemPanelEvent e);
}
ItemPanelEvent:
import java.util.EventObject;
public class ItemPanelEvent extends EventObject {
private int position;
public ItemPanelEvent(Object source) {
super(source);
}
public ItemPanelEvent(Object source, int position) {
super(source);
this.position = position;
}
public int getPosition() {
return position;
}
}

jbutton does not work

Hi I have the following code where I have a start and stop button . when start is pressed canvas starts painting but I cannot press stop button until the start operation is done . I need to stop and resume the paint on the button press . Once the start button is pressed the other buttons cannot be pressed till the canvas is painted.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Hashtable;
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.JTextField;
import javax.swing.Timer;
public abstract class JUIApp extends JPanel implements ActionListener {
public static CACanvas cacanvas= null;
public ArrayList<int[]> genL;
public JFrame frame = null;
protected JPanel mainPanel = null;
private JButton btn0 = null;
private JButton btn1 = null;
private JButton btn2 = null;
#SuppressWarnings("rawtypes")
DefaultComboBoxModel rules = null;
#SuppressWarnings("rawtypes")
JComboBox rulesCombo =null;
JScrollPane ruleListScrollPane=null;
JLabel lable=null;
JTextField generation=null;
JLabel gLable=null;
public static String Rule;
public static String Generations;
public boolean isChanged =false;
public int gridCellSize=4;
private static final long serialVersionUID = 1L;
public int genCurrent=0;
public int posCurrent=0;
public int i;
public Color cellColor= null;
public Timer waitTimer;
public static boolean waitFlag;
public static boolean alert1Flag=false;
public boolean stopFlag=false;
public JLabel Alert1=new JLabel();
public int genCheck=0;
//private List<Point> fillCells;
public JUIApp() {
initGUI();
}
public void initGUI() {
//fillCells = new ArrayList<>(25);
frame = new JFrame();
frame.setTitle("Cellular Automata Demo");
frame.setSize(1050, 610);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(getMainPanel(),BorderLayout.NORTH);
frame.setVisible(true);
Toolkit.getDefaultToolkit().setDynamicLayout(false);
cacanvas=new CACanvas();
frame.add(cacanvas);
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public JPanel getMainPanel() {
mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout());
//cacanvas=new CACanvas();
btn0 = new JButton("Start");
btn0.addActionListener(this);
//waitTimer = new Timer(1000, this);
mainPanel.add(btn0);
JButton btn2 = new JButton("Stop");
btn2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent s)
{
stopFlag=true;
//cacanvas.repaint();
}
});
mainPanel.add(btn2);
btn1 = new JButton("Clear");
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
CACanvas.clearFlag=true;
generation.setText("");
alert1Flag=true;
rulesCombo.setSelectedIndex(0);
Alert1.setText("Please enter the number of generations");
Alert1.setBounds(30, 20, 5, 5);
Alert1.setVisible(alert1Flag);
mainPanel.add(Alert1);
cacanvas.repaint();
frame.setSize(1060, 610);
}
});
mainPanel.add(btn1);
lable=new JLabel();
lable.setText("Select Rule :");
mainPanel.add(lable);
rules=new DefaultComboBoxModel();
for (int i=0;i<=100;i++)
{
String p=String.valueOf(i);
rules.addElement(p);
}
rules.addElement("250");
rules.addElement("254");
rulesCombo = new JComboBox(rules);
rulesCombo.setSelectedIndex(0);
ruleListScrollPane = new JScrollPane(rulesCombo);
mainPanel.add(ruleListScrollPane);
//mainPanel.revalidate();
gLable=new JLabel();
gLable.setText("Enter the number of Generations (Max 64)");
generation=new JTextField(2);
mainPanel.add(gLable);
mainPanel.add(generation);
// mainPanel.add(cacanvas);
return mainPanel;
}
public abstract void run();
#Override
public void actionPerformed(ActionEvent arg0) {
Alert1.setVisible(false);
waitFlag=false;
System.out.println("We received an ActionEvent " + arg0);
Generations=generation.getText();
System.out.println(Generations);
Rule = "";
if (rulesCombo.getSelectedIndex() != -1) {
Rule =
(String) rulesCombo.getItemAt
(rulesCombo.getSelectedIndex());
}
System.out.println(Rule);
int rule=Integer.parseInt(Rule);
Hashtable<String,Integer> rules= new Hashtable<String,Integer>();
CARule ruleClass=new CARule();
rules=ruleClass.setRule(rule);
CAGenetationSet sa =new CAGenetationSet(100, false,rules);
genL=new ArrayList<int[]>();
genL=sa.runSteps(Integer.parseInt(Generations));
System.out.println("calling pattern set");
for(int i=0;i<=genL.size()-1;i++)
{
System.out.println("Painting generation :"+i);
if(stopFlag==false)
{
cacanvas.repaint();
}
//genPaint();
//sleep();
int[] newCell=genL.get(i);
for(int r=0;r<newCell.length;r++)
{
if(newCell[r]==1)
{
System.out.println("Generaton is"+i+"CellLife is"+r);
cacanvas.fillCell(i,r);
}
}
}
/*cacanvas.patternSet(genL);
waitFlag=true;
System.out.println("run completed");
// cacanvas.clearFlag=true;
*/
}
public void genPaint()
{
cacanvas.repaint();
}
public void sleep()
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
JUIApp app = new JUIApp() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Run method");
}
};
}
}
Seems like you are using the current Thread on that task, you should create another Thread and add one listeners code to the new Thread.

I get a stack overflow error

I'm trying to create a program where you press start and a new JFrame comes up with 3 buttons , you have to switch the button after you click on it using a random , I'm fairly new to java so I don't know what to do. Thank you
package code;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
public class StartListener implements java.awt.event.ActionListener {
private int counter;
private Game Ga;
private JFrame z;
private int x;
public StartListener(Game a, int co){
Ga=a;
counter = co;
}
public void actionPerformed(ActionEvent e) {
Timer time = new Timer(10000,new Time(Ga));
time.start();
z = new JFrame("Sequence game");
FlowLayout fl = new FlowLayout(0, 50, 40);
z.getContentPane().setLayout(fl);
z.setVisible(true);
JButton a = new JButton("A");
Font f = a.getFont();
Font myFont = f.deriveFont(Font.BOLD, f.getSize()*4);
a.setSize(200,100);
a.setVisible(true);
JButton b = new JButton("B");
b.setVisible(true);
b.setSize(200,100);
JButton c = new JButton("C");
c.setVisible(true);
c.setSize(200,100);
z.getContentPane().add(a);
z.getContentPane().add(b);
z.getContentPane().add(c);
z.pack();
Random r = new Random();
x=r.nextInt(3);
figure(a,b,c,x,myFont,f);}
public void figure(JButton a,JButton b, JButton c, int x, Font myFont,Font f){
if(x==0){
a.setEnabled(true);
b.setEnabled(false);
c.setEnabled(false);
a.setFont(myFont);
b.setFont(f);
c.setFont(f);
x =buttonA(a);
figure(a,b,c,x,myFont,f);
;}
else if(x==1){
a.setEnabled(false);
b.setEnabled(true);
c.setEnabled(false);
a.setFont(f);
c.setFont(f);
b.setFont(myFont);
x = buttonB(b);
figure(a,b,c,x,myFont,f);
}
else if(x==2){
a.setEnabled(false);
b.setEnabled(false);
c.setEnabled(true);
a.setFont(f);
b.setFont(f);
c.setFont(myFont);
x = buttonC(c);
figure(a,b,c,x,myFont,f);
}
}
public int buttonA(JButton a){
Random r = new Random();
int rand = 0;
a.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
public int buttonB(JButton b){
Random r = new Random();
int rand = 0;
b.addActionListener(new Something(Ga));
rand=r.nextInt(3);
return rand;
}
public int buttonC(JButton c){
Random r = new Random();
int rand=0;
c.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
}
And here's the code for Something
package code;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Something implements ActionListener {
private Game G;
public Something(Game a){
G = a;
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
G.increment();
}
}
Here's the error :
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.awt.Component.enable(Unknown Source)
at java.awt.Component.setEnabled(Unknown Source)
at javax.swing.JComponent.setEnabled(Unknown Source)
at javax.swing.AbstractButton.setEnabled(Unknown Source)
Your figure method continuously calls itself recursively forever, or until stack space runs out. Solution: get rid of those recursive calls. Also you really don't want to keep adding multiple ActionListeners on to JButtons, all this suggesting that you will want to refactor and perhaps redesign the entire program.
You will want to change the state of a field in the class, and use that field's state to decide what to do within the ActionListener.
For example:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwapButtons extends JPanel {
private static final Font ACTIVE_FONT = new Font(Font.DIALOG, Font.BOLD, 15);
private static final String[] BTN_TEXT = { "Monday", "Tuesday", "Wednesday" };
private static final int EXTRA_WIDTH = 50;
private List<AbstractButton> buttonList = new ArrayList<>();
private int buttonIndex = 0;
public SwapButtons() {
setLayout(new GridLayout(1, 0, 5, 0));
BtnListener btnListener = new BtnListener();
for (int i = 0; i < BTN_TEXT.length; i++) {
JButton button = new JButton(BTN_TEXT[i]);
button.addActionListener(btnListener);
buttonList.add(button); // add to ArrayList
add(button); // add to GUI
}
setActiveButton();
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
// give preferred size extra width so gui can handle larger fonts
int prefW = superSz.width + EXTRA_WIDTH;
int prefH = superSz.height;
return new Dimension(prefW, prefH);
}
private void setActiveButton() {
// iterate through buttonList, turning on the "active" button
// as determined by the buttonIndex variable
for (int i = 0; i < buttonList.size(); i++) {
if (i == buttonIndex) {
buttonList.get(i).setFont(ACTIVE_FONT);
buttonList.get(i).setEnabled(true);
} else {
buttonList.get(i).setFont(null);
buttonList.get(i).setEnabled(false);
}
}
}
private class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// show which button pressed
System.out.println("Button Pressed: " + e.getActionCommand());
// advance button index so that next button can be activated
buttonIndex++;
// but change index to 0 if buttonList size is reached
buttonIndex %= buttonList.size();
// activate the next button:
setActiveButton();
}
}
private static void createAndShowGui() {
SwapButtons mainPanel = new SwapButtons();
JFrame frame = new JFrame("Swap Buttons");
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(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

combo getSelectedItem but then

Simple question for you , i input this code and i see the combobox and the label, but after the selection of the combo the label should be with an image. This does not happen ... Surely i forgot something
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ChooseFrame extends JFrame
{
public ChooseFrame()
{
labelLeagueImage = new JLabel("Liga");
comboLeague = createComboLeague();
class ChooseListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String league = (String)comboLeague.getSelectedItem();
if (league.equals("Italia - Serie A"))
{
ImageIcon icon = new ImageIcon("Italia - Serie A.png");
labelLeagueImage.setIcon(icon);
}
}
}
listener = new ChooseListener();
leaguePanel = new JPanel();
leaguePanel.add(comboLeague);
leaguePanel.add(labelLeagueImage);
add(leaguePanel);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
}
public JComboBox createComboLeague()
{
JComboBox combo = new JComboBox();
combo.addItem("Select a league");
combo.addItem("Italia - Serie A");
combo.addItem("Italia - Serie B");
combo.addActionListener(listener);
return combo;
}
private JPanel leaguePanel;
private JComboBox comboLeague;
private JLabel labelLeagueImage;
private ActionListener listener;
private static final int FRAME_WIDTH = 300;
private static final int FRAME_HEIGHT = 600;
}
At the time you create the combo box and assign the listener, in createComboLeague(), the listener is still null. It's initialized only after the createComboLeague() method has been called.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ChooseFrame extends JFrame
{
private JPanel leaguePanel;
private JComboBox comboLeague;
private JLabel labelLeagueImage;
private ActionListener listener;
private static final int FRAME_WIDTH = 300;
private static final int FRAME_HEIGHT = 600;
public ChooseFrame()
{
labelLeagueImage = new JLabel("Liga");
comboLeague = createComboLeague();
// listener = new ChooseListener();
leaguePanel = new JPanel();
leaguePanel.add(comboLeague);
leaguePanel.add(labelLeagueImage);
add(leaguePanel);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
}
public JComboBox createComboLeague()
{
JComboBox combo = new JComboBox();
combo.addItem("Select a league");
combo.addItem("Italia - Serie A");
combo.addItem("Italia - Serie B");
combo.addActionListener(listener);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
String league = (String)comboLeague.getSelectedItem();
if (league.equals("Italia - Serie A"))
{
ImageIcon icon = new ImageIcon("Italia - Serie A.png");
labelLeagueImage.setIcon(icon);
}
}
});
return combo;
}
public static void main(String[] args) {
ChooseFrame cs=new ChooseFrame();
cs.setVisible(true);
}
}

Categories