Reset Game Of Life Gui - java

I am making Conway's Game of Life using Java Swing. I am using a 2D arrays of buttons to paint the cells. The problem I have right now is that I implemented a button which will clear the pattern or patterns drew manually o randomly and also while the timer is running. I want to clear or restart the 2D array of buttons but when I try to draw it doesn't work.
Here I have the Action Listeners for each button
//Starts the timer
Starter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
cells = new JButton[size][size];
}
});
//Stops the timer
Stop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
//Clears de buttons which are painted
clear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(Univers[i][j]){
cells[i][j].setBackground(Color.BLACK);
}
}
}
Arrays.fill(cells, null);
}
});
All the code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class GameOfLife extends JFrame{
int size=15;
int time=0;
boolean Univers[][];
JButton cells[][];
//int countentry=0;
//List<boolean[][]> Record;
JComboBox combobox;
public GameOfLife() {
//Record = new ArrayList<>();
setPreferredSize(new Dimension(600, 600));
pack();
setLayout(null);
/*combobox= new JComboBox();
combobox.addItem("Records");
combobox.addItem(time+"s");
*/
Random rnd=new Random();
Univers=new boolean[size][size];
cells=new JButton[size][size];
JPanel UniversPanel=new JPanel();
UniversPanel.setBounds(0,0,500,500);
UniversPanel.setLayout(new GridLayout(size,size));
////////////////////////////////////////////////////////////
//manual cell adding
MouseListener mouseListener = new MouseListener(){
#Override
public void mouseClicked(MouseEvent e) { }
#Override
public void mouseReleased(MouseEvent e) { }
#Override
public void mousePressed(MouseEvent e) { }
#Override
public void mouseExited(MouseEvent e) { }
#Override
public void mouseEntered(MouseEvent e) {
JButton ch = (JButton) e.getSource();
//System.out.println(ch.getLocation(getLocation()));
int sizegrid = UniversPanel.getSize(getSize()).width / size;
int i = (ch.getLocation(getLocation()).x) / sizegrid;
int z = (ch.getLocation(getLocation()).y) / sizegrid;
//System.out.println("x= "+i);
//System.out.println("y= "+z);
if (!Univers[z][i] && SwingUtilities.isLeftMouseButton(e)) {
Univers[z][i] = true;
cells[z][i].setBackground(Color.GREEN);
}
if(Univers[z][i] && SwingUtilities.isRightMouseButton(e)) {
Univers[z][i]=false;
cells[z][i].setBackground(Color.BLACK);
}
}
};
///////////////////////////////////////////////////////////////////
for(int x=0;x<size;x++) {
for(int y=0;y<size;y++) {
/*if((x==0 && y==1 )|| (x==1 && y==1) || (x==2 && y==1)) {
Univers[x][y]=true;
}else {
Univers[x][y]=false;
}*/
Univers[x][y]=false;
//Univers[x][y]=rnd.nextInt(100)<20;
JButton btn=new JButton();
if(Univers[x][y]) {
btn.setBackground(Color.GREEN);
}else {
btn.setBackground(Color.BLACK);
}
UniversPanel.add(btn);
cells[x][y]=btn;
}
}
//Record.add(Univers);
//countentry+=1;
//System.out.print(Record.size());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int delay=100;//milliseconds
//int Timeup=5000/delay;
Timer timer=new Timer(delay,new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean[][] tempUnivers=new boolean[size][size];
//countentry+=1;
for(int x=0;x<size;x++) {
for(int y=0;y<size;y++) {
int count=Neigbours(x,y);
if(Univers[x][y]) {
if(count<2) {
tempUnivers[x][y]=false;
}
if(count==3 ||count==2) {
tempUnivers[x][y]=true;
}
if(count>3) {
tempUnivers[x][y]=false;
}
}else{
if(count==3)
tempUnivers[x][y]=true;
}
}
}
Univers=tempUnivers;
//Record.add(Univers);
//System.out.print(Record.size());
for(int x=0;x<size;x++) {
for(int y=0;y<size;y++) {
if(Univers[x][y]) {
cells[x][y].setBackground(Color.GREEN);
}else {
cells[x][y].setBackground(Color.BLACK);
}
}
}
/* if(countentry==Timeup) {
time+=5;
combobox.addItem(time+"s");
countentry=0;
}
*/
}
});
for(int x=0;x<size;x++) {
for(int y=0;y<size;y++) {
cells[x][y].addMouseListener(mouseListener);
}
}
//Slider
/*JPanel PanelSlider =new JPanel();
PanelSlider.setLayout(new GridLayout(0,2));
PanelSlider.setBounds(0,510,300,50);
JSlider slider = new JSlider(0,5,0);
slider.setPaintTrack(true);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMajorTickSpacing(1);
slider.setMinorTickSpacing(1/10);
slider.setBounds(51, 88, 277, 52);
PanelSlider.add(combobox);
PanelSlider.add(slider);
*/
//Buttons
JPanel PanelButton =new JPanel();
PanelButton.setLayout(new GridLayout(0,3));
PanelButton.setBounds(0,510,200,50);
JButton Starter=new JButton("Start");
PanelButton.add(Starter);
JButton Stop=new JButton("Stop");
PanelButton.add(Stop);
JButton clear = new JButton("Clear");
PanelButton.add(clear);
//Starts the timer
Starter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
cells = new JButton[size][size];
}
});
//Stops the timer
Stop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
//Clears de buttons which are painted
clear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(Univers[i][j]){
cells[i][j].setBackground(Color.BLACK);
}
}
}
Arrays.fill(cells, null);
}
});
//add(PanelSlider);
add(UniversPanel);
add(PanelButton);
setLocationRelativeTo(null);
setVisible(true);
}
int Neigbours(int i, int z) {
int count=0;
for(int x=i-1;x<=i+1;x++) {
for(int y=z-1;y<=z+1;y++) {
try {
if(Univers[x][y]) {
count++;
}
}catch(Exception e){
//System.out.println(e);
}
}
}
if(Univers[i][z])
count--;
return count;
}
public static void main(String[] args) {
new GameOfLife();
}
//Slider info https://docs.oracle.com/javase/tutorial/uiswing/components/slider.html
//Manual insert void ActionPerformed(ActionEvent ae){add jbutton ch = (Jbutton) ae.getSource();}
}

