I am attempting to make minesweeper. I understand that there is probably a better way to do this but this is how I am trying it.
My problem comes in the gridSquare class. This class is a JLabel and I need the frame that the gridSquare is contained within. I attempt to get the frame with the line minesweeperFrame frame = (minesweeperFrame) SwingUtilities.getWindowAncestor(this);. The problem I run into is that frame is null and never set to the gridSquares Frame. Is there any way to fix this.
Main.java
public class Main {
public static void main(String[] args) {
minesweeperFrame frame = new minesweeperFrame();
}
}
gridSquare.java
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Objects;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.Border;
public class gridSquare extends JLabel implements MouseListener{
Boolean isBomb = false;
int gridNum;
int n1,n2,n3,n4,n6,n7,n8,n9;
int bombNumber;
minesweeperFrame frame = (minesweeperFrame) SwingUtilities.getWindowAncestor(this);
gridSquare(int gridNum){
this.gridNum = gridNum;
n1 = gridNum - 10 - 1; //Top left
n2 = gridNum - 10 ; //Top center
n3 = gridNum - 10 + 1; //Top Left
n4 = gridNum - 1;//center left
n6 = gridNum + 1;//center right
n7 = gridNum + 10 -1;//Bottom Left
n8 = gridNum + 10; //Bottom Center
n9 = gridNum + 10 + 1; //Bottom Right
int neighbors[] = {n1,n2,n3,n4,n6,n7,n8,n9};
try {
//get the bomb number
for(int i:neighbors) {
if(frame.getSquares().get(i).getIsBomb()) { // if any neighbor is a bomb increase bombNumber ---------- frame.getSquares().get(i).getIsBomb()
bombNumber++;
}
System.out.println("WORKS");
}
}
catch(Exception e){
System.out.println(e);
}
setText("");
setHorizontalAlignment(JLabel.CENTER);
setVerticalAlignment(JLabel.CENTER);
setFont(new Font("Copperplate Gothic Bold",Font.PLAIN,20));
setForeground(new Color(0x000000)); //set font color CHANGE FOR EACHER NUMBER
setSize(50,50);
Border border = BorderFactory.createLineBorder(Color.darkGray,5);
setBorder(border);
setBackground(new Color(0xd3d3d3)); //set background color ----- change to #424242 after clicked
setOpaque(true);//display background color
addMouseListener(this);
}
public Boolean getIsBomb() {
return isBomb;
}
public void setIsBomb(Boolean isBomb) {
this.isBomb = isBomb;
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
if(e.getButton() == MouseEvent.BUTTON1) {
setText("Left Click!");
if(isBomb) {
setText("bomb");
}
}
if(e.getButton() == MouseEvent.BUTTON3) {
setText("Flag");
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
mineSeeperFrame.java
import java.awt.GridLayout;
import java.awt.color.*;
import java.util.ArrayList;
import javax.swing.*;
public class minesweeperFrame extends JFrame{
private final int numColumns = 10;
private int numRows = 8;
int numBombs = 0;
ArrayList<gridSquare> squares = new ArrayList<gridSquare>();
minesweeperFrame(){
setTitle("Minesweeper");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000,850);
setResizable(false);
setLayout(new GridLayout(numRows,numColumns,1,1));
setVisible(true);
//Fill Arraylist and add to frame
for(int i = 0; i < 80;i++) {
squares.add(new gridSquare(i));
add(squares.get(i));
}
//AddBombs
while(numBombs < 10) {
squares.get((int) (Math.random()*80)).setIsBomb(true);
numBombs++;
}
}
public ArrayList<gridSquare> getSquares() {
return squares;
}
public int getGridRows() {
return numRows;
}
public int getGridColumns() {
return numColumns;
}
}
You cannot do this during initialization:
minesweeperFrame frame = (minesweeperFrame) SwingUtilities.getWindowAncestor(this);
the component is being created and not added to the frame yet, so you get null.
Moreover you add the gridsquare to the frame directly, this is wrong, you must add it to the contentPane, please read:
https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html
https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html
Related
I am programming a Mario game for my project for my computer science class, and so far the Mario character can run left and right, crouch, and I have built the background.
Two questions that I have are
when making the background move, should I make a separate class that has all the background images? This way I can switch out the various backgrounds I intend to create.
My current program has the issue of when I try and jump (press the up arrow key), Mario does not jump normally, he lags a bit and then rises a lot. I am trying to make it so Mario can rise lets say, one pixel every 100th of a second, but that is not working, instead, it waits around 1 or 2 seconds then rises 100 pixels and stops.
Frame Class:
package FirstPlatformer;
import javax.swing.JFrame;
public class PlatformerFrame
{
public static void main(String[] args)
{
//change to match your values for width/height
//these can be changed
int w = 1525;
int h = 830;
//sets up a JFrame object with title "Template"
JFrame frame = new JFrame("Template");
//make sure the jframe closes when you hit the 'x'
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//adds the drawing panel to the frame
frame.getContentPane().add(new Platformer(w,h));
//resizes the frame to fit the panel
frame.pack();
//makes it visible
frame.setVisible(true);
}
}
Platformer Class:
package FirstPlatformer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
//change to be your packagename
//all imports are necessary
//must 'extend' JPanel
public class Platformer extends JPanel
{
Random test = new Random();
Color aboveground = new Color (99, 158, 169);
private ImageIcon marioStart, ground, mysteryBlock, smallMarioRight, smallMarioLeft, smallMarioCrouchedLeft, smallMarioCrouchedRight;
//variables for the overall width and height
private int w, h;
boolean start = false;
//crouching mechanism
boolean crouchPressed = false;
boolean crouchReleased = false;
boolean youAreCrouching = false;
//facing direction mechanisms
boolean facingRight = true;
boolean facingLeft = false;
//jumping mechanisms
boolean jumpStart = false;
int jumpCountEqual = 0;
private int number = 0;
private int count = 0;
int baseHeight = 770;
int smallMarioGround = 725;
//variable that establishes marios x coord
int marioX = 0;
//sets up the initial panel for drawing with proper size
public Platformer(int w, int h)
{
setFocusable(true);
this.w = w;
this.h = h;
this.setPreferredSize(new Dimension(w,h));
//creating the images
marioStart = new ImageIcon("src/FirstPlatformer/marioStart.JPG");
//building blocks
ground = new ImageIcon("src/FirstPlatformer/ground.JPG");
mysteryBlock = new ImageIcon("src/FirstPlatformer/mysteryBlock.png");
//small mario actions
smallMarioLeft = new ImageIcon("src/FirstPlatformer/smallMarioRight.png");
smallMarioRight = new ImageIcon("src/FirstPlatformer/smallMarioLeft.png");
smallMarioCrouchedLeft = new ImageIcon("src/FirstPlatformer/marioCrouched.png");
smallMarioCrouchedRight= new ImageIcon("src/FirstPlatformer/marioCrouchedRight.png");
this.addMouseListener(new MouseTracker());
this.addKeyListener(new Keyboard());
}
//all graphical components go here
//this.setBackground(Color c) for example will change background color
public void paintComponent(Graphics g)
{
//this line sets up the graphics - always needed
super.paintComponent(g);
g.setColor(Color.RED);
//all drawings below here:
//creating the starting screen
if(start != true) {
setBackground(Color.BLACK);
marioStart.paintIcon(this,g,240,100);
g.setFont(new Font("Arial", Font.BOLD, 50));
g.drawString("Created by Zane Lanski", 515, 625);
g.drawString("Press Space to Start", 525, 725);
}
else {
//setting the overall background for when mario is aboveground
setBackground(aboveground);
//variable for building the bottom of the level
int groundCount = 0;
//for loop creates the base of the level
for(int groundBase = 0; groundBase <30; groundBase++)
{
ground.paintIcon(this, g, groundCount, 770);
groundCount = groundCount + 52;
}
mysteryBlock.paintIcon(this, g, 500, 500);
if(crouchPressed != true && facingRight == true) {
smallMarioRight.paintIcon(this,g,marioX,smallMarioGround);
}
if(crouchPressed != true && facingLeft == true) {
smallMarioLeft.paintIcon(this,g,marioX,smallMarioGround);
}
if(crouchPressed != false) {
smallMarioCrouchedRight.paintIcon(this,g, marioX, smallMarioGround+18);
}
if(jumpStart == true) {
for(int jumpCount = jumpCountEqual;jumpCount < 100; jumpCount++) {
smallMarioGround = smallMarioGround- 1;
// smallMarioRight.paintIcon(this, g, marioX, smallMarioGround);
try
{
Thread.sleep(10);
}
catch(InterruptedException e)
{
System.out.println(e);
}
repaint();
System.out.println(jumpCount);
jumpCountEqual++;
}
}
}
}
private class MouseTracker implements MouseListener, MouseMotionListener
{
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
number++;
count++;
number %= 5;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
private class Keyboard implements KeyListener
{
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
repaint();
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT) {
facingLeft = false;
facingRight = true;
marioX = marioX + 5;
facingRight = true;
facingLeft = false;
}
if(key == KeyEvent.VK_LEFT) {
crouchPressed = false;
marioX = marioX - 5;
facingLeft = true;
facingRight = false;
}
if(key == KeyEvent.VK_DOWN) {
crouchPressed = true;
youAreCrouching = true;
}
if(key == KeyEvent.VK_UP) {
jumpStart = true;
}
if(key == KeyEvent.VK_SPACE) {
start = true;
}
repaint();
}
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if(key == KeyEvent.VK_DOWN) {
crouchPressed = false;
}
repaint();
}
}
}
I am working on program wich is drawing a grid of cells. Each cell has specified color and one of four states:
STARTCELL //marked by yellow color
ENDCELL //marked by red color
EMPTYCELL //marked by white color
BLOCKEDCELL // marked by black color
At the beginning there are one yellow cell, and one red cell and the rest of them is white.
I wanted to be able to change the colors and states of cells by clicking on them and after some research I found the solution:
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
for (Cell item : gridCells) {
if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
item.setCellColor(mouseColor);
if(mouseColor==startCellColor){
item.setCellState(CellState.STARTCELL);
}else if(mouseColor==endCellColor){
item.setCellState(CellState.ENDCELL);
}else{
item.setCellState(CellState.BLOCKEDCELL);
}
}
}
repaint();
}
The only problem is there should be only one STARTCELL
and one ENDCELLat the time and I can't find a way to properly change states of non clicked cells.
I tried many times and ended up with this:
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
for (Cell item : gridCells) {
if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
item.setCellColor(mouseColor);
if(mouseColor==startCellColor){
gridCells.get(numberOfStartCell-1).setCellColor(cellColor);
gridCells.get(numberOfStartCell-1).setCellState(CellState.EMPTYCELL);
numberOfStartCell=item.getNumberOfCell();
item.setCellState(CellState.STARTCELL);
}else if(mouseColor==endCellColor){
item.setCellState(CellState.ENDCELL);
}else{
item.setCellState(CellState.BLOCKEDCELL);
}
areaTest.setText(Integer.toString(numberOfStartCell));
}
}
repaint();
}
Unfortunately it doesn't work correctly. After the first click the color of the new cell changes to yellow the old one became white, and value of variable numberOfStartCell also changes. But after the second click and so on the only part wich changes is numberOfStartCell.
Here is MCV:
Nothing to explain in first two classes i guess.
Class Main
import java.awt.EventQueue;
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MyFrame();
}
});
}
}
Class MyFrame
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class MyFrame extends JFrame {
int width = 750;
int height = 750;
MyPanel panel;
public MyFrame() {
super("Przeszukiwanie");
setSize(width,height);
setResizable(false);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double screenWidth = screenSize.getWidth();
double ScreenHeight = screenSize.getHeight();
int x = ((int)screenWidth-width)/2;
int y = ((int)ScreenHeight-height)/2;
setLocation(x,y);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
panel=new MyPanel();
add(panel);
pack();
}
}
Class MyPanel takes care of event handling and GUI.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
public class MyPanel extends JPanel implements ActionListener{
private JButton createButton;
private ButtonGroup cellColorGroup;
private JRadioButton startingNode;
private JRadioButton endingNode;
private JRadioButton obstacleNode;
private JTextField rows;
private JTextField columns;
private JLabel labelRows;
private JLabel labelColumns;
private String strRowsField;
private String strColumnsField;
private JPanel panelButtons;
private GridPanel panelGrid;
private JPanel panelSettings;
public MyPanel(){
setPreferredSize(new Dimension(700, 600));
setLayout(new BorderLayout());
strRowsField="10";
strColumnsField="10";
panelButtons=new JPanel();
panelSettings=new JPanel();
panelGrid=new GridPanel(Integer.parseInt(strColumnsField),Integer.parseInt(strRowsField));
panelSettings.setLayout(new GridLayout(6,2));
createButton= new JButton("Create");
cellColorGroup=new ButtonGroup();
startingNode=new JRadioButton("Strating Node");
endingNode=new JRadioButton("Ending Node");
obstacleNode=new JRadioButton("Remove/Add Obstacle", true);
cellColorGroup.add(startingNode);
cellColorGroup.add(endingNode);
cellColorGroup.add(obstacleNode);
createButton.addActionListener(this);
startingNode.addActionListener(this);
endingNode.addActionListener(this);
obstacleNode.addActionListener(this);
columns=new JTextField(strColumnsField,2);
rows=new JTextField(strRowsField,2);
labelRows=new JLabel("Number of rows");
labelColumns= new JLabel("Number of columns");
panelButtons.add(createButton);
panelSettings.add(labelColumns);
panelSettings.add(columns);
panelSettings.add(labelRows);
panelSettings.add(rows);
panelSettings.add(startingNode);
panelSettings.add(endingNode);
panelSettings.add(obstacleNode);
add(panelButtons,BorderLayout.SOUTH);
add(panelGrid,BorderLayout.WEST);
add(panelSettings,BorderLayout.EAST);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == createButton) {
panelGrid.setcNodes(Integer.parseInt(columns.getText()));
panelGrid.setrNodes(Integer.parseInt(rows.getText()));
panelGrid.getGridCells().clear();
panelGrid.repaint();
}else if(e.getSource() == startingNode){
panelGrid.setMouseColor(panelGrid.getStartCellColor());
}else if(e.getSource() == endingNode){
panelGrid.setMouseColor(panelGrid.getEndCellColor());
}else if(e.getSource() == obstacleNode){
panelGrid.setMouseColor(panelGrid.getObstacleCellColor());
}
}
}
Class GridPanel takes care of drawing nodes, edges and cells.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JPanel;
public class GridPanel extends JPanel implements MouseListener, MouseMotionListener {
private int cNodes;//Number of nodes across
private int rNodes;//Number of nodes along
private int nodeX;//X coordinate of the first node
private int nodeY;//Y coordinate of the first node
private int width=330;
private int height=330;
private int circleX;//Center of circle X
private int circleY;//Center of circle Y
private Color cellColor;
private Color startCellColor;
private Color endCellColor;
private Color obstacleCellColor;
private Color mouseColor;
private int numberOfStartCell;
private ArrayList<Cell> gridCells;
public GridPanel(int cNodes, int rNodes){
setPreferredSize(new Dimension(width,height));
this.cNodes=cNodes;
this.rNodes=rNodes;
if(cNodes>rNodes){
nodeX=width/(cNodes+1);//Calculation of the x coordinate value of the first node
nodeY=height/(cNodes+1);//Calculation of the y coordinate value of the first node
}else{
nodeX=width/(rNodes+1);
nodeY=height/(rNodes+1);
}
circleX=nodeX;
circleY=nodeY;
cellColor=Color.WHITE;
startCellColor=Color.YELLOW;
endCellColor=Color.RED;
obstacleCellColor=Color.BLACK;
gridCells=new ArrayList<Cell>();
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
drawCells(g2d);
}
public void drawCells(Graphics2D g2d){
int number=0;
int c=0;
for(int i=0; i<rNodes; i++){
for(int j=0; j<cNodes; j++){
number++;
if(i==0 && j==cNodes-1){
gridCells.add(new Cell(circleX,circleY,nodeX,endCellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.ENDCELL,number));
}
else if(i==rNodes-1 && j==0){
gridCells.add(new Cell(circleX,circleY,nodeX,startCellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.STARTCELL,number));
numberOfStartCell=number;
}
else {
gridCells.add(new Cell(circleX,circleY,nodeX,cellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.EMPTYCELL,number));
}
g2d.setPaint(gridCells.get(c).getCellColor());
g2d.fill(gridCells.get(c).getCellShape());
g2d.setPaint(Color.BLACK);
g2d.draw(gridCells.get(c).getCellShape());
if(j<(cNodes-1)){
circleX+=nodeX;
}
c++;
}
circleX=nodeX;
if(i<(rNodes-1)){
circleY+=nodeY;
}
}
circleX=nodeX;
circleY=nodeY;
}
public void setMouseColor(Color mouseColor) {
this.mouseColor = mouseColor;
}
public void setcNodes(int cNodes) {
this.cNodes = cNodes;
}
public void setrNodes(int rNodes) {
this.rNodes = rNodes;
}
public Color getObstacleCellColor() {
return obstacleCellColor;
}
public Color getStartCellColor() {
return startCellColor;
}
public Color getEndCellColor() {
return endCellColor;
}
public ArrayList<Cell> getGridCells() {
return gridCells;
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
for (Cell item : gridCells) {
if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
item.setCellColor(mouseColor);
if(mouseColor==startCellColor){
gridCells.get(numberOfStartCell-1).setCellColor(cellColor);
gridCells.get(numberOfStartCell-1).setCellState(CellState.EMPTYCELL);
numberOfStartCell=item.getNumberOfCell();
item.setCellState(CellState.STARTCELL);
}else if(mouseColor==endCellColor){
item.setCellState(CellState.ENDCELL);
}else{
item.setCellState(CellState.BLOCKEDCELL);
}
}
}
repaint();
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
Class Cell has information about cells (state, color, number..).
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
public class Cell implements Shape{
private int centerX;
private int centerY;
private double side;
private Color cellColor;
private double x;
private double y;
private Shape cellShape;
private CellState cellState;
private int numberOfCell;
public Cell(int centerX, int centerY, int side, Color cellColor,Shape cellShape, CellState cellState,int numberOfCell){
super();
this.centerX=centerX;
this.centerY=centerY;
this.side=side;
this.cellColor=cellColor;
this.cellShape=cellShape;
this.cellState=cellState;
this.numberOfCell=numberOfCell;
}
public Shape getCellShape() {
return cellShape;
}
public int getNumberOfCell() {
return numberOfCell;
}
public Color getCellColor() {
return cellColor;
}
public void setCellColor(Color cellColor) {
this.cellColor = cellColor;
}
public void setCellShape(Shape cellShape) {
this.cellShape = cellShape;
}
public double getSide() {
return side;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public CellState getCellState() {
return cellState;
}
public void setCellState(CellState cellState) {
this.cellState = cellState;
}
#Override
public boolean contains(Point2D p) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean contains(Rectangle2D r) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean contains(double x, double y) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean contains(double x, double y, double w, double h) {
// TODO Auto-generated method stub
return false;
}
#Override
public Rectangle getBounds() {
// TODO Auto-generated method stub
return null;
}
#Override
public Rectangle2D getBounds2D() {
// TODO Auto-generated method stub
return null;
}
#Override
public PathIterator getPathIterator(AffineTransform at) {
// TODO Auto-generated method stub
return null;
}
#Override
public PathIterator getPathIterator(AffineTransform at, double flatness) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean intersects(Rectangle2D r) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean intersects(double x, double y, double w, double h) {
// TODO Auto-generated method stub
return false;
}
}
Class CellState
public enum CellState {
STARTCELL,ENDCELL,EMPTYCELL,BLOCKEDCELL;
}
I can't give a chapter and verse answer, not without your MCVE, but I can give you a large suggestion. Note that selecting empty and and blocked cells is logically a very different thing from selecting starting and ending cells, and so your code should do these things in very different ways. What I would do, is in the mouse listener, check which button is pressed. If the left button (the standard button), toggle the cells blocked / empty state (but only if it's not already a start or end cell). If the right mouse button is pressed (or alt-mouse if there is no mouse button), then display a pop-up menu to allow the user to select the cell as the start or end cell. The code for selecting start or end would be separate from the empty/block toggle code, would first iterate through the model, clearing the former start or end cell, and then setting it.
If you want a better more complete solution, again, please post your valid Minimal, Complete, and Verifiable example code here with your question (not in a link).
Luck.
I am trying to write a 2d graphical game. In this game I have keyboard inputs to move a square block on a black plane. I order to ensure smooth key motions I want to use Buffered key input. In order to do this I use a boolean array that saves the key strokes.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame{
/**
* #param args
*/
class Entity
{
int x = 150,y = 150;
int Speed = 5;
}
Entity user = new Entity();
boolean[] keys = new boolean[KeyEvent.KEY_TYPED];
public Main()
{
setSize(800,600);
setLocationRelativeTo(null);
final JPanel display = new JPanel()
{
protected void paintComponent(Graphics g)
{
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
g.fillRect(user.x, user.y, 30, 30);
}
};
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent arg0)
{
keys[arg0.getKeyCode()] = true;
if(keys[KeyEvent.VK_UP])
{
user.y -= user.Speed;
}
if(keys[KeyEvent.VK_DOWN])
{
user.y += user.Speed;
}
if(keys[KeyEvent.VK_LEFT])
{
user.x -= user.Speed;
}
if(keys[KeyEvent.VK_RIGHT])
{
user.x += user.Speed;
}
setFocusable(true);
repaint();
}
});
//add a action listener
//remember to set the focusable
add(display);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t = new Thread();
try {
t.sleep(100);
Main m = new Main();
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In this input the block moves in the correct direction but just twice, then It moves in a different motion and it even Stops moving.
I have searched in all my Java books that I have and it does not help much. How can I get this error fixed?
Make the boolean[] keys a local variable so that it does not contain previously pressed keys, which will impact the x,y coordinates.
public void keyPressed(KeyEvent arg0)
{
boolean[] keys = new boolean[KeyEvent.KEY_TYPED];
keys[arg0.getKeyCode()] = true;
if(keys[KeyEvent.VK_UP])
{
user.y -= user.Speed;
}
else if(keys[KeyEvent.VK_DOWN])
{
user.y += user.Speed;
}
else if(keys[KeyEvent.VK_LEFT])
{
user.x -= user.Speed;
}
else if(keys[KeyEvent.VK_RIGHT])
{
user.x += user.Speed;
}
setFocusable(true);
repaint();
}
If you just want to clear the keys
public void keyPressed(KeyEvent arg0)
{
keys = new boolean[KeyEvent.KEY_TYPED];
keys[arg0.getKeyCode()] = true;
/* Rest of code */
I am having problems, I want a square (fly) to be drawn and redrawn to show movement. Fine in this code when the button is pressed the fly does "move", but the old squares do not delete. I have tried enviromentPanel.repaint() updateui() and removeall() and I cannot get it to work, if I use any of them then none of the shapes appear and I get a blank screen.
import java.util.Random;
public class Fly implements Runnable{
private int xPosition;
private int yPosition;
private boolean eaten;
public Fly(){
Random randomGenerator = new Random();
xPosition = randomGenerator.nextInt(690) + 10;
yPosition = randomGenerator.nextInt(690) + 10;
eaten = false;
}
public int getxPosition() {
return xPosition;
}
public void setxPosition(int xPosition) {
this.xPosition = xPosition;
}
public int getyPosition() {
return yPosition;
}
public void setyPosition(int yPosition) {
this.yPosition = yPosition;
}
public boolean isEaten() {
return eaten;
}
public void setEaten(boolean eaten) {
this.eaten = eaten;
}
public void move(){
Random randomGenerator = new Random();
int xChange = -10 + randomGenerator.nextInt(20);
int yChange = -10 + randomGenerator.nextInt(20);
xPosition = xPosition + xChange;
yPosition = yPosition + yChange;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
move();
}
#Override
public String toString() {
return "Fly [xPosition=" + xPosition + ", yPosition=" + yPosition
+ ", eaten=" + eaten + "]";
}
#Override
public void run() {
move();
}
}
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.*;
import javax.imageio.ImageIO;
public class Enviroment2 implements Runnable,ActionListener{
private JFrame frame;
private JPanel enviromentPanel,totalGUI,enviromentButtonPanel;
private JButton newFrogButton, resetButton, hungryButton;
private JTextField enterName;
private JLabel hungryLabel;
private ArrayList<Frog> frogs;
private ArrayList<Fly> flys;
public Enviroment2(){
totalGUI = new JPanel();
flys = new ArrayList<Fly>();
frogs = new ArrayList<Frog>();
enviromentPanel = new JPanel();
enviromentButtonPanel = new JPanel();
newFrogButton = new JButton("New Frog");
enterName = new JTextField("Enter name");
hungryButton = new JButton("Hungry!");
resetButton = new JButton("Reset");
frame = new JFrame("[=] Hungry Cyber Pet [=]");
JFrame.setDefaultLookAndFeelDecorated(true);
frame.setContentPane(runEnviroment());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(740, 800);
frame.setVisible(true);
}
public JPanel runEnviroment(){
totalGUI.setLayout(null);
enviromentPanel.setLayout(null);
enviromentPanel.setLocation(10, 10);
enviromentPanel.setSize(700, 700);
enviromentPanel.setBackground(Color.WHITE);
totalGUI.add(enviromentPanel);
FlowLayout experimentLayout = new FlowLayout();
enviromentButtonPanel.setLayout(experimentLayout);
enviromentButtonPanel.setLocation(10, 710);
enviromentButtonPanel.setSize(700, 50);
totalGUI.add(enviromentButtonPanel);
newFrogButton.setLocation(0, 0);
newFrogButton.setSize(120, 30);
newFrogButton.addActionListener(this);
enviromentButtonPanel.add(newFrogButton);
enterName.setLocation(140,0);
enterName.setSize(120,30);
enviromentButtonPanel.add(enterName);
hungryButton.setLocation(280, 0);
hungryButton.setSize(120, 30);
hungryButton.addActionListener(this);
enviromentButtonPanel.add(hungryButton);
resetButton.setLocation(420, 0);
resetButton.setSize(120, 30);
resetButton.addActionListener(this);
enviromentButtonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
public void draw(){
Graphics paper = enviromentPanel.getGraphics();
for (int i = 0; i <= flys.size()-1; i++){
System.out.println("hi");
paper.setColor(Color.BLACK);
paper.fillRect(flys.get(i).getxPosition(), flys.get(i).getyPosition(), 10, 10);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
draw();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == newFrogButton){
Frog frog = new Frog(enterName.getText());
frogs.add(frog);
Fly fly = new Fly();
Thread t = new Thread(fly);
t.start();
flys.add(fly);
showFlys();
}
else if(e.getSource() == hungryButton){
}
else if(e.getSource() == resetButton){
frogs.clear();
flys.clear();
System.out.println(frogs);
System.out.println(flys);
}
}
public void showFlys(){
for (int i = 0; i <= flys.size()-1; i++){
System.out.println(flys.get(i));
}
}
#Override
public void run() {
draw();
}
}
This Graphics paper = enviromentPanel.getGraphics() is the start of your problems, this is not how custom painting is done.
getGraphics returns the graphics context that was used in the last paint cycle, at best it's a snap shot, at worst it can be null.
You should never maintain a reference to any Graphics context you didn't create. They can change and painting on it out of turn can produce unexpected results.
Instead, you should override the paintComponent method (probably in environmentPanel) and do all your custom painting in it.
Your second problem is your violating the thread rules of Swing - you should never create or modify any UI component in any thread other then the EDT
You might like to take a read through
Performing Custom Painting
Painting in AWT and Swing
Concurrency in Swing
I am trying to get this program to show two pictures and check if they are the same picture, i am having trouble getting bildeSjekk() to do this, it shows all pictures and if you double click a picture it removes it, first i need to store the previous instance of the int i, then when teller should become two when two pictures have been revealed, and then i will use current int i and int temp in the int array index and check if the value is the same. It's a Picture memory game.
package prosjekt_1139;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Hukommelse extends JPanel implements MouseListener, ActionListener{
//private JLabel[] kort = new JLabel[16];
private JButton nyOmgang = new JButton("Del ut kortene");
private JButton tilbake = new JButton("Tilbake");
private HovedVinduet vindu;
private int[] index = new int[16];
private int teller =0, temp = 0;
private Image img;
private Image[] imgarray;
private Rectangle[] bokser;
private Point point1;
private URL path1, path2[]= new URL[8];
private boolean sjekk[] = new boolean[16];
public Hukommelse(HovedVinduet vindu) throws IOException{
this.vindu = vindu;
bokser = new Rectangle[16];
imgarray = new Image[8];
point1 = new Point();
img = null;
setBackground(Color.GREEN);
setPreferredSize(new Dimension(720,690));
setLocation(0,0);
nyOmgang.addActionListener(this);
tilbake.addActionListener(this);
add(nyOmgang);
add(tilbake);
this.addMouseListener(this);
boks();
}
// this is my randomisere metode
public void kortIndex(){
int temp;
for (int i = 0;i<index.length;i++){
index[i] = i/2;
//System.out.println(index[i]);
}
for (int i=0;i<1000;i++){
int index1 = (int)(Math.random()*16);
int index2 = (int)(Math.random()*16);
temp = index[index1];
index[index1] = index[index2];
index[index2] = temp;
}
// for (int i = 0; i<index.length;i++)
// System.out.print(index[i]+"\t");
// System.out.println();
}
public void paintComponent(Graphics g){
super.paintComponents(g);
g.setColor(Color.green);
int j = 0;
int k = 0;
for (int i = 0; i<16;i++){
g.drawImage(img, 20+(k*175), 50+(j*160), 150, 150, this);
k++;
if(i == 3 || i == 7 || i == 11 || i == 15){
j++;
k = 0;
}
}
for (int i=0; i<bokser.length; i++) {
if(sjekk[i]){
g.drawImage(imgarray[index[i]], bokser[i].x, bokser[i].y, bokser[i].width, bokser[i].height, this);
}
}
}
//Metode For checking if the image is clicked on
public void bildeSjekk(){
for (int i = 0;i<bokser.length;i++){
if(bokser[i].contains(point1)){
sjekk[i] = true;
teller++;
temp = i;
}
if(teller >= 2 ){
sjekk[i] = false;
sjekk[temp] = false;
teller = 0;
}
}
}
public void boks(){
int j = 0;
int k = 0;
for(int i = 0; i <bokser.length; i++){
bokser[i] = new Rectangle(20+(j*175), 50+(k*160), 150, 150);
j++;
if(i == 3 || i == 7 || i == 11 || i == 15){
j =0;
k++;
}
}
}
public void bilder() throws IOException{
img = ImageIO.read(new File("Image/grass.jpg"));
//repaint();
imgarray[0] = ImageIO.read(new File("Image/bekk.jpg"));
imgarray[1] = ImageIO.read(new File("Image/solnedgang.jpg"));
imgarray[2] = ImageIO.read(new File("Image/tåge.jpg"));
imgarray[3] = ImageIO.read(new File("Image/vile.jpg"));
imgarray[4] = ImageIO.read(new File("Image/fuglekasse.jpg"));
imgarray[5] = ImageIO.read(new File("Image/gullfugl.jpg"));
imgarray[6] = ImageIO.read(new File("Image/byen.jpg"));
imgarray[7] = ImageIO.read(new File("Image/bekk.jpg"));
}
#Override
public void mouseClicked(MouseEvent agr0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println(e.getX()+"\t"+e.getY());
point1 = e.getPoint();
bildeSjekk();
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Del ut kortene")){
try {
bilder();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
point1 = new Point(0,0);
for (int i = 0;i<bokser.length;i++){
sjekk[i] = false;
}
teller = 0;
kortIndex();
repaint();
}
if(e.getSource() == tilbake){
vindu.setMenyPanelAktivt();
vindu.setSize(800, 600);
vindu.setLocation(0,0);
}
}
}
You might like this related memory game that uses JToggleBUtton and Unicode glyphs instead of pictures.
Addendum: As an aside, you may get more helpful answers if you prepare an sscce that doesn't depend on a large number of inaccessible images. As an example, RotatableImage is a simple, static class that can be adapted as required.