I'm trying to write a program where you guess a random generated number (from 1-1000) and the program will tell you if you're getting close or not. The problem I'm having is that I have to have the background change color according to how close you are to the answer. Red is closer, blue is further away. I have the code but I can't figure out why the background isn't working. Is it something to do with the container? Thank you!
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Random;;
public class GuessGame extends JFrame
{
private JButton newGameButton;
private JButton enterButton;
private JButton exitButton;
private JTextField guessBox;
private JLabel initialTextLabel;
private JLabel enterLabel;
private JLabel userMessageLabel;
private int randomNumber;
private int userGuess;
private int counter = 0;
private int lastGuess = 0;
private Color background;
Container container;
public GuessGame()
{
super("Guessing Game");
newGameButton = new JButton("New Game");
exitButton = new JButton("Exit Game");
enterButton = new JButton("Enter");
guessBox = new JTextField(4);
initialTextLabel = new JLabel("I have a number between 1 and 1000 can you guess my number?");
enterLabel = new JLabel("Please enter your first guess.");
userMessageLabel = new JLabel("");
randomNumber = new Random().nextInt(1000) + 1;
container=getContentPane();
container.setLayout(new FlowLayout());
container.add(initialTextLabel);
container.add(enterLabel);
container.add(guessBox);
container.add(newGameButton);
container.add(enterButton);
container.add(exitButton);
container.add(userMessageLabel);
setSize(400, 150);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
newGameButtonHandler nghandler = new newGameButtonHandler();
newGameButton.addActionListener(nghandler);
ExitButtonHandler exithandler = new ExitButtonHandler();
exitButton.addActionListener(exithandler);
enterButtonHandler enterhandler = new enterButtonHandler();
enterButton.addActionListener(enterhandler);
}
class newGameButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
getContentPane();
background=Color.lightGray;
userMessageLabel.setText("");
randomNumber = new Random().nextInt(1000) + 1;
}
}
class ExitButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
class enterButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
userGuess = Integer.parseInt(guessBox.getText());
compareGuess(userGuess, randomNumber);
}
}
public void paint(Graphics g)
{
super.paint(g);
container.setBackground(background);
}
public void compareGuess(int userGuess, int randomNumber)
{
counter++;
if (userGuess == randomNumber)
{
userMessageLabel.setText("You are correct, it took you: " + counter + " tries");
getContentPane();
background=Color.green;
}
else if (userGuess > randomNumber)
{
userMessageLabel.setText("Too high");
}
else if (userGuess < randomNumber)
{
userMessageLabel.setText("Too Low");
}
if (counter > 1)
{
if ((randomNumber - userGuess) > (randomNumber - lastGuess))
{
getContentPane();
background=Color.red;
}
else if ((randomNumber - userGuess) < (randomNumber - lastGuess))
{
getContentPane();
background=Color.blue;
}
else
{
getContentPane();
background=Color.gray;
}
}
lastGuess = userGuess;
}
public static void main(String[] args)
{
GuessGame myGuessGame = new GuessGame();
myGuessGame.setVisible(true);
}
}
You are trying to override paint(Graphics g) function of JFrame. We should not override paint function of Top level component like JFrame.
Use a custom component extending JPanel and override its paintComponent(Graphics g) function and don't forget to call super.paintComponent(g) inside this function.
When any update should be made to the painting of a component, invoke component.repaint() on that component to reflect the changes on the GUI.
Please have a tour to the Official tutorial page: Lesson: Performing Custom Painting
I addition to Sage's comments, you are calling setBackground from within the paint, which is simply going to make another request to paint...again and again and again...
The other problem is, you are changing the background of the frame, not it's content pane.
Instead, get rid of your paint method, you're not doing anything with it...
Instead, when you want to change the color, simply call getContentPane().setBackground(...), for example...
class newGameButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
getContentPane().setBackground(Color.lightGray);
userMessageLabel.setText("");
randomNumber = new Random().nextInt(1000) + 1;
}
}
If that doesn't work, you may need to call getContentPane().repaint()
Related
This is my code for a game im making. At the moment im not worried about how the game functions I've been more so worried about the fact that each time I hit the UP button the panels disappear and sometimes when i hit the LEFT button as well. Is there an explanation to this can anyone help me understand why this happens?? I have a feeling it has something to do with my if statements but im not really sure. also, im messing around with the key listener and if you could give me some advice on key listeners like some dos and donts I really appreciate the help!!
import javax.swing.*;
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class Game extends Applet implements ActionListener,KeyListener {
Image image;
MediaTracker tr;
JLabel label,computerLabel;
JPanel panel,computerPanel;
Button start,up,down;
Label result;
Dimension SIZE = new Dimension(50,50);
int x = 0;
int y = 0;
int w = 100;
int q = 100;
int WIDTH = 50;
int HEIGHT = 50;
//Player Integers
int zeroPosX,zeroPosY,xLeft,xUp;
//Computer integers
int compZeroPosX,compZeroPosY,compXLeft,compXUp;
//--------------------------------------
public void init() {
setLayout(new FlowLayout());
start = new Button("Start");
up = new Button("UP");
down = new Button("LEFT");
//PlayerPiece stuff
ImageIcon icon = new ImageIcon("playerpiece.png");
label = new JLabel(icon);
panel = new JPanel();
label.setVisible(true);
panel.add(label);
panel.setPreferredSize(SIZE);
//ComputerPiece Stuff
ImageIcon computerIcon = new ImageIcon("computerPiece.png");
computerPanel = new JPanel();
computerLabel = new JLabel(computerIcon);
computerLabel.setVisible(true);
computerPanel.add(computerLabel);
computerPanel.setPreferredSize(SIZE);
//===============================================
result = new Label("=========");
addKeyListener(this);
setSize(650,650);
up.addActionListener(this);
down.addActionListener(this);
start.addActionListener(this);
label.setSize(WIDTH,HEIGHT);
label.setLocation(0,0);
add(computerPanel);
add(panel);
add(start);
add(up);
add(down);
add(result);
}
//--------------------------------------
public void paint(Graphics g) {
Graphics2D firstLayer = (Graphics2D)g;
Graphics2D secondLayer = (Graphics2D)g;
Graphics2D thirdLayer = (Graphics2D)g;
secondLayer.setColor(Color.BLACK);
for(x=100; x<=500; x+=100)
for(y=100; y <=500; y+=100)
{
firstLayer.fillRect(x,y,WIDTH,HEIGHT);
}
for(w=150; w<=500; w+=100)
for(q=150; q <=500; q+=100)
{
secondLayer.fillRect(w,q,WIDTH,HEIGHT);
}
}
//--------------------------------------
public void actionPerformed(ActionEvent ae) {
int [] range = {50,0,0,0,0};
int selection = (int)Math.random()*5 ;
//~~~~~~~~~~~~~~~~~~~~~~~~~
//PlayerPositioning
zeroPosX = panel.getX();
zeroPosY = panel.getY();
xLeft = zeroPosX - 50;
xUp = zeroPosY - 50;
//ComputerPositioning
compZeroPosX = computerPanel.getX();
compZeroPosY = computerPanel.getY();
compXLeft = compZeroPosX - range[selection];
compXUp = compZeroPosY - range[selection];
//~~~~~~~~~~~~~~~~~~~~~~~~~~
Button user = (Button)ae.getSource();
//Starting the game
if(user.getLabel() == "Start") {
result.setText("=========");
//playersetup
label.setLocation(0,0);
panel.setLocation(300,500);
//============================
//npc setup
computerLabel.setLocation(0,0);
computerPanel.setLocation(500,300);
}
if(compZeroPosX >= 150) {
if(compZeroPosY >= 150) {
if(zeroPosX >= 150) {
if(zeroPosY >=150) {
if(user.getLabel() == "UP") {
panel.setLocation(zeroPosX,xUp);
}
else
computerPanel.setLocation(compZeroPosX,compXUp);
if(user.getLabel() == "LEFT") {
panel.setLocation(xLeft,zeroPosY);
}
else
computerPanel.setLocation(compXLeft,compZeroPosY);
if(panel.getX() < 150)
result.setText("GAME-OVER");
if(panel.getY() < 150)
result.setText("GAME-OVER");
}
}
}
}
}
#Override
public void keyPressed(KeyEvent kp) {
int keycode = kp.getKeyCode();
switch (keycode) {
case KeyEvent.VK_W:
panel.setLocation(xLeft,zeroPosY);
break;
}
}
#Override
public void keyReleased(KeyEvent kr) {
}
#Override
public void keyTyped(KeyEvent kt) {
}
}
Issues and suggestions:
You're mixing AWT (e.g., Applet, Button, Label) with Swing (e.g., JPanel, JLabel) dangerously and without need. Stick with Swing and get rid of all vestiges of AWT.
You're painting directly in a top-level window, here the Applet, a dangerous thing to do. Don't. Follow the Swing graphics tutorials and do your drawing in a JPanel's paintComponent method.
You're not calling the super method within your painting method override, another dangerous thing to do, and another indication that you're trying to do this without reading the important relevant tutorials.
Don't compare Strings using == or !=. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two object references are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here.
You're trying to directly set the location of a component such as a JPanel without regard for the layout managers. Don't do this. Instead move logical (non-component) entities and display the movement in your graphics.
You can find links to the Swing tutorials and to other Swing resources here: Swing Info
Later we can talk why you should avoid applets of all flavors...
Myself, I'd move ImageIcons around a grid of JLabels and not directly use a painting method at all. For example,
To see, run the following code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Game2 extends JPanel {
private static final String CPU_PATH = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/"
+ "Gorilla-thinclient.svg/50px-Gorilla-thinclient.svg.png";
private static final String PERSON_PATH = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/"
+ "Emblem-person-blue.svg/50px-Emblem-person-blue.svg.png";
private static final int SQR_WIDTH = 50;
private static final int SIDES = 10;
private static final Dimension SQR_SIZE = new Dimension(SQR_WIDTH, SQR_WIDTH);
private static final Color DARK = new Color(149, 69, 53);
private static final Color LIGHT = new Color(240, 220, 130);
private JLabel[][] labelGrid = new JLabel[SIDES][SIDES];
private Icon playerIcon;
private Icon computerIcon;
public Game2() throws IOException {
// would use images instead
playerIcon = createIcon(PERSON_PATH);
computerIcon = createIcon(CPU_PATH);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new StartAction("Start", KeyEvent.VK_S)));
buttonPanel.add(new JButton(new UpAction("Up", KeyEvent.VK_U)));
buttonPanel.add(new JButton(new LeftAction("Left", KeyEvent.VK_L)));
JPanel gameBrd = new JPanel(new GridLayout(SIDES, SIDES));
gameBrd.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for (int i = 0; i < labelGrid.length; i++) {
for (int j = 0; j < labelGrid[i].length; j++) {
JLabel label = new JLabel();
label.setPreferredSize(SQR_SIZE);
label.setOpaque(true);
Color c = i % 2 == j % 2 ? DARK : LIGHT;
label.setBackground(c);
gameBrd.add(label);
labelGrid[i][j] = label;
}
}
setLayout(new BorderLayout());
add(buttonPanel, BorderLayout.PAGE_START);
add(gameBrd);
// random placement, just for example
labelGrid[4][4].setIcon(computerIcon);
labelGrid[5][5].setIcon(playerIcon);
}
private Icon createIcon(String path) throws IOException {
URL url = new URL(path);
BufferedImage img = ImageIO.read(url);
return new ImageIcon(img);
}
private abstract class MyAction extends AbstractAction {
public MyAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
}
private class StartAction extends MyAction {
public StartAction(String name, int mnemonic) {
super(name, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO start game code
}
}
// move all icons up
private class UpAction extends MyAction {
public UpAction(String name, int mnemonic) {
super(name, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// collection to hold label that needs to be moved
Map<JLabel, Icon> labelMap = new HashMap<>();
for (int i = 0; i < labelGrid.length; i++) {
for (int j = 0; j < labelGrid[i].length; j++) {
Icon icon = labelGrid[i][j].getIcon();
if (icon != null) {
int newI = i == 0 ? labelGrid.length - 1 : i - 1;
labelGrid[i][j].setIcon(null);
labelMap.put(labelGrid[newI][j], icon);
}
}
}
// move the icon after the iteration complete so as not to move it twice
for (JLabel label : labelMap.keySet()) {
label.setIcon(labelMap.get(label));
}
}
}
// move all icons left
private class LeftAction extends MyAction {
public LeftAction(String name, int mnemonic) {
super(name, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Map<JLabel, Icon> labelMap = new HashMap<>();
for (int i = 0; i < labelGrid.length; i++) {
for (int j = 0; j < labelGrid[i].length; j++) {
Icon icon = labelGrid[i][j].getIcon();
if (icon != null) {
int newJ = j == 0 ? labelGrid[i].length - 1 : j - 1;
labelGrid[i][j].setIcon(null);
labelMap.put(labelGrid[i][newJ], icon);
}
}
}
for (JLabel label : labelMap.keySet()) {
label.setIcon(labelMap.get(label));
}
}
}
private static void createAndShowGui() {
Game2 mainPanel = null;
try {
mainPanel = new Game2();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("Game2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
I am making a clone of minesweeper with (slightly modified) JButtons. Because there are so many game tiles in minesweeper, I am storing them as an array. When I try and add the buttons to the Frame using a for loop, I get a nullpointerexception on the buttons. The class ButtonObject is extended from the JButton class with just two extra variables and getter/setter methods. What is going wrong?
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Minesweeper extends JFrame implements ActionListener{
JLabel starttitle;
ButtonObject[] minefield;
JFrame frame;
Random r = new Random();
int rand;
JPanel startscreen;
JPanel gamescreen;
int gamesize;
JButton ten;
JButton tfive;
JButton fifty;
GridLayout layout;
public Minesweeper()
{
frame = new JFrame("Minesweeper");
frame.setSize(500,500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);;
startscreen = new JPanel();
startScreen();
}
public void startScreen()
{
ten = new JButton("10 x 10");
tfive = new JButton("25 x 25");
fifty = new JButton("50 x 50");
starttitle = new JLabel("Welcome to minesweeper. Click a game size to begin.");
frame.add(startscreen);
startscreen.add(starttitle);
startscreen.add(ten);
startscreen.add(tfive);
startscreen.add(fifty);
ten.addActionListener(this);
tfive.addActionListener(this);
fifty.addActionListener(this);
}
public void initializeGame()
{
minefield = new ButtonObject[gamesize];
for(int i = 0;i<gamesize;i++)
{
minefield[i]=new ButtonObject();
rand = r.nextInt(5);
if(rand==5)
{
minefield[i].setButtonType(true);//this tile is a mine
}
}
}
public void gameScreen()
{
frame.getContentPane().removeAll();
frame.repaint();
initializeGame();
for(int i = 0;i<minefield.length;i++)
{
gamescreen.add(this.minefield[i]);//EXCEPTION HERE
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==ten)
{
gamesize = 99;
gameScreen();
}
else if(e.getSource()==tfive)
{
gamesize = 624;
gameScreen();
}
else if(e.getSource()==fifty)
{
gamesize = 2499;
gameScreen();
}
else
{
System.out.println("Fatal error");
}
}
public static void main(String[] args)
{
new Minesweeper();
}
}
Well, you never initialize your gamescreen variable, so that's totally normal you get a NullPointerException at this line.
This is homework. I included relevant code at the bottom.
Problem:
In an attempted to allow the user to resize the grid, the grid is now being drawn severely overpopuated.
Screen Shots:
"Overpopulation" -
http://i.imgur.com/zshAC6n.png
"Desired Population" -
http://i.imgur.com/5Rf6P42.png
Background:
It's a version of Conway's Game of Life. In class we completed 3 classes: LifeState which handles the game logic, LifePanel which is a JPanel that contains the game, and a driver that created a JFrame and added the LifePanel. The assignment was to develop it into a full GUI application with various requirements. My solution was to extend JFrame and do most of my work in that class.
Initializing the LifePanel outside of the actionlistener yields normal population, but intializing the LifePanel in the actionlistener "overpopulates" the grid.
Question: Why is the overpopulation occurring?
LifePanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class LifePanel extends JPanel implements MouseListener
{
private int row;
private int col;
private int scale;
private LifeState life;
boolean state;
boolean wrap;
int delay;
Timer timer;
public LifePanel(int r, int c, int s, int d)
{
row = r;
col = c;
scale = s;
delay = d;
life = new LifeState(row,col);
Random rnd = new Random();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
life.setCell(i,j,rnd.nextBoolean());
timer = new Timer(delay, new UpdateListener());
setPreferredSize( new Dimension(scale*row, scale*col));
addMouseListener(this);
timer.start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
if(life.getCell(i,j))
g.fillRect(scale*i,scale*j,scale,scale);
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getScale() {
return scale;
}
public void setScale(int scale) {
this.scale = scale;
}
public int getDelay() {
return delay;
}
public void setDelay(int delay) {
this.delay = delay;
timer.setDelay(delay);
}
public void pauseGame(){
timer.stop();
}
public void playGame(){
timer.restart();
}
public void setInitState(boolean set){
state = set;
if(state){
timer.stop();
}
}
public void setWrap(boolean set){
wrap = set;
if(wrap){
//implement allow wrap
}
}
#Override
public void mouseClicked(MouseEvent e) {
if(state){
int x=e.getX();
int y=e.getY();
boolean isFilled;
isFilled = life.getCell(x,y);
//Test pop-up
JOptionPane.showMessageDialog(this, x+","+y+"\n"+life.getCell(x,y));
if(isFilled){
life.setCell(x,y,false);
}else{
life.setCell(x,y,true);
}
repaint();
}
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
private class UpdateListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
life.iterate();
repaint();
}
}
}
LifeFrame class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LifeFrame extends JFrame implements ActionListener{
JMenuBar menuBar;
JMenu mainMenu, helpMenu;
JMenuItem restartItem, quitItem, helpItem;
JButton stopButton, playButton, pauseButton, startButton;
CardLayout cardLayout = new MyCardLayout();
CardLayout cardLayout2 = new MyCardLayout();
SetupPanel setupPanel; //panel for input
LifePanel gamePanel; //game panel
JPanel controls = new JPanel(); //controls for game
JPanel controls2 = new JPanel(); //controls for input panel
JPanel cardPanel = new JPanel(cardLayout);
JPanel cardPanel2 = new JPanel(cardLayout2);
int gridRow=480;
int gridCol=480;
int scale=1;
int delay=2;
boolean setState = false;
boolean setWrap = false;
public LifeFrame() {
setTitle("Game of Life");
setLayout(new BorderLayout());
//Add the Panels
setupPanel = new SetupPanel();
gamePanel = new LifePanel(gridRow,gridCol,scale,delay);
cardPanel.add(setupPanel, "1");
cardPanel.add(gamePanel, "2");
add(cardPanel, BorderLayout.NORTH);
cardPanel2.add(controls2, "1");
cardPanel2.add(controls, "2");
add(cardPanel2, BorderLayout.SOUTH);
//init menu
menuBar = new JMenuBar();
//button listener setup
stopButton = new JButton("Stop");
pauseButton = new JButton("Pause");
playButton = new JButton("Play");
startButton = new JButton("Start");
stopButton.addActionListener(this);
pauseButton.addActionListener(this);
playButton.addActionListener(this);
startButton.addActionListener(this);
//menu listener setup
restartItem = new JMenuItem("Restart", KeyEvent.VK_R);
quitItem = new JMenuItem("Quit", KeyEvent.VK_Q);
helpItem = new JMenuItem("Help", KeyEvent.VK_H);
restartItem.addActionListener(this);
quitItem.addActionListener(this);
helpItem.addActionListener(this);
//add buttons
controls.add(stopButton);
controls.add(pauseButton);
controls.add(playButton);
controls2.add(startButton);
//build the menus
mainMenu = new JMenu("Menu");
mainMenu.setMnemonic(KeyEvent.VK_M);
helpMenu = new JMenu("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);
menuBar.add(mainMenu);
menuBar.add(helpMenu);
setJMenuBar(menuBar);
//add JMenuItems
restartItem.getAccessibleContext().setAccessibleDescription("Return to setup screen");
mainMenu.add(restartItem);
mainMenu.add(quitItem);
helpMenu.add(helpItem);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
try{
gridRow = setupPanel.getRowSize();
gridCol = setupPanel.getColSize();
scale = setupPanel.getScale();
delay = setupPanel.getDelay();
setWrap = setupPanel.getSetWrap();
setState = setupPanel.getSetState();
}catch (NumberFormatException n){
JOptionPane.showMessageDialog(LifeFrame.this, "Make sure the fields contain only digits and are completed!");
return;
}
if(e.getSource() == pauseButton){
gamePanel.pauseGame();
}else if(e.getSource() == playButton){
gamePanel.playGame();
}else if(e.getSource() == quitItem){
System.exit(0);
}else if(e.getSource() == restartItem || e.getSource() == stopButton){
cardLayout.show(cardPanel, "1");
cardLayout2.show(cardPanel2, "1");
pack();
setLocationRelativeTo(null);
}else if(e.getSource() == helpItem){
String helpText = "Help\nPlease make sure every field is completed and contains only digits\nCurrent Stats:\nGrid Size: "+gamePanel.getRow()+" by "+gamePanel.getCol()+"\nScale: "+ gamePanel.getScale() +"\nDelay: "+gamePanel.getDelay()+"\nManual Initial State: "+setState+"\nEnable Wrapping: "+setWrap;
JOptionPane.showMessageDialog(LifeFrame.this, helpText);
}else if(e.getSource() == startButton){
gamePanel = new LifePanel(gridRow,gridCol,scale,delay);
cardPanel.add(gamePanel, "2");
/*
* Alternate solution, throws array index out of bounds due to array usage in the LifePanel, but properly
* populates the grid.
*
gamePanel.setRow(gridRow);
gamePanel.setCol(gridCol);
gamePanel.setScale(scale);
gamePanel.setDelay(delay);
*/
if(setWrap){
gamePanel.setWrap(true);
gamePanel.playGame();
}else if(setState){
gamePanel.setInitState(true);
}else{
gamePanel.setWrap(false);
gamePanel.setInitState(false);
gamePanel.playGame();
}
gamePanel.repaint();
cardLayout.show(cardPanel, "2");
cardLayout2.show(cardPanel2, "2");
pack();
setLocationRelativeTo(null);
}
}
public static class MyCardLayout extends CardLayout {
#Override
public Dimension preferredLayoutSize(Container parent) {
Component current = findCurrentComponent(parent);
if (current != null) {
Insets insets = parent.getInsets();
Dimension pref = current.getPreferredSize();
pref.width += insets.left + insets.right;
pref.height += insets.top + insets.bottom;
return pref;
}
return super.preferredLayoutSize(parent);
}
public Component findCurrentComponent(Container parent) {
for (Component comp : parent.getComponents()) {
if (comp.isVisible()) {
return comp;
}
}
return null;
}
}
}
Thanks for reading all this, and in advance for any help/advice you offer.
EDIT: Added screen shots and refined question.
Based on how you initialize LifePanel
Random rnd = new Random();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
life.setCell(i,j,rnd.nextBoolean());
what you call "overpopulation" is the expected state. The above code will set about 1/2 of the cells to "alive" (or "occupied"), which is what your "overpopulated" state looks like.
The "desired population" screenshot contains many "life" artifacts such as "beehives", "gliders", "traffic lights", etc, and was either manually constructed or is the result of running several iterations on an initially 50% random population. With a 50% occupied population the first generation will result in wholesale clearing ("death") of many, many cells due to the proximity rules.
Most crucially, consider that, when starting up, your program does not paint the initial configuration. At least one iteration occurs before the first repaint() call.
I don't think your code is broken at all, just your expectation for what the initial population looks like.
I'm new in Java and I need your help in implementing a GUI. Below is a Guessing Game code. It works.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class GuessGame extends JFrame {
private JTextField guessTextField;
private JLabel introLabel, guessLabel, clueLabel;
private JButton enterB, playAgainB;
private int randomNumber;
public GuessGame() {
super("Guessing Game!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Creates components
enterB = new JButton("Guess");
playAgainB = new JButton("Quit");
introLabel = new JLabel("I have a number between 1 and 1000.");
guessLabel = new JLabel("Can you guess my number? Please enter your guess:");
clueLabel = new JLabel("");
// comment2 = new JLabel(" ");
guessTextField = new JTextField(5);
//content pane
Container c = getContentPane();
setLayout(new FlowLayout());
//adding component to the pane
c.add(introLabel);
c.add(guessLabel);
c.add(guessTextField);
//c.add(comment2);
c.add(enterB);
c.add(playAgainB);
c.add(clueLabel);
//enterB.setMnemonic('G');
//playAgainB.setMnemonic('Q');
setSize(350, 200);
setLocationRelativeTo(null);
setVisible(true);
//setResizable(false);
initializeNumber();
//creating the handler
GuessButtonHandler ghandler = new GuessButtonHandler(); //instantiate new object
enterB.addActionListener(ghandler); // add event listener
QuitButtonHandler qhandler = new QuitButtonHandler();
playAgainB.addActionListener(qhandler);
}
private void initializeNumber() {
randomNumber = new Random().nextInt(1000) + 1;
System.out.println(randomNumber);
}
class QuitButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
class GuessButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
int getUserInput;
int diff;
int Difference;
try {
getUserInput = Integer.parseInt(guessTextField.getText().trim());
if (getUserInput == randomNumber) {
clueLabel.setText(" Correct!");
}
if (getUserInput > randomNumber) {
clueLabel.setText(" Too High");
} else {
clueLabel.setText(" Too Low");
}
}
catch (NumberFormatException e1) {
clueLabel.setText("Enter a VALID number!");
}
}
}
public static void main(String args[]) {
//instantiate gueesgame object
GuessGame app = new GuessGame();
}
}
However, the color of the window should change into red or blue. Please help me with this code. I'm new in Java and it's syntax. I'd really appreciate your help. Thank you!
You could use:
current = Integer.parseInt(guessTextField.getText().trim());
if (!firstTime) {
if (getUserInput > previous) {
getContentPane().setBackground(Color.red);
} else {
getContentPane().setBackground(Color.blue);
}
}
where firstTime and previous are class member variables.
Don't forget to assign previous if the getUserInput == randomNumber is not met.
Update:
You are setting the background blue twice:
if (getUserInput < randomNumber) {
clueLabel.setText("Too Low");
getContentPane().setBackground(Color.blue); <------ remove this extra call
previous = getUserInput;
}
A code is better than thousand words.....
if (current_Input > previous) {
c.setBackground(Color.red);
} else {
c.setBackground(Color.blue);
}
I am trying to write a program in Java that takes a random number from 1-1000 and then as the guess it the background color changes to blue(cold) or red(warm) if they are in the number. I am new to java GUI, but I think the rest of the logic is right, not sure. It compiles, but the guess button doesn't work. Any guidance will be appreciated.
package guessGame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.color.*;
import java.util.Random;
import java.util.Random;
import java.util.logging.FileHandler;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class GuessGame extends JFrame
{
private JFrame mainFrame;
private JButton GuessButton;
private JButton QuitButton;
private JLabel prompt1, prompt2;
private JTextField userInput;
private JLabel comment = new JLabel("What is your destiny?");
private JLabel comment2 = new JLabel (" ");
//private int number, guessCount;
//private int lastGuess;
private int randomNumber;
private Color background;
public GuessGame()
{
mainFrame = new JFrame ("Guessing Game!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Creates components
GuessButton = new JButton("Guess");
QuitButton = new JButton("Quit");
prompt1 = new JLabel("I have a number between 1 and 1000.");
prompt2 = new JLabel("Can you guess my number? Enter your Guess:");
comment = new JLabel ("What is your destiny?");
comment2 = new JLabel (" ");
userInput = new JTextField(5);
//userInput.addActionListener(new GuessHandler());
//content pane
Container c = mainFrame.getContentPane();
c.setLayout(new FlowLayout());
//adding component to the pane
c.add(prompt1);
c.add(prompt2);
c.add(userInput);
c.add(comment2);
c.add(GuessButton);
c.add(QuitButton);
c.add(comment);
GuessButton.setMnemonic('G');
QuitButton.setMnemonic('Q');
mainFrame.setSize(300,200);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
mainFrame.setResizable(false);
// define and register window event handler
// mainFrame.addWindowListener(new WindowAdapter() {
// public void windowClosing(WindowEvent e)
// { System.exit(0); }
// });
//creating the handler
GuessButtonHandler ghandler = new GuessButtonHandler(); //instantiate new object
GuessButton.addActionListener(ghandler); // add event listener
QuitButtonHandler qhandler = new QuitButtonHandler();
QuitButton.addActionListener(qhandler);
}
public void paint (Graphics g)
{
super.paint(g);
setBackground(background);
}
class QuitButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
class GuessButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
int getUserInput=0;
int diff;
int Difference;
randomNumber = new Random().nextInt(1001);
try {
getUserInput = Integer.parseInt(
userInput.getText().trim());
} catch (NumberFormatException ex){
comment.setText("Enter a VALID number!");
return;
}
if (getUserInput == randomNumber){
JOptionPane.showMessageDialog(null, "CONGRATULATIONS! You got it!!",
"Random Number: " + randomNumber,
JOptionPane.INFORMATION_MESSAGE);
randomNumber = new Random().nextInt(1000) + 1;
return;
}
if (getUserInput > randomNumber){
comment.setText( "Too High. Try a lower number." );
diff=getUserInput - randomNumber;
Difference=Math.abs(diff);
} else {
comment.setText( "Too Low. Try a higher number." );
diff=randomNumber - getUserInput;
Difference=Math.abs(diff);
}
if(Difference<=25){
comment2.setText("Cold");
setBackgroundColor(Color.blue);
}
if(Difference<=10){
comment2.setText("Warm");
setBackgroundColor(Color.red);
}
else {
}
}
private void setBackgroundColor(Color color) {
setBackgroundColor(color);
}
}
public static void main(String args[]) {
//instantiate gueesgame object
GuessGame app = new GuessGame();
}
}
The colors aren't changing because your setBackgroundColor always uses Color.black. Change it to:
private void setBackgroundColor(Color color) {
setBackground(color);
}
As for the number always being zero. You do not instantiate the randomNumber field. Add this to your constructor:
randomNumber = new Random().nextInt(1001);
Another problem I noticed was you added a window listener to ensure the program exits when you close the window. This is implemented in JFrame. In the constructor add:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Instead of using the deprecated method:
mainFrame.show();
use the not deprecated:
mainFrame.setVisible(true);
Furthermore you have a field, which is never queried:
private Color background;
It's best to do the logic before connecting it to the gui. It's a lot easier to test and find the worst bugs.
Refactored code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class GuessGame extends JFrame {
private JTextField userInput;
private JLabel comment = new JLabel("What is your destiny?");
private JLabel comment2 = new JLabel(" ");
private int randomNumber;
public GuessGame() {
super("Guessing Game!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Creates components
JButton guessButton = new JButton("Guess");
JButton quitButton = new JButton("Quit");
JLabel prompt1 = new JLabel("I have a number between 1 and 1000.");
JLabel prompt2 = new JLabel("Can you guess my number? Enter your Guess:");
comment = new JLabel("What is your destiny?");
comment2 = new JLabel(" ");
userInput = new JTextField(5);
//content pane
Container c = getContentPane();
setLayout(new FlowLayout());
//adding component to the pane
c.add(prompt1);
c.add(prompt2);
c.add(userInput);
c.add(comment2);
c.add(guessButton);
c.add(quitButton);
c.add(comment);
guessButton.setMnemonic('G');
quitButton.setMnemonic('Q');
setSize(300, 200);
setLocationRelativeTo(null);
setVisible(true);
setResizable(false);
initializeNumber();
//creating the handler
GuessButtonHandler ghandler = new GuessButtonHandler(); //instantiate new object
guessButton.addActionListener(ghandler); // add event listener
QuitButtonHandler qhandler = new QuitButtonHandler();
quitButton.addActionListener(qhandler);
}
private void initializeNumber() {
randomNumber = new Random().nextInt(1000) + 1;
}
class QuitButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
class GuessButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
int getUserInput;
int diff;
int Difference;
try {
getUserInput = Integer.parseInt(userInput.getText().trim());
if (getUserInput == randomNumber) {
JOptionPane.showMessageDialog(null, "CONGRATULATIONS! You got it!!",
"Random Number: " + randomNumber,
JOptionPane.INFORMATION_MESSAGE);
initializeNumber();
return;
}
if (getUserInput > randomNumber) {
comment.setText("Too High. Try a lower number.");
diff = getUserInput - randomNumber;
Difference = Math.abs(diff);
} else {
comment.setText("Too Low. Try a higher number.");
diff = randomNumber - getUserInput;
Difference = Math.abs(diff);
}
if (Difference <= 25) {
comment2.setText("Cold");
GuessGame.this.setBackgroundColor(Color.blue);
}
if (Difference <= 10) {
comment2.setText("Warm");
GuessGame.this.setBackgroundColor(Color.red);
}
} catch (NumberFormatException ex) {
comment.setText("Enter a VALID number!");
}
}
}
private void setBackgroundColor(Color color) {
getContentPane().setBackground(color);
}
public static void main(String args[]) {
//instantiate gueesgame object
GuessGame app = new GuessGame();
}
}
You have more Swing components than you need, and you seem to be adding one set to the frame while manipulating another set. For example, you have two JTextFields, fieldBox and userInput. You add userInput to the frame, but check fieldBox for input in the Guess button handler. Since fieldBox is always empty, the NumberFormatException is caught by your exception handler (which should really just catch NumberFormatException, not Exception), and comment is updated with "Enter a VALID number!". However, just like with the double text area, comment isn't actually added to the frame, prompt1 and prompt2 are, so you can't see the change
I would write your logic without a UI first and test it until it was 100% correct. Just use a command line, text UI at first. Once that's done, put a GUI in front of it. It'll help to isolate your problems: once the text-driven logic is right, you'll know that future problems are due to UI.
It makes your MVC separation cleaner as well.