Please read the comment within the code to follow the changes made in the code and the recommendations:
import java.awt.*;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
public class GameOfLife extends JFrame{
//declare constants
private final int BOARD_SIZE=15,
ANIMATION_DELAY=100;//milliseconds;
private final Cell cells[][];
public GameOfLife() {
//setPreferredSize(new Dimension(600, 600)); let layout manager work out the size derived from children
//setLayout(null); avoid using null layouts and seting bounds manually
cells=new Cell[BOARD_SIZE][BOARD_SIZE];
JPanel universPanel=new JPanel();
//universPanel.setBounds(0,0,500,500); let the layout manager set bounds
universPanel.setLayout(new GridLayout(BOARD_SIZE,BOARD_SIZE));
//initialize all cells
for(int x=0;x<BOARD_SIZE;x++) {
for(int y=0;y<BOARD_SIZE;y++) {
Cell cell=new Cell();
universPanel.add(cell);
cells[x][y]=cell;
}
}
//move the animation code to a method for better readability
Timer timer=new Timer(ANIMATION_DELAY,e -> animate());
//Buttons
JPanel panelButton =new JPanel();
panelButton.setLayout(new GridLayout(0,3));
//panelButton.setBounds(0,510,200,50); let the layout manager set bounds
JButton starter=new JButton("Start");
panelButton.add(starter);
JButton stop=new JButton("Stop");
panelButton.add(stop);
JButton clear = new JButton("Clear");
panelButton.add(clear);
//Starts the timer
starter.addActionListener(e -> timer.start());
//Stops the timer
stop.addActionListener(e -> timer.stop());
//Resets all cells
clear.addActionListener(e -> {
for(int i = 0; i < BOARD_SIZE; i++){
for(int j = 0; j < BOARD_SIZE; j++){
cells[i][j].setUniverse(false);
}
}
//Arrays.fill(cells, null); no need to set to null.
});
//add(PanelSlider);
//add to appropriate BorderLayout positions
add(universPanel, BorderLayout.CENTER);
add(panelButton, BorderLayout.SOUTH);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack(); //pack after you added all components
setVisible(true);
}
private void animate(){
for(int x1=0;x1<BOARD_SIZE;x1++) {
for(int y1=0;y1<BOARD_SIZE;y1++) {
int count=numberOfNeigboursAround(x1,y1);
if(cells[x1][y1].isUniverse()) {
if(count<2) {
cells[x1][y1].setUniverse(false);
}else if//process next if only if previous one was false
(count==3 ||count==2) {
cells[x1][y1].setUniverse(true);
}else if(count>3) {
cells[x1][y1].setUniverse(false);
}
}else if(count==3) {
cells[x1][y1].setUniverse(true);
}
}
}
}
private int numberOfNeigboursAround(int x, int y) {
int count=0;
for(int xIndex=x-1;xIndex<=x+1;xIndex++) {
for(int yIndex=y-1;yIndex<=y+1;yIndex++) {
//make sure index is valid
if(xIndex >= BOARD_SIZE || xIndex < 0 || yIndex >= BOARD_SIZE || yIndex < 0) {
continue;
}
//don't process center cell
if(xIndex == x&&yIndex ==y) {
continue;
}
if(cells[xIndex][yIndex].isUniverse()) {
count++;
}
}
}
return count;
}
public static void main(String[] args) {
new GameOfLife();
}
}
//Introduce a Cell class with the needed properties. Since button functionality i snot
//use a JLabel can be used to represent a cell
class Cell extends JLabel{
private static Color BOARD = Color.BLACK, UNIVERSE = Color.GREEN, BORDER = Color.GRAY;
private static Dimension CELL_SIZE = new Dimension(30,30);
private boolean universe;
public Cell() {
super();
universe = false;
setOpaque(true);
setBorder(BorderFactory.createLineBorder(BORDER, 2));
setBackground(BOARD);
//add mouse listener. use MouseInputAdapter to implement only needed methods
addMouseListener( new MouseInputAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
mouseClicksHandler(e);
}
});
}
public boolean isUniverse() {
return universe;
}
public void setUniverse(boolean isUniverse) {
if (universe == isUniverse) return; //no change
universe = isUniverse;
setBackground(isUniverse ? UNIVERSE : BOARD);
repaint();
}
private void mouseClicksHandler(MouseEvent e){
if (SwingUtilities.isLeftMouseButton(e)) {
setUniverse(true);
}else //if first if is true no need to evaluate the second if
if( SwingUtilities.isRightMouseButton(e)) {
setUniverse(false);
}
}
//preferred size used by layout managers
#Override
public Dimension getPreferredSize() {
return CELL_SIZE;
}
}

Related

How to access a JButton from another class

I have two classes 'UserInterface' and a 'GameEngine' I have declared a JButton component in the UserInterface and I am trying to use one of the variables i.e use the variable 'button1' from 'UserInterface' in the 'horizontalWin' method from the class 'GameEngine'.
I got this error instead "cannot find symbol - variable button1"
Userinterface:
public class UserInterface implements ActionListener
{
private GameEngine game;
private JFrame frame;
JButton button1 = new JButton("");
JButton button2 = new JButton("");
JButton button3 = new JButton("");
JButton button4 = new JButton("");
JButton button5 = new JButton("");
JButton button6 = new JButton("");
JButton button7 = new JButton("");
JButton button8 = new JButton("");
JButton button9 = new JButton("");
/**
* Create a user interface.
* #param engine The game's engine.
*/
public UserInterface(GameEngine engine)
{
game = engine;
makeFrame();
}
//some methods
}
GameEngine:
public class GameEngine {
private String buttonName;
boolean winner = false;
byte count;
public GameEngine()
{
count = 0;
}
public void horizontalWin()
{
if(button1.getText()==button2.getText() && button2.getText()==button3.getText() && button1.getText()!="" )
{
winner=true;
playAgain(buttonName);
}
// Horizontal win row 2
else if(button4.getText()==button5.getText() && button5.getText()==button6.getText() && button4.getText()!="" )
{
winner=true;
playAgain(buttonName);
}
// horizontal win row 3
else if(button7.getText()==button8.getText() && button8.getText()==button9.getText() && button7.getText()!="")
{
winner=true;
playAgain(buttonName);
}
}
I think that you don't really want to do this, that you don't want your game engine trying to obtain variables from the view. Rather why not have your view notify the engine or "model" (usually through something called a "control", when a button has been pressed. The engine then can keep track of what has been pressed and change its state accordingly. The View can then change in response to changes in the engine's state.
For example:
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class TicTacToe {
private static void createAndShowGui() {
View mainPanel = new View();
JFrame frame = new JFrame("TicTacToe");
frame.setDefaultCloseOperation(JFrame.EXIT_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();
}
});
}
}
#SuppressWarnings("serial")
class View extends JPanel {
private static final int GAP = 2;
private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 42);
private JButton[][] gameGrid = new JButton[Engine.ROWS][Engine.ROWS];
private Engine engine = new Engine();
public View() {
engine.addPropertyChangeListener(Engine.GAME_OVER, new GameOverListener());
JPanel gameGridPanel = new JPanel(new GridLayout(Engine.ROWS, Engine.ROWS, GAP, GAP));
for (int i = 0; i < gameGrid.length; i++) {
for (int j = 0; j < gameGrid[i].length; j++) {
gameGrid[i][j] = createGameGridButton(i, j);
gameGridPanel.add(gameGrid[i][j]);
}
}
JButton resetBtn = new JButton(new ResetAction("Reset", KeyEvent.VK_R));
JPanel northPanel = new JPanel();
northPanel.add(resetBtn);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(gameGridPanel, BorderLayout.CENTER);
add(northPanel, BorderLayout.NORTH);
}
private JButton createGameGridButton(int i, int j) {
JButton button = new JButton();
button.setName(String.format("%d,%d", i, j));
button.setText(XO.BLANK.getText());
button.setFont(BTN_FONT);
button.addActionListener(new GridButtonListener(i, j));
return button;
}
private class GridButtonListener implements ActionListener {
private int i;
private int j;
public GridButtonListener(int i, int j) {
this.i = i;
this.j = j;
}
#Override
public void actionPerformed(ActionEvent e) {
if (engine.isGameOver()) {
return;
}
AbstractButton source = (AbstractButton) e.getSource();
String text = source.getText();
if (text.trim().isEmpty()) {
source.setText(engine.getTurn().getText());
engine.setXO(i, j);
}
}
}
private class ResetAction extends AbstractAction {
public ResetAction(String text, int mnemonic) {
super(text);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
engine.reset();
for (JButton[] row : gameGrid) {
for (JButton button : row) {
button.setText(XO.BLANK.getText());
}
}
};
}
private class GameOverListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == Boolean.TRUE) {
JOptionPane.showMessageDialog(View.this, engine.getTurn()
.getText() + " is a winner!", "We Have a Winner!",
JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
class Engine {
public static final int ROWS = 3;
public static final String GAME_OVER = "game over";
private XO[][] grid = new XO[ROWS][ROWS];
private XO turn = XO.X;
private boolean gameOver = false;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public Engine() {
reset();
}
public XO getTurn() {
return turn;
}
public boolean isGameOver() {
return gameOver;
}
public void setXO(int row, int col) {
grid[row][col] = turn;
checkForWin(row, col);
turn = (turn == XO.X) ? XO.O : XO.X;
}
public void reset() {
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
grid[r][c] = XO.BLANK;
}
}
turn = XO.X;
gameOver = false;
}
public void checkForWin(int i, int j) {
boolean win = true;
for (int col = 0; col < grid.length; col++) {
if (grid[col][j] != turn) {
win = false;
}
}
if (!win) {
win = true;
for (int row = 0; row < grid[i].length; row++) {
if (grid[i][row] != turn) {
win = false;
}
}
}
if (!win && i == j) {
win = true;
for (int k = 0; k < grid.length; k++) {
if (grid[k][k] != turn) {
win = false;
}
}
}
if (!win && i + j == 2) {
win = true;
for (int k = 0; k < grid.length; k++) {
if (grid[k][2 - k] != turn) {
win = false;
}
}
}
if (win) {
setGameOver(true);
}
}
private void setGameOver(boolean gameOver) {
boolean oldValue = this.gameOver;
boolean newValue = gameOver;
this.gameOver = gameOver;
pcSupport.firePropertyChange(GAME_OVER, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name,
PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name,
PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
enum XO {
X("X"), O("O"), BLANK(" ");
private String text;
private XO(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
My view's ActionListener (here an AbstractAction) notifies the Engine that a certain button has been pushed. The Engine keeps track of which button has been pushed, and when a winner has been determined, sets a gameOver field thereby notifying all listeners that the game is over.

Java swing repainting while computing: animating sorting algorithm

http://www.youtube.com/watch?v=M0cNsmjK33E
I want to develop something similar to the link above using Java Swing. I have the sorting method and did while repaint but when I triggered the sorting, instead of showing the bars slowly sorting itself, it freezes and then unfreezes when the array has been fully sorted.
How do I fix this?
Edit: sorry forgot about the codes. its a very simple gui. and another class for sorting which sorts the whole array
public class SortGUI {
JFrame frame;
int frameWidth = 1000, frameHeight = 1000;
int panelWidth, panelHeight;
DrawPanel panel;
JPanel panel2;
JScrollPane scroll;
JViewport view;
static int[] S = new int[50000];
public static void main(String[] args) throws InterruptedException {
SortGUI app = new SortGUI();
initializeArray();
app.go();
}
public static void initializeArray()
{
for (int i = 0; i < S.length; i++) {
S[i] = (int) (Math.random() * 16581375);
}
}
public void go() throws InterruptedException {
//Frame
frame = new JFrame();
frame.setSize(frameWidth, frameHeight);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//panel
panel = new DrawPanel();
scroll = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
//Layout
frame.add(scroll);
frame.addKeyListener(new keyListener());
while(true)
{
panel.repaint();
}
}
public class DrawPanel extends JPanel
{
public DrawPanel()
{
this.setPreferredSize(new Dimension(50000,930));
}
public void paintComponent(Graphics g)
{
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
for(int i = 0; i < S.length; i++)
{
int red = S[i] / 65025;
int green = (S[i] > 65025)? S[i] % 65025 : 0;
int blue = green;
blue %= 255;
green /= 255;
g.setColor(new Color(red,green,blue));
g.fillRect(i, 900 - (S[i] / 18500), 1, S[i] / 18500);
}
}
}
public class keyListener implements KeyListener{
public void keyTyped(KeyEvent ke) {
}
public void keyPressed(KeyEvent ke) {
if(ke.getKeyChar() == '1')
{
sorter.bubbleSort(S);
}
}
public void keyReleased(KeyEvent ke) {
}
}
}
Note: I started writing this before the question was deleted
Most likely your using some looping mechanism and praying that each iteration, the ui with be updated. That's a wrong assumption. The UI will not be update until the loop is finished. What you are doing is what we refer to as blocking the Event Dispatch Thread(EDT)
See How to use a Swing Timer. Make "iterative" updates in the ActionListener call back. For instance, if you want to animate a sorting algorithm, you need to determine what needs to be updated per "iteration" of the timer callback. Then each iteration repaint the ui.
So your Timer timer could look something like
Timer timer = new Timer(40, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if (sortingIsDone()) {
((Timer)e.getSource()).stop();
} else {
sortOnlyOneItem();
}
repaint();
}
});
Your sortOnlyOneItem method should only, well, perform a sort for just one item. And have some sort of flag to check if the sorting is done, then stop the timer.
Other notes:
You should be calling super.paintComponent in the paintComponent method, if you aren't going to paint the background yourself. Generally I always do though.
Here's a complete example. I'm glad you figured it out on your own. I was working on this example before I saw that you got it.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class SelectionSortAnimate extends JPanel {
private static final int NUM_OF_ITEMS = 20;
private static final int DIM_W = 400;
private static final int DIM_H = 400;
private static final int HORIZON = 350;
private static final int VERT_INC = 15;
private static final int HOR_INC = DIM_W / NUM_OF_ITEMS;
private JButton startButton;
private Timer timer = null;
private JButton resetButton;
Integer[] list;
int currentIndex = NUM_OF_ITEMS - 1;
public SelectionSortAnimate() {
list = initList();
timer = new Timer(200, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (isSortingDone()) {
((Timer) e.getSource()).stop();
startButton.setEnabled(false);
} else {
sortOnlyOneItem();
}
repaint();
}
});
startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
list = initList();
currentIndex = NUM_OF_ITEMS - 1;
repaint();
startButton.setEnabled(true);
}
});
add(startButton);
add(resetButton);
}
public boolean isSortingDone() {
return currentIndex == 0;
}
public Integer[] initList() {
Integer[] nums = new Integer[NUM_OF_ITEMS];
for (int i = 1; i <= nums.length; i++) {
nums[i - 1] = i;
}
Collections.shuffle(Arrays.asList(nums));
return nums;
}
public void drawItem(Graphics g, int item, int index) {
int height = item * VERT_INC;
int y = HORIZON - height;
int x = index * HOR_INC;
g.fillRect(x, y, HOR_INC, height);
}
public void sortOnlyOneItem() {
int currentMax = list[0];
int currentMaxIndex = 0;
for (int j = 1; j <= currentIndex; j++) {
if (currentMax < list[j]) {
currentMax = list[j];
currentMaxIndex = j;
}
}
if (currentMaxIndex != currentIndex) {
list[currentMaxIndex] = list[currentIndex];
list[currentIndex] = currentMax;
}
currentIndex--;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < list.length; i++) {
drawItem(g, list[i], i);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(DIM_W, DIM_H);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Sort");
frame.add(new SelectionSortAnimate());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

Breakout Game: JButton problems

I am a beginner programmer and I am trying to make a simple 2D game, Breakout. I have the logic for the game itself working but I am having trouble with getting the buttons to work with the game. I added a start and pause button to the top of the screen but whenever I pressed one of these buttons, the paddle at the bottom of the screen cannot move.
When I take out the buttons the game runs perfectly.
Any help would be greatly appreciated! Thank you in advance.
Below is the code for my game. I only included the Breakout class because this was were I ran into trouoble.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.TimerTask;
public class Breakout extends JPanel implements KeyListener, ActionListener
{
boolean rightPressed;
boolean leftPressed;
boolean upPressed;
boolean downPressed;
boolean inGame;
int width = 1450;
int height = 900;
Timer tm = new Timer(5, this);
int numRows =5;
int numCols = 8;
int numBricks = 40;
int mouseX;
int mouseY;
Paddle paddle = new Paddle(width/2, height-40);
Ball ball = new Ball();
//BrickArray brick = new BrickArray(numRows, numCols, width/numCols, (height-100)/numRows);
Brick[][] bricks = new Brick[8][5];
JButton start = new JButton("Start");
JButton pause = new JButton("Pause");
JButton reset = new JButton("Reset");
JButton exit = new JButton("Exit");
JButton help = new JButton("Help");
public Breakout()
{
setDoubleBuffered(true);
//tm.start();
addKeyListener(this);
setFocusable(true);
add(start);
start.addActionListener(new StartAction());
add(pause);
pause.addActionListener(new PauseAction());
add(reset);
add(exit);
add(help);
ball.setMaxX(width);
ball.setMaxY(height);
ball.setWidth(width);
ball.setHeight(height);
ball.setX(width/2); //width/2
ball.setY(height/2); //height
paddle.setMaxX(width-paddle.getWidth());
int k=0;
//row 1
for(int a=0; a<bricks.length; a++)
{
bricks[a][0]=new Brick(120,40);
bricks[a][0].setX(a*180);
bricks[a][0].setY(50);
//System.out.println(k + ": " + a*80);
}
//row 2
for(int b=0; b<bricks.length; b++)
{
bricks[b][1]=new Brick(120,40);
bricks[b][1].setX(b*180);
bricks[b][1].setY(100);
}
//row 3
for(int c=0; c<bricks.length; c++)
{
bricks[c][2]=new Brick(120,40);
bricks[c][2].setX(c*180);
bricks[c][2].setY(150);
}
//row 4
for(int d=0; d<bricks.length; d++)
{
bricks[d][3]=new Brick(120,40);
bricks[d][3].setX(d*180);
bricks[d][3].setY(200);
}
for(int e=0; e<bricks.length; e++)
{
bricks[e][4]=new Brick(120,40);
bricks[e][4].setX(e*180);
bricks[e][4].setY(250);
}
}
public void actionPerformed(ActionEvent e)
{
tm.setRepeats(true);
if(rightPressed)
{
paddle.setX(paddle.getX()+5);
//System.out.println("Pressed");
}
if(leftPressed)
paddle.setX(paddle.getX()-5);
/*if(upPressed)
y--;
if(downPressed)
y++;*/
ball.checkCollision(paddle);
for(int i=0; i<bricks.length; i++)
{
for(int j=0; j<bricks[i].length; j++)
{
if(ball.checkCollision(bricks[i][j]))
{
bricks[i][j].destroy();
//System.out.println(bricks[i][j].isDestroyed());
numBricks--;
ball.move();
repaint();
}
}
}
//ball.checkCollision(brick);
ball.move();
repaint();
}
public void keyPressed(KeyEvent e)
{
int c = e.getKeyCode();
if(c == KeyEvent.VK_LEFT)
{
leftPressed=true;
}
/*if(c == KeyEvent.VK_UP)
{
upPressed=true;
}*/
if(c == KeyEvent.VK_RIGHT)
{
rightPressed=true;
//System.out.println("Pressed");
}
/*if(c == KeyEvent.VK_DOWN)
{
downPressed=true;
}*/
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
int c = e.getKeyCode();
if(c == KeyEvent.VK_LEFT)
{
leftPressed=false;
}
if(c == KeyEvent.VK_UP)
{
upPressed=false;
}
if(c == KeyEvent.VK_RIGHT)
{
rightPressed=false;
}
if(c == KeyEvent.VK_DOWN)
{
downPressed=false;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int a=0; a<bricks.length; a++)
{
g.setColor(Color.RED);
bricks[a][0].paintComponent(g);
}
for(int b=0; b<bricks.length; b++)
{
g.setColor(Color.ORANGE);
bricks[b][1].paintComponent(g);
}
for(int c=0; c<bricks.length; c++)
{
g.setColor(Color.YELLOW);
bricks[c][2].paintComponent(g);
}
for(int d=0; d<bricks.length; d++)
{
g.setColor(Color.GREEN);
bricks[d][3].paintComponent(g);
}
for(int e=0; e<bricks.length; e++)
{
g.setColor(Color.BLUE);
bricks[e][4].paintComponent(g);
}
ball.paintComponent(g);
paddle.paintComponent(g);
g.setColor(Color.BLACK);
g.drawString("Bricks left: " + numBricks, 10, 10);
}
public static void main(String[] args)
{
Breakout obj = new Breakout();
JFrame jf = new JFrame();
jf.setTitle("Breakout");
jf.setSize(1450,900);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(obj);
}
class StartAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
tm.start();
System.out.println("Start");
}
}
class PauseAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
tm.stop();
System.out.println("Pause");
}
}
}
I don't have the other classes implemented so I cannot confirm if this will work.
start.setFocusable(false);
pause.setFocusable(false);
Alternatively
start.addKeyListener(this);
pause.addKeyListener(this);

Adding/Removing from a JPanel

I am trying to make a basic map where pressing a button moves a character.
I am using Netbeans and so far it's going smoothly! Except for trying to remove a JLabel from a JPanel and then add a new JLabel to it.
Here is my full code:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class startMap extends JFrame {
public int locX = 1;
public int locY = 1;
ImageIcon tile = new ImageIcon("src/tile.png");
JLabel tileLabel = new JLabel(tile);
ImageIcon berry = new ImageIcon("src/berry.png");
JLabel berryLabel = new JLabel(berry);
ImageIcon blank = new ImageIcon("src/blank.png");
JLabel blankLabel = new JLabel(blank);
JLabel testL = new JLabel("LOL");
JPanel[][] map = new JPanel[7][7];
public startMap() {
setBackground(Color.BLACK);
setFocusable(true);
keyHandler kh = new keyHandler();
addKeyListener(kh);
mapGUI();
}
public void mapGUI() {
JPanel mainP = new JPanel();
mainP.setBackground(Color.BLACK);
mainP.setLayout(new FlowLayout());
for (int x = 0; x < 7; x++) {
for (int i = 0; i < 7; i++) {
map[x][i] = new JPanel();
System.out.println("1");
blankLabel = new JLabel(blank);
map[x][i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
map[x][i].add(blankLabel);
}
}
for (int x = 1; x < 6; x++) {
for (int i = 1; i < 6; i++) {
System.out.println("2");
map[x][i].removeAll();
revalidate();
repaint();
tileLabel = new JLabel(tile);
map[x][i].add(tileLabel);
revalidate();
repaint();
}
}
System.out.println("3");
map[locX][locY].removeAll();
revalidate();
repaint();
map[locX][locY].add(berryLabel);
revalidate();
repaint();
for (int x = 0; x < 7; x++) {
for (int i = 0; i < 7; i++) {
mainP.add(map[x][i]);
}
}
add(mainP);
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
private class keyHandler extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
locY+=1;
map[locX][locY].removeAll();
revalidate();
repaint();
map[locX][locY].add(berryLabel);
revalidate();
repaint();
}
}
}
}
Here is what changes the squares when the user clicks Right.
Here is the KeyAdapter code:
private class keyHandler extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
locY+=1;
map[locX][locY].removeAll();
revalidate();
repaint();
map[locX][locY].add(berryLabel);
revalidate();
repaint();
}
}}
NOTE: the system out is just a debugging method I use to check what's being called when.
So when I run it looks like this
Move to the right and revalidate $ repaint:
Why does the box located in 1,1 go to being gray?
Help figuring out how to make the boxes stay with a white square instead of turning back to gray.
----------------------------SSCCE----------------------------------
Use the full code above
and this is the main class:
import javax.swing.*;
public class TestGame extends JFrame {
public static void main(String[] args) {
startMap sm = new startMap();
sm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sm.setVisible(true);
sm.setSize(380,415);
sm.setResizable(false);
}
}
Fixed Version:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class startMap extends JFrame {
public int locX = 1;
public int locY = 1;
ImageIcon tile = new ImageIcon("src/tile.png");
JLabel tileLabel = new JLabel(tile);
ImageIcon berry = new ImageIcon("src/berry.png");
JLabel berryLabel = new JLabel(berry);
ImageIcon blank = new ImageIcon("src/blank.png");
JLabel blankLabel = new JLabel(blank);
JLabel testL = new JLabel("LOL");
JPanel[][] map = new JPanel[7][7];
public startMap() {
setBackground(Color.BLACK);
setFocusable(true);
keyHandler kh = new keyHandler();
addKeyListener(kh);
mapGUI();
}
public void mapGUI() {
JPanel mainP = new JPanel();
mainP.setBackground(Color.BLACK);
mainP.setLayout(new FlowLayout());
for (int x = 0; x < 7; x++) {
for (int i = 0; i < 7; i++) {
map[x][i] = new JPanel();
System.out.println("1");
blankLabel = new JLabel(blank);
map[x][i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
map[x][i].add(blankLabel);
}
}
for (int x = 1; x < 6; x++) {
for (int i = 1; i < 6; i++) {
System.out.println("2");
map[x][i].removeAll();
tileLabel = new JLabel(tile);
map[x][i].add(tileLabel);
revalidate();
repaint();
}
}
System.out.println("3");
map[locX][locY].removeAll();
map[locX][locY].add(berryLabel);
revalidate();
repaint();
for (int x = 0; x < 7; x++) {
for (int i = 0; i < 7; i++) {
mainP.add(map[x][i]);
}
}
add(mainP);
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
private class keyHandler extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
berryLabel = new JLabel(berry); //THIS
tileLabel = new JLabel(tile); //And THIS had to be RE initialized idk why.
map[locX][locY].removeAll();
map[locX][locY].add(tileLabel);
locY += 1;
map[locX][locY].removeAll();
map[locX][locY].add(berryLabel);
revalidate();
repaint();
}
}
}
}
Should be called after adding / removing
revalidate();
repaint();
Don't call repaint() from paint()

Java Paint (yes I know but I searched..), ActionListeners

thank you so much but I need Listener methods and solved it now.. But now I cant see the buttons until I hover on them! I think its just a small mistake but I couldnt figure it out!! Now my code is like below...
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class PaintMain extends JFrame
{
JPanel colorPanel = new JPanel();
JPanel drawPanel = new JPanel();
JPanel selectPanel = new JPanel();
JButton[][] randomColors = new JButton[5][5];
Color selectedColor = Color.BLACK;
Random colorGenerator = new Random();
int curx = drawPanel.getX();
int cury = drawPanel.getY();
public PaintMain()
{
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
colorPanel.setLayout(new GridLayout(5,5));
drawPanel.setLayout(new BorderLayout());
drawPanel.setBackground(Color.WHITE);
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
randomColors[i][j]=new JButton();
randomColors[i][j].setBackground(getRandomColor());
randomColors[i][j].addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if( e.getSource() instanceof JButton)
{
selectedColor=((JButton)e.getSource()).getBackground();
System.out.println(selectedColor);
}
}
});
colorPanel.add(randomColors[i][j]);
}
}
this.addMouseMotionListener(new MouseLsnr());
add(colorPanel, BorderLayout.WEST);
add(drawPanel, BorderLayout.CENTER);
setVisible(true);
pack();
}
public Color getRandomColor()
{
return new Color(colorGenerator.nextInt(256), colorGenerator.nextInt(256), colorGenerator.nextInt(256));
}
public static void main(String[] args)
{
new PaintMain();
}
public void paint(Graphics g)
{
//super.paint(g);
g.setColor(selectedColor);
g.drawRect(curx, cury, 2, 1);
}
class MouseLsnr implements MouseMotionListener
{
public void mouseDragged(MouseEvent arg0) {
System.out.println(arg0.getX()+":"+arg0.getY());
curx=arg0.getX();
cury=arg0.getY();
repaint();
}
public void mouseMoved(MouseEvent arg0)
{
}
}
}
You'll want to take a closer look at Custom Painting
The you might want to take a read through How to Write a Mouse Listener
public class RandomColorPane {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new RandomColorPane();
}
public RandomColorPane() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
JPanel colorPanel = new JPanel();
JPanel drawPanel = new DrawPane();
JPanel selectPanel = new JPanel();
JPanel[][] randomColors = new JPanel[5][5];
Color selectedColor = Color.BLACK;
Random colorGenerator = new Random();
int curx = drawPanel.getX();
int cury = drawPanel.getY();
public MainPane() {
setLayout(new BorderLayout());
colorPanel.setLayout(new GridLayout(5, 5));
drawPanel.setLayout(new BorderLayout());
drawPanel.setBackground(Color.WHITE);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
randomColors[i][j] = new JPanel();
randomColors[i][j].setPreferredSize(new Dimension(25, 25));
randomColors[i][j].setBackground(getRandomColor());
// randomColors[i][j].addActionListener(new ActionListener() {
// #Override
// public void actionPerformed(ActionEvent e) {
// if (e.getSource() instanceof JButton) {
// selectedColor = ((JButton) e.getSource()).getBackground();
// drawPanel.setForeground(selectedColor);
// drawPanel.repaint();
// }
// }
//
// });
randomColors[i][j].addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
drawPanel.setForeground(((JPanel)e.getSource()).getBackground());
drawPanel.repaint();
}
});
colorPanel.add(randomColors[i][j]);
}
}
add(colorPanel, BorderLayout.WEST);
add(drawPanel, BorderLayout.CENTER);
}
public Color getRandomColor() {
return new Color(colorGenerator.nextInt(256), colorGenerator.nextInt(256), colorGenerator.nextInt(256));
}
}
public class DrawPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(20, 20);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - 10) / 2;
int y = (getHeight() - 10) / 2;
g.setColor(getForeground());
g.fillRect(x, y, 20, 20);
}
}
}

Categories

Resources