Related
So I'm new at java and need some help with my breakout game. My JFrame is just blank and i don't know how to fix it?
So I have a ball class, paddle class, canvas class and a brick class as well as a main class. In my canvas class I set all functions the ball, paddle and bricks has etc. In brick class I draw the bricks. And in my main I do the JFrame but it's blank
Main class :
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame();
Canvas c = new Canvas();
frame.add(c);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I expect the JFrame to show the game instead of just blank window
package breakout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.KeyEvent;
import breakout.Bricks.Type;
public class Canvas extends JPanel implements ActionListener, MouseMotionListener, MouseListener, KeyListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int HEIGHT = 600;
public static final int WIDTH = 720;
private int horizontalCount;
private BufferedImage image;
private Graphics2D bufferedGraphics;
private Timer time;
private static final Font endFont = new Font(Font.SANS_SERIF, Font.BOLD, 20);
private static final Font scoreFont = new Font(Font.SANS_SERIF, Font.BOLD, 15);
private Paddle player;
private Ball ball;
ArrayList<ArrayList<Bricks>> bricks;
public Canvas() {
super();
setPreferredSize( new Dimension(WIDTH, HEIGHT));
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
bufferedGraphics = image.createGraphics();
time = new Timer (15, this);
player = new Paddle((WIDTH/2)-(Paddle.PADDLE_WIDTH/2));
ball = new Ball (((player.getX() + (Paddle.PADDLE_WIDTH / 2 )) - (Ball.DIAMETER / 2)), (Paddle.Y_POS - (Ball.DIAMETER + 10 )), -5, -5);
bricks = new ArrayList<ArrayList<Bricks>>();
horizontalCount = WIDTH / Bricks.BRICK_WIDTH;
for(int i = 0; i < 8; ++i) {
ArrayList<Bricks> temp = new ArrayList<Bricks>();
#SuppressWarnings("unused")
Type rowColor = null;
switch(i) {
case 0 :
case 2:
rowColor = Type.LOW;
break;
case 1 :
case 3 :
case 5 :
rowColor = Type.MEDIUM;
break;
case 4 :
case 6 :
rowColor = Type.HIGH;
break;
case 7 :
default :
rowColor = Type.ULTRA;
break;
}
for(int j = 0; j < horizontalCount; ++j) {
Bricks tempBrick = new Bricks();
temp.add(tempBrick);
}
bricks.add(temp);
addMouseMotionListener(this);
addMouseListener(this);
addKeyListener(this);
requestFocus();
}
}
public void actionPerformed(ActionEvent e) {
checkCollisions();
ball.Move();
for(int i = 0; i < bricks.size(); ++i) {
ArrayList<Bricks> al = bricks.get(i);
for(int j = 0; j < al.size(); ++j) {
Bricks b = al.get(j);
if(b.dead()) {
al.remove(b);
}
}
}
repaint();
}
private void checkCollisions() {
if(player.hitPaddle(ball)) {
ball.setDY(ball.getDY() * -1);
return;
}
if(ball.getX() >= (WIDTH - Ball.DIAMETER) || ball.getX() <= 0) {
ball.setDX(ball.getDX() * -1);
}
if(ball.getY() > (Paddle.Y_POS + Paddle.PADDLE_HEIGHT + 10)) {
resetBall();
}
if(ball.getY() <= 0) {
ball.setDY(ball.getDY() * -1);
}
int brickRowActive = 0;
for(ArrayList<Bricks> alb : bricks) {
if(alb.size() == horizontalCount) {
++brickRowActive;
}
}
for(int i = (brickRowActive==0) ? 0 : (brickRowActive - 1); i < bricks.size(); ++i) {
for(Bricks b : bricks.get(i)) {
if(b.hitBy(ball)) {
player.setScore(player.getScore() + b.getBrickType().getPoints());
b.decrementType();
}
}
}
}
private void resetBall() {
if(gameOver()) {
time.stop();
return;
}
ball.setX(WIDTH/2);
ball.setDY((HEIGHT/2) + 80);
player.setLives(player.getLives() -1);
player.setScore(player.getScore() <= 1);
}
private boolean gameOver() {
if(player.getLives() <= 1) {
return true;
}
return false;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
bufferedGraphics.clearRect(0, 0, WIDTH, HEIGHT);
player.drawPaddle(bufferedGraphics);
player.drawBall(bufferedGraphics);
for(ArrayList<Bricks> row : bricks) {
for(Bricks b : row) {
b.drawBrick(bufferedGraphics);
}
}
bufferedGraphics.setFont(scoreFont);
bufferedGraphics.drawString("Score: " + player.getScore(), 10, 25);
if(gameOver() && ball.getY() >= HEIGHT) {
bufferedGraphics.setColor(Color.black);
bufferedGraphics.setFont(endFont);
bufferedGraphics.drawString("Game Over Score: " + player.getScore(), (WIDTH /2) -85, (HEIGHT/2));
}
if(empty()) {
bufferedGraphics.setColor(Color.black);
bufferedGraphics.setFont(endFont);
bufferedGraphics.drawString("You won. Score: " + player.getScore(), (WIDTH /2) -85, (HEIGHT /2));
time.stop();
}
g.drawImage(image, 0, 0, this);
Toolkit.getDefaultToolkit().sync();
}
private boolean empty() {
for(ArrayList<Bricks> al : bricks) {
if(al.size() != 0) {
return false;
}
}
return true;
}
#Override
public void mouseMoved(MouseEvent e) {
player.setX(e.getX() - (Paddle.PADDLE_WIDTH / 2));
}
#Override
public void mouseClicked(MouseEvent e) {
if(time.isRunning()) {
return;
}
time.start();
}
#Override
public void mouseDragged(MouseEvent e) { }
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
#Override
public void keyPressed(KeyEvent arg0) {}
#Override
public void keyReleased(KeyEvent arg0) {}
#Override
public void keyTyped(KeyEvent arg0) {}
}
Preparing an MCVE, as required in SO, not only it makes helping much easier.
In many case, while preparing one, you are likely to find the problem, so it is a good debugging tool.
To answer "why is my JFrame blank ?" you could create the minimal code example like the following (copy-paste the entire code into GameBoard.java and run):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GameBoard extends JPanel {
static final int HEIGHT = 600, WIDTH = 720, BRICK_ROWS = 8;
private final int horizontalCount;
private static final Font scoreFont = new Font(Font.SANS_SERIF, Font.BOLD, 15);
private final Paddle player;
private final Ball ball;
ArrayList<ArrayList<Brick>> bricks;
public GameBoard() {
super();
setPreferredSize( new Dimension(WIDTH, HEIGHT));
player = new Paddle(WIDTH/2-Paddle.PADDLE_WIDTH/2);
ball = new Ball (player.getX() + Paddle.PADDLE_WIDTH / 2 - Ball.DIAMETER / 2,
Paddle.Y_POS - (Ball.DIAMETER + 10 ));
bricks = new ArrayList<>();
horizontalCount = WIDTH / Brick.BRICK_WIDTH;
for(int i = 0; i < BRICK_ROWS; ++i) {
ArrayList<Brick> temp = new ArrayList<>();
for(int j = 0; j < horizontalCount; ++j) {
Brick tempBrick = new Brick(j*Brick.BRICK_WIDTH , Brick.BRICK_YPOS + i*Brick.BRICK_HEIGHT);
temp.add(tempBrick);
}
bricks.add(temp);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D)g;
g2D.clearRect(0, 0, WIDTH, HEIGHT);
player.drawPaddle(g2D);
ball.drawBall(g2D);
for(ArrayList<Brick> row : bricks) {
for(Brick b : row) {
b.drawBrick(g2D);
}
}
g2D.setFont(scoreFont);
g2D.drawString("Score: " + player.getScore(), 10, 25);
}
}
class Paddle{
public final static int PADDLE_WIDTH = 100, PADDLE_HEIGHT= 30, Y_POS = GameBoard.HEIGHT - 2* PADDLE_HEIGHT;
private int xPos, score;
Paddle(int xPos) {
this.xPos = xPos;
}
void setX(int xPos) {this.xPos = xPos;}
int getX() {return xPos;}
String getScore() {
return String.valueOf(score);
}
void drawPaddle(Graphics2D g2D) {
g2D.setColor(Color.GREEN);
g2D.fillRect(xPos, Y_POS, PADDLE_WIDTH, PADDLE_HEIGHT);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(400,250);
frame.add(new GameBoard());
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
}
class Brick{
final static int BRICK_WIDTH = 80, BRICK_HEIGHT = 15, BRICK_YPOS = 50;
int xPos, yPos;
Brick(int xPos, int yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
void drawBrick(Graphics2D g2D) {
g2D.setColor(Color.RED);
g2D.fillRect(xPos, yPos, BRICK_WIDTH, BRICK_HEIGHT);
g2D.setColor(Color.BLACK);
g2D.drawRect(xPos, yPos, BRICK_WIDTH, BRICK_HEIGHT);
}
}
class Ball{
final static int DIAMETER = 40;
int xPos, yPos;
Ball(int xPos, int yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
void drawBall(Graphics2D g2D) {
g2D.setColor(Color.BLUE);
g2D.fillOval(xPos, yPos, DIAMETER, DIAMETER);
}
}
This produces the following result, which I believe can serve as the basis of what you wanted to achieve:
Now start adding the missing functionality and see what breaks it.
I have made a turtle graphics panel which allows a turtle move from user inputs such as forward <distance>, turnright, turnleft, etc. However, I don't know how to move the turtle as it is stuck at the top left of the screen. Does anyone know what I am doing wrong with the code and could adjust it for me? I want it to be directly in the center with the pen down
Here is a picture of the application so far Turtle Graphics
First class
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* Represents the graphics display panel within the turtle program. This panel contains an image which is updated to reflect user commands.
*
*
*
*/
#SuppressWarnings("serial")
public class GraphicsPanel extends JPanel
{
private JTextField console = new JTextField(15);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
JMenuBar myMenuBar;
JMenu file;
JMenu help;
JMenuItem load;
JMenuItem save;
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Turtle Graphics");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new GraphicsPanel());
f.pack();
f.setVisible(true);
}
/**
* The default BG colour of the image.
*/
private final static Color BACKGROUND_COL = Color.DARK_GRAY;
private final static int TURTLE_X_SIZE = 8, TURTLE_Y_SIZE = 8;
/**
* The underlying image used for drawing. This is required so any previous drawing activity is persistent on the panel.
*/
private BufferedImage image, turtleDisplay;
//djm added
private Color PenColour = Color.RED;
private boolean penDown = false;
private int xPos=0, yPos=0;
private int direction = 180; //robot pointing down the screen;
private JMenuItem newfile;
private JMenuItem exit;
private JMenuItem about;
/**
* Draw a line on the image using the given colour.
*
* #param color
* #param x1
* #param y1
* #param x2
* #param y2
*/
public void drawLine(Color color, int x1, int y1, int x2, int y2)
{
Graphics g = image.getGraphics();
g.setColor(color);
g.drawLine(x1, y1, x2, y2);
}
//djm added commands
public void penDown()
{
penDown = true;
}
public void penUp()
{
penDown = false;
}
public void turnRight()
{
direction +=90;
if (direction >= 360)
direction = 0;
}
public void turnLeft()
{
direction -=90;
if (direction < 0)
direction = 270;
}
public void forward(int distance)
{
//Graphics g = image.getGraphics();
int x=xPos,y=yPos;
//stored xPos and yPos are current location
if (direction == 0) //robot facing up the screen, so forward subtracts y
{
y = yPos-distance;
}
else if (direction == 90) //robot facing right so forward add x
{
x = xPos + distance;
}
else if (direction == 180) //robot facing down the screen, so forwards adds to y
{
y = yPos + distance;
}
else if (direction == 270) //robot facing left, so forwards subtracts from x
{
x = xPos - distance;
}
else
{
System.out.println("strange, shouldn't get here");
}
if (penDown)
{
//x=400; y=400;
drawLine(PenColour, xPos, yPos, x, y);
//g.drawLine(xPos,yPos,x,y);
}
//now robot has moved to the new position
xPos = x;
yPos = y;
}
/**
* Clears the image contents.
*/
public void clear()
{
Graphics g = image.getGraphics();
g.setColor(BACKGROUND_COL);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
}
public void setTurtleColour(Color col)
{
Graphics g = turtleDisplay.getGraphics();
g.setColor(col);
g.fillRect(0, 0, turtleDisplay.getWidth(), turtleDisplay.getHeight()); }
public void green()
{
setTurtleColour(Color.GREEN);
Graphics g = image.getGraphics();
g.setColor(Color.GREEN);
PenColour = Color.GREEN;
}
public void black()
{
setTurtleColour(Color.BLACK);
Graphics g = image.getGraphics();
g.setColor(Color.BLACK);
PenColour = Color.BLACK;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
g.drawImage(turtleDisplay, xPos-TURTLE_X_SIZE/2, yPos-TURTLE_Y_SIZE/2, null);
repaint();
// render the image on the panel.
g.drawImage(image, 0, 0, null);
g.drawImage(turtleDisplay, xPos-TURTLE_X_SIZE/2, yPos-TURTLE_Y_SIZE/2, null); }
/**
* Constructor.
*/
public GraphicsPanel() {
add(console);
console.addActionListener(new ActionListener()
//Command List//
{
public void actionPerformed(ActionEvent arg0)
{
if (console.getText().contains("penup"))
{
penUp();
}
else if (console.getText().contains("pendown"))
{
penDown();
}
else if (console.getText().contains("turnleft"))
{
turnLeft();
}
else if (console.getText().contains("turnright"))
{
turnRight();
}
else if (console.getText().contains("forward"))
{
forward(direction);
}
else if (console.getText().contains("reset"))
{
clear();
}
else if (console.getText().contains("red"))
{
setTurtleColour(PenColour);
}
else if (console.getText().contains("green"))
{
green();
}
else if (console.getText().contains("black"))
{
black();
}
else
{
JOptionPane.showMessageDialog(console, "Invalid command, try again");
}
console.setText("");
}
});
myMenuBar = new JMenuBar ();
file = new JMenu ("File");
help = new JMenu("Help");
load = new JMenuItem("Load");
save = new JMenuItem("Save");
newfile = new JMenuItem("New");
exit = new JMenuItem("Exit");
about = new JMenuItem("About");
file.add(load);
file.add(save);
file.add(newfile);
file.add(exit);
help.add(about);
myMenuBar.add(file);
myMenuBar.add(help);
add(myMenuBar);
setBorder(BorderFactory.createLineBorder(Color.black));}
public Dimension getPreferredSize() {
return new Dimension(800,400);
}
{
//main drawing area
image = new BufferedImage(800, 400, BufferedImage.TYPE_INT_RGB);
//small image to display on top of drawing area to represent the turtle
turtleDisplay = new BufferedImage(TURTLE_X_SIZE, TURTLE_Y_SIZE, BufferedImage.TYPE_INT_RGB);
//set up turtle
setTurtleColour(PenColour);
// Set max size of the panel, so that is matches the max size of the image.
setMaximumSize(new Dimension(image.getWidth(), image.getHeight()));
setSize(800,400);
setVisible(true);
clear();
}
}
Second Class
public class turtleClass {
public static void main(String[] args)
{
turtleClass m = new turtleClass();
m.go();
}
public void go ()
{
GraphicsPanel p = new GraphicsPanel ();
p.turnLeft();
p.forward(100);
p.turnRight();
p.penDown();
p.forward(400);
}
}
I would comment this, but I don't have enough rep points.
I don't see you calling repaint() after any of your methods, so this could be the problem.
~~EDIT~~
I was able to fix your code on my machine but I had to change the entire structure, the repaint() method is the problem, but you have quite a few structural problems as well.
heres an example of how you should structure it, I created 1 extra file that extends JFrame and added your JPanel to it I also deleted your main method in the JPanel class:
this is a rough draw up but I'll let you handle the rest.
public class myFrame extends JFrame{
public GraphicsPanel panel;
public myFrame() {
panel = new GraphicsPanel();
add(panel);
}
public void go ()
{
panel.turnLeft();
panel.forward(100);
panel.turnRight();
panel.penDown();
panel.forward(400);
repaint();
}
}
Original class without main and a few other modifications
/**
* Represents the graphics display panel within the turtle program. This panel contains an image which is updated to reflect user commands.
*
*
*
*/
#SuppressWarnings("serial")
public class GraphicsPanel extends JPanel
{
private JTextField console = new JTextField(15);
JMenuBar myMenuBar;
JMenu file;
JMenu help;
JMenuItem load;
JMenuItem save;
/**
* The default BG colour of the image.
*/
private final static Color BACKGROUND_COL = Color.DARK_GRAY;
private final static int TURTLE_X_SIZE = 8, TURTLE_Y_SIZE = 8;
/**
* The underlying image used for drawing. This is required so any previous drawing activity is persistent on the panel.
*/
private BufferedImage image, turtleDisplay;
//djm added
private Color PenColour = Color.RED;
private boolean penDown = false;
private int xPos=0, yPos=0;
private int direction = 180; //robot pointing down the screen;
private JMenuItem newfile;
private JMenuItem exit;
private JMenuItem about;
/**
* Draw a line on the image using the given colour.
*
* #param color
* #param x1
* #param y1
* #param x2
* #param y2
*/
public void drawLine(Color color, int x1, int y1, int x2, int y2)
{
Graphics g = image.getGraphics();
g.setColor(color);
g.drawLine(x1, y1, x2, y2);
}
//djm added commands
public void penDown()
{
penDown = true;
}
public void penUp()
{
penDown = false;
}
public void turnRight()
{
direction +=90;
if (direction >= 360)
direction = 0;
}
public void turnLeft()
{
direction -=90;
if (direction < 0)
direction = 270;
}
public void forward(int distance)
{
//Graphics g = image.getGraphics();
int x=xPos,y=yPos;
//stored xPos and yPos are current location
if (direction == 0) //robot facing up the screen, so forward subtracts y
{
y = yPos-distance;
}
else if (direction == 90) //robot facing right so forward add x
{
x = xPos + distance;
}
else if (direction == 180) //robot facing down the screen, so forwards adds to y
{
y = yPos + distance;
}
else if (direction == 270) //robot facing left, so forwards subtracts from x
{
x = xPos - distance;
}
else
{
System.out.println("strange, shouldn't get here");
}
if (penDown)
{
//x=400; y=400;
drawLine(PenColour, xPos, yPos, x, y);
//g.drawLine(xPos,yPos,x,y);
}
//now robot has moved to the new position
xPos = x;
yPos = y;
}
/**
* Clears the image contents.
*/
public void clear()
{
Graphics g = image.getGraphics();
g.setColor(BACKGROUND_COL);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
}
public void setTurtleColour(Color col)
{
Graphics g = turtleDisplay.getGraphics();
g.setColor(col);
g.fillRect(0, 0, turtleDisplay.getWidth(), turtleDisplay.getHeight()); }
public void green()
{
setTurtleColour(Color.GREEN);
Graphics g = image.getGraphics();
g.setColor(Color.GREEN);
PenColour = Color.GREEN;
}
public void black()
{
setTurtleColour(Color.BLACK);
Graphics g = image.getGraphics();
g.setColor(Color.BLACK);
PenColour = Color.BLACK;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
g.drawImage(turtleDisplay, xPos-TURTLE_X_SIZE/2, yPos-TURTLE_Y_SIZE/2, null);
// render the image on the panel.
g.drawImage(image, 0, 0, null);
g.drawImage(turtleDisplay, xPos-TURTLE_X_SIZE/2, yPos-TURTLE_Y_SIZE/2, null); }
/**
* Constructor.
*/
public GraphicsPanel() {
add(console);
console.addActionListener(new ActionListener()
//Command List//
{
public void actionPerformed(ActionEvent arg0)
{
if (console.getText().contains("penup"))
{
penUp();
}
else if (console.getText().contains("pendown"))
{
penDown();
}
else if (console.getText().contains("turnleft"))
{
turnLeft();
}
else if (console.getText().contains("turnright"))
{
turnRight();
}
else if (console.getText().contains("forward"))
{
forward(direction);
}
else if (console.getText().contains("reset"))
{
clear();
}
else if (console.getText().contains("red"))
{
setTurtleColour(PenColour);
}
else if (console.getText().contains("green"))
{
green();
}
else if (console.getText().contains("black"))
{
black();
}
else
{
JOptionPane.showMessageDialog(console, "Invalid command, try again");
}
console.setText("");
}
});
myMenuBar = new JMenuBar ();
file = new JMenu ("File");
help = new JMenu("Help");
load = new JMenuItem("Load");
save = new JMenuItem("Save");
newfile = new JMenuItem("New");
exit = new JMenuItem("Exit");
about = new JMenuItem("About");
file.add(load);
file.add(save);
file.add(newfile);
file.add(exit);
help.add(about);
myMenuBar.add(file);
myMenuBar.add(help);
add(myMenuBar);
setBorder(BorderFactory.createLineBorder(Color.black));}
public Dimension getPreferredSize() {
return new Dimension(800,400);
}
{
//main drawing area
image = new BufferedImage(800, 400, BufferedImage.TYPE_INT_RGB);
//small image to display on top of drawing area to represent the turtle
turtleDisplay = new BufferedImage(TURTLE_X_SIZE, TURTLE_Y_SIZE, BufferedImage.TYPE_INT_RGB);
//set up turtle
setTurtleColour(PenColour);
// Set max size of the panel, so that is matches the max size of the image.
setMaximumSize(new Dimension(image.getWidth(), image.getHeight()));
setSize(800,400);
setVisible(true);
clear();
}
}
Your turtle class
public class turtleClass {
public static void main(String[] args)
{
myFrame m = new myFrame();
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m.pack();
m.setVisible(true);
m.go();
}
}
Whenever you're finished making changes to your graphics buffer, you need to call repaint() to make those changes visible to the user. Even when changing pen color, even though the color won't apply until the next thing we draw, we call repaint() so that the turtle cursor itself displays in the new color. Ditto for clear(), forward() (pen up or down), etc. If your turtle cursor had a non-symmetrical shape (eg. arrow or actual turtle) then even turnLeft() and turnRight() would need to trigger a repaint() to display the new turtle heading.
Along with adding missing calls to repaint(), here's my rework of your code that makes the commands you have operate correctly:
GraphicsPanel.java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.JOptionPane;
import javax.swing.BorderFactory;
import javax.swing.SwingUtilities;
/*
* Represents the graphics display panel within the turtle program. This panel contains an image
* which is updated to reflect user commands.
*/
public class GraphicsPanel extends JPanel
{
private JTextField console = new JTextField(15);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
JMenuBar menuBar;
JMenu file;
JMenu help;
JMenuItem load;
JMenuItem save;
private static void createAndShowGUI() {
JFrame frame = new JFrame("Turtle Graphics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GraphicsPanel());
frame.pack();
frame.setVisible(true);
}
/*
* The default BG colour of the image.
*/
private final static Color BACKGROUND_COL = Color.DARK_GRAY;
private final static int TURTLE_X_SIZE = 8, TURTLE_Y_SIZE = 8;
/*
* The underlying image used for drawing. This is required so
* any previous drawing activity is persistent on the panel.
*/
private BufferedImage image, turtleDisplay;
// djm added
private Color PenColour = Color.RED;
private boolean penDown = true;
private int xPos = 400 - TURTLE_X_SIZE/2, yPos = 200 - TURTLE_Y_SIZE/2;
private int direction = 180; // robot pointing down the screen
private JMenuItem newfile;
private JMenuItem exit;
private JMenuItem about;
private int distance = 100;
/*
* Draw a line on the image using the given colour.
*/
public void drawLine(Color color, int x1, int y1, int x2, int y2)
{
Graphics graphics = image.getGraphics();
graphics.setColor(color);
graphics.drawLine(x1, y1, x2, y2);
}
// djm added commands
public void penDown()
{
penDown = true;
}
public void penUp()
{
penDown = false;
}
public void turnRight()
{
direction += 90;
if (direction >= 360)
{
direction -= 360;
}
}
public void turnLeft()
{
direction -= 90;
if (direction < 0)
{
direction += 360;
}
}
public void forward(int distance)
{
int x = xPos, y = yPos;
// stored xPos and yPos are current location
if (direction == 0) // robot facing up the screen, so forward subtracts y
{
y = yPos - distance;
}
else if (direction == 90) // robot facing right so forward add x
{
x = xPos + distance;
}
else if (direction == 180) // robot facing down the screen, so forwards adds to y
{
y = yPos + distance;
}
else if (direction == 270) // robot facing left, so forwards subtracts from x
{
x = xPos - distance;
}
else
{
System.out.println("strange, shouldn't get here");
}
if (penDown)
{
drawLine(PenColour, xPos, yPos, x, y);
}
// now robot has moved to the new position
xPos = x;
yPos = y;
repaint();
}
/*
* Clear the image contents.
*/
public void clear()
{
Graphics graphics = image.getGraphics();
graphics.setColor(BACKGROUND_COL);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
repaint();
}
public void setColour(Color color)
{
Graphics graphics = turtleDisplay.getGraphics();
graphics.setColor(color);
graphics.fillRect(0, 0, turtleDisplay.getWidth(), turtleDisplay.getHeight());
graphics = image.getGraphics();
graphics.setColor(color);
PenColour = color;
repaint();
}
public void green()
{
setColour(Color.GREEN);
}
public void red()
{
setColour(Color.RED);
}
#Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics.drawImage(image, 0, 0, null);
graphics.drawImage(turtleDisplay, xPos - TURTLE_X_SIZE/2, yPos - TURTLE_Y_SIZE/2, null);
}
/*
* Constructor.
*/
public GraphicsPanel() {
add(console);
console.addActionListener(new ActionListener()
/* Command List */
{
public void actionPerformed(ActionEvent arg0)
{
if (console.getText().contains("penup"))
{
penUp();
}
else if (console.getText().contains("pendown"))
{
penDown();
}
else if (console.getText().contains("turnleft"))
{
turnLeft();
}
else if (console.getText().contains("turnright"))
{
turnRight();
}
else if (console.getText().contains("forward"))
{
forward(distance);
}
else if (console.getText().contains("reset"))
{
clear();
}
else if (console.getText().contains("green"))
{
green();
}
else if (console.getText().contains("red"))
{
red();
}
else
{
JOptionPane.showMessageDialog(console, "Invalid command, try again");
}
console.setText("");
}
}
);
menuBar = new JMenuBar();
file = new JMenu("File");
load = new JMenuItem("Load");
save = new JMenuItem("Save");
newfile = new JMenuItem("New");
exit = new JMenuItem("Exit");
file.add(load);
file.add(save);
file.add(newfile);
file.add(exit);
menuBar.add(file);
help = new JMenu("Help");
about = new JMenuItem("About");
help.add(about);
menuBar.add(help);
add(menuBar);
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize()
{
return new Dimension(800, 400);
}
{
// main drawing area
image = new BufferedImage(800, 400, BufferedImage.TYPE_INT_RGB);
// small image to display on top of drawing area to represent the turtle
turtleDisplay = new BufferedImage(TURTLE_X_SIZE, TURTLE_Y_SIZE, BufferedImage.TYPE_INT_RGB);
// set up turtle
setColour(PenColour);
// Set max size of the panel, so that is matches the max size of the image.
setMaximumSize(new Dimension(image.getWidth(), image.getHeight()));
setSize(800, 400);
setVisible(true);
clear();
}
}
TurtleClass.java
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TurtleClass extends JFrame {
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TurtleClass();
}
});
}
public TurtleClass()
{
JFrame frame = new JFrame("Turtle Graphics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsPanel panel = new GraphicsPanel();
frame.add(panel);
frame.pack();
frame.setVisible(true);
panel.turnLeft();
panel.forward(100);
panel.turnRight();
panel.penDown();
panel.forward(400);
}
}
You can still run this from the TurtleClass or GraphicsPanel as you originally designed:
I would drop the console when invoked as a library like TurtleClass does but keep it when invoked as an application as GraphicsPanel does. It could then be both and output device and an interactive environment depending on need.
I have a JFrame with a subclass, Paint_Panel. Paint_Panel extends JPanel and implements a MouseListener.
I need to place three circles with mouse clicks. No problem. I have a button (Draw) that should draw lines from each circle's center to the other (thus - a triangle). I can maintain the coordinates within an ArrayList - no problem. However, when I try to reference the ArrayList by clicking the button, the list is returned empty. The Array isn't in memory at the time it is needed to draw the lines. Thoughts?
Note- Circles are hard-coded at 40.
Code:
public class Paint_Panel extends JPanel implements MouseListener {
public static int flag = 0;
boolean drawCircles = false;
boolean drawLines = false;
private final ArrayList<Point> points = new ArrayList<>();
public Paint_Panel() {
addMouseListener(this);
}
//Method to draw lines from point to point
public void drawLines() {
Graphics g = getGraphics();
drawLines = true;
paintComponent(g);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (drawCircles) {
for (int i = 0; i < points.size(); i++) {
//Circle number 1
g.setColor(Color.RED);
g.fillOval(points.get(0).x - 20, points.get(0).y - 20, 40, 40);
//Circle number 2
if (points.size() >= 2) {
g.setColor(Color.GREEN);
g.fillOval(points.get(1).x - 20, points.get(1).y - 20, 40, 40);
}
//Circle number 3
if (points.size() >= 3) {
g.setColor(Color.BLUE);
g.fillOval(points.get(2).x - 20, points.get(2).y - 20, 40, 40);
}
}
} else if (drawLines) {
g.setColor(Color.BLACK); //Set line color
g.drawLine(points.get(0).x, points.get(0).y, points.get(1).x, points.get(1).y);
g.drawLine(points.get(1).x, points.get(1).y, points.get(2).x, points.get(2).y);
g.drawLine(points.get(2).x, points.get(2).y, points.get(0).x, points.get(0).y);
}
}
public void mouseClicked(MouseEvent evt) { //Place circles for click event
Graphics g = getGraphics();
if (!drawCircles) {
prevX = evt.getX() - 20; //Allows placement at center. Size - radius
prevY = evt.getY() - 20;
points.add(evt.getPoint()); //Add point to ArrayList
if (flag < 3) { //Keep track of how many circles are placed
flag += 1;
drawCircles = true;
paintComponent(g);
} else if (flag == 3) { //If additional circles attempted, inform user
flag = 4;
System.out.println("Only 3 circles allowed."); //Debug
drawCircles = false;
}
}
drawCircles = false;
}
#Override
public void mousePressed(MouseEvent evt) { //Unused
}
#Override
public void mouseReleased(MouseEvent evt) { //Unused
}
#Override
public void mouseEntered(MouseEvent evt) { //Unused
}
#Override
public void mouseExited(MouseEvent evt) { //Unused
}
}
Here's one way to draw 3 circles and 3 lines. Edited to draw the circles first, then the lines. Edited again to check for an invalid button press.
I separated the view and controller logic.
Here's the runnable code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CirclePaintTest implements Runnable {
private JFrame frame;
private PaintPanel paintPanel;
#Override
public void run() {
frame = new JFrame("Circle Paint Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
paintPanel = new PaintPanel();
mainPanel.add(paintPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
JButton lineButton = new JButton("Draw Lines");
lineButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
if (paintPanel.isComplete()) {
paintPanel.setDrawLines(true);
paintPanel.repaint();
}
}
});
buttonPanel.add(lineButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new CirclePaintTest());
}
public class PaintPanel extends JPanel {
private static final long serialVersionUID = 6481890334304291711L;
private final Color[] colors = { Color.RED, Color.GREEN, Color.BLUE,
Color.ORANGE, Color.CYAN, Color.YELLOW };
private boolean drawLines;
private final int pointLimit;
private final List<Point> points;
public PaintPanel() {
this.points = new ArrayList<Point>();
this.pointLimit = 3;
this.drawLines = false;
this.addMouseListener(new CircleMouseListener());
this.setPreferredSize(new Dimension(400, 400));
}
public void setDrawLines(boolean drawLines) {
this.drawLines = drawLines;
}
public boolean isComplete() {
return points.size() >= pointLimit;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Point pp = null;
Point p0 = null;
for (int i = 0; i < points.size(); i++) {
g.setColor(colors[i]);
Point p = points.get(i);
g.fillOval(p.x - 20, p.y - 20, 40, 40);
pp = p;
}
if (drawLines && (points.size() > 1)) {
p0 = points.get(0);
pp = p0;
g.setColor(Color.BLACK);
for (int i = 1; i < points.size(); i++) {
Point p = points.get(i);
g.drawLine(pp.x, pp.y, p.x, p.y);
pp = p;
}
g.drawLine(pp.x, pp.y, p0.x, p0.y);
}
}
public class CircleMouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent event) {
if (points.size() < pointLimit) {
points.add(event.getPoint());
PaintPanel.this.repaint();
}
}
}
}
}
You don't call repaint when flag equals 3, so there is no call to the paintComponent method with the right condition (drawCircles false and drawLines true).
I suggest you to call repaint either when flag equals to 3 or and the end of mouseClicked.
I want to click on the screen and have the character move to that destination. Not instantly, but rather "walk" to the given coordinate. Currently I'm using JLabels and they're fine if I only use static images, but everytime I click somewhere on the screen the image shows up at that exact point. Could someone give me some tips?
edit: Should I override the paint class and draw some items that way?
Here's some code:
package mod;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.awt.KeyboardFocusManager;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Board2 extends JPanel {
private Thread animator;
int x, y;
double ix, iy;
double dx, dy;
final int frameCount = 8;
BufferedImage flower;
private int[][] fPos = {{232, 15},{400, 200},{335, 335}}; // flower coordinates
private static int bWIDTH = 800; // width of window
private static int bHEIGHT = 600;// height of window
private Font font;
private FontMetrics metrics;
ImageIcon grassI = new ImageIcon(this.getClass().getResource("grass.png"));
ImageIcon riverI = new ImageIcon(this.getClass().getResource("river.png"));
private Image grass = grassI.getImage();
private Image river = riverI.getImage();
private House house = new House();
private River river1 = new River();
//private Flower flower = new Flower();
private TitleScreenLayer ts = new TitleScreenLayer();
private Player girlP = new Player();
private static int px = 250;
private static int py = 250;
private boolean visTl = false;
private boolean plant = false;
ArrayList<Flower> flowers= new ArrayList<Flower>();
private long period;
private volatile boolean running = false;
private volatile boolean gameOver = false;
private volatile boolean isPaused = false;
// New stuff for Board2 below
private JLayeredPane lpane;
private JLabel grassLabel;
private JLabel riverLabel;
private JLabel houseLabel;
private JLabel pear1Label;
private JLabel pear2Label;
private JLabel pear3Label;
private JLabel drivewayLabel;
private JLabel girlLabel;
private JProgressBar progressBar;
private JLabel toolLabel;
private JTextArea textBubble;
ImageIcon girlImage = new ImageIcon(girlP.getImage());
int mouseClicks = 0;
CountdownTimer cTimer;
private static String message;
public static String setMessage(String newMessage){
return message = newMessage;
}
private static ImageIcon playerTool = new ImageIcon("BradfordPear.png");
public ImageIcon getPlayerTool(){
return playerTool;
}
public static void setPlayerTool(String image){
playerTool = new ImageIcon(image);
}
public JTextArea getTextBubble(){
return textBubble;
}
public Player getPlayer(){
return girlP;
}
public static int getPlayerX(){
return px;
}
public static int getPlayerY(){
return py;
}
public JLayeredPane getLayeredPane(){
return lpane;
}
public Board2(){
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
//create the layered pane
lpane = new JLayeredPane();
lpane.setPreferredSize(new Dimension(800, 600));
//create the "background" image
ImageIcon image = new ImageIcon("grass.png");
grassLabel = new JLabel(image);
grassLabel.setBounds(0, 0, image.getIconWidth(), image.getIconHeight());
//create the house image
ImageIcon houseImage = new ImageIcon("house.png");
houseLabel = new JLabel(houseImage);
houseLabel.setBounds(-330, -150, image.getIconWidth(), image.getIconHeight());
//create the driveway image
ImageIcon drivewayImage = new ImageIcon("driveway.png");
drivewayLabel = new JLabel(drivewayImage);
drivewayLabel.setBounds(-335, 105, image.getIconWidth(), image.getIconHeight());
//create the river image
ImageIcon riverImage = new ImageIcon("river.png");
riverLabel = new JLabel(riverImage);
riverLabel.setBounds(360, 0, image.getIconWidth(), image.getIconHeight());
//create pear1 image
ImageIcon pear1Image = new ImageIcon("BradfordPear.png");
pear1Label = new JLabel(pear1Image);
pear1Label.setBounds(100, 100, image.getIconWidth(), image.getIconHeight());
//create pear2 image
ImageIcon pear2Image = new ImageIcon("BradfordPear.png");
pear2Label = new JLabel(pear2Image);
pear2Label.setBounds(50, -100, image.getIconWidth(), image.getIconHeight());
//create pear3 image
ImageIcon pear3Image = new ImageIcon("BradfordPear.png");
pear3Label = new JLabel(pear3Image);
pear3Label.setBounds(-100, -50, image.getIconWidth(), image.getIconHeight());
//create initial Player(girl) image
//ImageIcon girlImage = new ImageIcon(girlP.getImage());
girlLabel = new JLabel(girlImage);
girlLabel.setBounds((int)girlP.getPositionX(), (int)girlP.getPositionY(), image.getIconWidth(), image.getIconHeight());
//create progress bar
progressBar = new JProgressBar(JProgressBar.VERTICAL, 0, 10);
progressBar.setValue(0);
progressBar.setBounds(720, 50, 100, 500);
//create timer
JTextField timerField = new JTextField();
cTimer = new CountdownTimer(timerField);
timerField.setBounds(400, 0, 50, 50);
//create toolbox
Toolbox toolbox = new Toolbox();
toolbox.setBounds(550, 0, 250, 50);
//create the text bubble
textBubble = new JTextArea("IDPC is the best coding group ever");
textBubble.setLineWrap(true);
//textBubble.setBounds(200, 200, 100, 100);
//add the background & various images
lpane.add(grassLabel, new Integer(1));
lpane.add(houseLabel, new Integer(2));
lpane.add(riverLabel, new Integer(2));
lpane.add(drivewayLabel, new Integer(2));
lpane.add(pear1Label, new Integer(2));
lpane.add(pear2Label, new Integer(2));
lpane.add(pear3Label, new Integer(2));
lpane.add(progressBar, new Integer(3));
lpane.add(girlLabel, new Integer(3));
lpane.add(timerField, new Integer(2));
lpane.add(toolbox, new Integer(3));
add(lpane);
cTimer.start();
// listen for action events
new ActionListener() {
public void actionPerformed(ActionEvent e) {
girlP.move();
//girlLabel.setLocation(px, py);
}
};
// listen for mouse presses
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
//lpane.remove(textBubble);
mouseClicks+= 1;
testPress(e.getX(), e.getY());
//textBubble.setBounds(e.getX(), e.getY(), 40, 40);
updateProgressBar();
}
});
//listen for player action
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 2){
ImageIcon flowerImage = playerTool;
JLabel flowerPanel = new JLabel(flowerImage);
flowerPanel.setBounds((px -((int)girlP.getPositionX() / 2)),
(py - ((int)girlP.getPositionY() / 2)),
flowerImage.getIconWidth(),
flowerImage.getIconHeight());
lpane.add(flowerPanel, new Integer(3));
textBubble.setBounds(e.getX(), e.getY(), 200, 40);
textBubble.replaceSelection(message);
lpane.add(textBubble, new Integer(3));
//lpane.remove(textBubble);
}
}
});
x = 15;
y = 150;
ix = 0;
iy = 0;
dx = .05;
dy = .05;
girlP.setDestination(px, py);
}
public void testPress(int x, int y){
px = x;
py = y;
if (px < (ix + house.getImage().getWidth(this))
&& (py < (iy + house.getImage().getHeight(this)))) {
px = px + (house.getImage().getWidth(this)/3);
py = py + (house.getImage().getHeight(this)/3);
}
if (px > (bWIDTH - river1.getImage().getWidth(this))) {
px = px - 80 - (river1.getImage().getWidth(this)/2);
}
girlLabel.setBounds((px -((int)(girlP.getPositionX()*2.5))),
(py - ((int)(girlP.getPositionY()*2.5))),
girlImage.getIconWidth(), girlImage.getIconHeight());
girlP.setDestination((px-(girlP.getImage().getWidth(this)/2)),
(py-(girlP.getImage().getHeight(this)/2)));
girlP.pinned(x, y);
}
public void updateProgressBar(){
if(progressBar.getValue() == 3){
//progressBar.setBackground(Color.red);
//UIManager.put("progressBar.foreground", Color.RED);
UIDefaults defaults = new UIDefaults();
defaults.put("progressBar[Enabled].foregroundPainter", Color.RED);
progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
progressBar.putClientProperty("Nimbus.Overrides", defaults);
}
progressBar.setValue(mouseClicks);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new TitleScreenLayer();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Here's the player class:
package mod;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Player {
int tile;
double positionX;
double positionY;
int destinationX;//Used when moving from place to place
int destinationY;
Tool currentTool;
int direction; //Position the image is facing
double dx;
double dy;
int [] pin = new int[10];
private String girl = "girl.png";
ImageIcon ii = new ImageIcon(this.getClass().getResource(girl)); // load girl image
private Image image = ii.getImage();
private boolean visible = true;
public boolean plant = false;
Image playerImage;
public double getPositionX() {
return positionX;
}
public void setPositionX(double positionX) {
this.positionX = positionX;
}
public double getPositionY() {
return positionY;
}
public void setPositionY(double positionY) {
this.positionY = positionY;
}
public Player(){
positionX=30;
positionY=20;
dx = 0.2;
dy = 0.2;
destinationX=(int)positionX;
destinationY=(int)positionY;
//this.playerImage=playerImage;
}
public void doAction() {
//currentTool.getNum();
plant = true;
}
public void pinned(int x, int y) {
if (plant == true) {
pin[0] = x;
pin[1] = y;
}
//plant = false;
}
public void plant(Graphics g, ImageObserver io) {
int x = pin[0];
int y = pin[1];
if (plant == true) {
// g.drawImage(flower.getImage(), x, y, io);
}
}
public void ActionPerformed(ActionEvent e) {
positionX += dx;
positionY += dy;
}
public boolean isVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public Image getImage() {
return image;
}
public void move(){
//MOVE LEFT AND RIGHT
if(destinationX<positionX){
positionX-=dx;
}
if(destinationX>positionX){
positionX+=dx;
}
//MOVE UP AND DOWN
if(destinationY<positionY){
positionY-=dy;
}
if(destinationY>positionY){
positionY+=dy;
}
}
public double setDx(double speed) {
dx = speed;
return dx;
}
public double setDy(double speed) {
dy = speed;
return dy;
}
public void TileIn(int px, int py)
{
px=destinationX;
py=destinationY;
int tileX=1;
int tileY = 1;
int bWIDTH=800;
int bHEIGHT=600;
if(px >= 0 && px <= 800*.1)
{
tileX=2;
}
else if(px> bWIDTH*.1 && px <= bWIDTH*.2)
{
tileX=3;
}
else if(px > bWIDTH*.2 && px <= bWIDTH*.3)
{
tileX=4;
}
else if(px > bWIDTH*.3 && px <= bWIDTH*.4)
{
tileX=5;
}
else if(px > bWIDTH*.4 && px <= bWIDTH*.5)
{
tileX=6;
}
else if(px > bWIDTH*.5 && px <= bWIDTH*.6)
{
tileX=7;
}
else if(px > bWIDTH*.6 && px <= bWIDTH*.7)
{
tileX=8;
}
else if(px > bWIDTH*.7 && px <= bWIDTH*.8)
{
tileX=9;
}
else if(px > bWIDTH*.8 && px <= bWIDTH*.9)
{
tileX=10;
}
else if(px > bWIDTH*.9 && px <= bWIDTH)
{
tileX=11;
}
if(py >= 0 && py <= bHEIGHT*.1)
{
tileY=2;
}
else if(py> bHEIGHT*.1 && py <= bHEIGHT*.2)
{
tileY=3;
}
else if(py > bHEIGHT*.2 && py <= bHEIGHT*.3)
{
tileY=4;
}
else if(py > bHEIGHT*.3 && py <= bHEIGHT*.4)
{
tileY=5;
}
else if(py > bHEIGHT*.4 && py <= bHEIGHT*.5)
{
tileY=6;
}
else if(py > bHEIGHT*.5 && py <= bHEIGHT*.6)
{
tileY=7;
}
else if(py > bHEIGHT*.6 && py <= bHEIGHT*.7)
{
tileY=8;
}
else if(py > bHEIGHT*.7 && py <= bHEIGHT*.8)
{
tileY=9;
}
else if(py > bHEIGHT*.8 && py <= bHEIGHT*.9)
{
tileY=10;
}
else if(py > bHEIGHT*.9 && py <= bHEIGHT)
{
tileY=11;
}
System.out.println("Grid X: " + tileX + " Grid Y: " + tileY);
}
public void setDestination(int x, int y){
destinationX=x;
destinationY=y;
System.out.println(x + "," + y);
TileIn(x,y);
}
// public void tileIn(int a)
// {
//
// b=destinationY;
// return TileIn(x,y)
// }
public void draw(Graphics g,ImageObserver io){
g.drawImage(image, (int)positionX,(int) positionY,io);
}
}
Here is the main class:
package mod;
import java.awt.Container;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
public class Skeleton2 extends JFrame /*implements WindowListener*/{
private static int DEFAULT_FPS = 80;
private Board2 bd;
public Skeleton2(long period) {
super("Skeleton");
makeGUI(period);
//addWindowListener(this);
pack();
setResizable(false);
setVisible(true);
}
public void makeGUI(long period) {
Container c = getContentPane();
bd = new Board2();
c.add(bd, "Center");
} // end of makeGUI()
//==================================================================================
// Window Events
//==================================================================================
/*
public void windowActivated(WindowEvent e) {
bd.resumeGame();
}
public void windowDeactivated(WindowEvent e) {
bd.pauseGame();
}
public void windowDeiconified(WindowEvent e) {
bd.resumeGame();
}
public void windowIconified(WindowEvent e) {
bd.pauseGame();
}
public void windowClosing(WindowEvent e) {
bd.stopGame();
}
*/
public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
//==================================================================================
public static void main(String[] args) {
int fps = DEFAULT_FPS;
long period = (long) 1000.0/fps;
new Skeleton2(period);
System.out.println("Period: " + period);
}
}
Not instantly, but rather "walk" to the given coordinate.
Then you need to use a Swing Timer. The Timer is used to schedule the animation. So you would need to calculate a path between the two points. Every time the Timer fires you would move the label a few pixels until it reaches it's destination.
There is no need to do custom painting for this. A JLabel will work fine. The hard part is calculating the path you want the character to take. Also make sure you use a null layout on the panel you add the JLabel to, which means you will also need to set the size of the label equal to the preferred size of the label.
You should rather use g.drawImage in your component paintComponent method.
I'm new at using actionListener and mouselistner. I want to track the Mouse movements and connect the dots as I go. So it will be one continuous line. I am using the MouseMotionListener every time I move the mouse across the screen and get a new set of points. I am not using mousePressed or mouseReleased.
Everytime I move the mouse, I can get every point of where my mouse's position is on my JPanel to show up on my results window, but in order to draw the line between two points, I'm not sure how to decipher between each different set of points so I can have a beginning and ending set of points to use for drawing a line? I checked through here and the API and I'm stuck.
I was asked to put more code and so I gave you my code.
I am basically creating a Jpane that tracks mouse movement when the Track Mouse button or Draw Track Radio button is pressed
These results will print out as (x,y) on the output screen
FYI: You can also draw circles once the Draw circles RadioButton is checked
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class MouseTest {
private JFrame frame;
private boolean tracking;
private boolean drawing;
private boolean connectdots;
private int xstart;
private int ystart;
private int xend;
private int y;
private int x;
private int yend;
private int borderWidth = 5;
String drawCircles = "Draw Circles";
String drawTrack = "Draw Track";
public static void main (String [] arg) {
MouseTest first = new MouseTest();
}//main
$
public MouseTest() {
tracking = false;
frame = new JFrame();
frame.setBounds(250,98,600,480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton track = new JButton("Track Mouse");
track.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
trackMouse();
}
});
JPanel top = new JPanel();
top.add(track);
cp.add(top,BorderLayout.NORTH);
MyPanel pane = new MyPanel();
cp.add(pane,BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) { int tmp = xstart; xstart = xend; xend = tmp; }
if (yend < ystart) { int tmp = ystart; ystart = yend; yend = tmp; }
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
JRadioButton circleButton = new JRadioButton(drawCircles);
circleButton.setMnemonic(KeyEvent.VK_B);
circleButton.setActionCommand(drawCircles);
circleButton.setSelected(false);
JRadioButton trackButton = new JRadioButton(drawTrack);
trackButton.setMnemonic(KeyEvent.VK_C);
ButtonGroup group = new ButtonGroup();
group.add(circleButton);
group.add(trackButton);
JPanel radioPanel = new JPanel(new GridLayout(2,0));
radioPanel.add(circleButton);
radioPanel.add(trackButton);
cp.add(radioPanel,BorderLayout.EAST);
drawing = false;
connectdots = false;
circleButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
tracking = !tracking;
drawCircles();
}
});
trackButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
drawing = false;
tracking = true;
connectDots();
}
});
frame.setVisible(true);
}//constructor
$
public void trackMouse() {
tracking = !tracking;
}//trackMouse
public void msg(String s) { //new method to simplify the system.out.print method
System.out.println(s);
}
public void drawCircles() {
drawing = true;
}//Allow Drawing of Circles
public void connectDots() {
connectdots = !connectdots;
}//Trying to use for connecting the mouse motion listener points when tracking
$
public class MyPanel extends JPanel {
ArrayList<Circle> circles = new ArrayList<Circle>();
public void paintComponent(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
msg("H = " + height + ", w = " + width);
g.setColor(Color.BLACK);
Circle c = new Circle(xstart, ystart);
circles.add(c);
if (drawing){
for(int k=0; k<circles.size(); k++){
circles.get(k).draw(g);
}
} // draw the circle
if (connectdots && tracking) { //trying to use for drawing the lines
g.drawLine(x,y,x,y);
}
for (int delta = 0; delta < borderWidth; delta++) {
g.drawRect(delta,delta,width-(2*delta),height-(2*delta));
}
if (xstart != xend || ystart != yend) {
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
msg("Colors are: " + red + " - " + green + " - " + blue );
msg("Drawing from: (" + xstart + ", " + ystart + ") to (" + xend + ", " + yend + ")");
msg("Width is " + (xend-xstart) + " - Height is " + (yend-ystart));
g.fillRect(xstart,ystart,xend-xstart,yend-ystart);
}
}
}
}
$
public class Circle {
// instance variables:
int radius; //random radius
int x, y; // coords of the center point
private Graphics g;
public Circle(int xIn, int yIn) {
radius = (int)(127*Math.random());
x = xIn;
y = yIn;
}
public void draw(Graphics g){
g.drawOval(x-radius, y-radius, radius, radius);
g.fillOval(x-radius, y-radius, radius, radius);
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
}
public int getX(int xstart) {
// TODO Auto-generated method stub
return x;
}
public int getY(int ystart) {
// TODO Auto-generated method stub
return y;
}
}
You just have to save x and y in some attribute for your class (like lastX and lastY.) When you get the event the second time, your first point coordinates are saved in your attributes and you can then draw your line. This new point has to be saved too to serve as your new lastX and lastY.
Even better: since you'll probably need to redraw your lines each frame (if you want a set of lines and not just a single line to be drawn each frame), use Point to save your coordinates and some kind of list like ArrayList. Save the full set of tracked points in an ArrayList<Point> and then draw each frame iterating over this list.
An example of an sscce:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class Foo3 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private boolean tracking = false;
private int x, y;
public Foo3() {
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
}
private static void createAndShowGui() {
Foo3 mainPanel = new Foo3();
JFrame frame = new JFrame("MouseMotion Eg");
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();
}
});
}
}
Edit: Example 2
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class MouseTestHovercraft extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final int MAX_CLR = 5;
private static final Color CURRENT_LIST_COLOR = new Color(190, 190, 255);
private List<Color> colors = new ArrayList<Color>();
private boolean tracking = false;
private List<Point> currentList = null;
private BufferedImage bufferedImage = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
private Random random = new Random();
public MouseTestHovercraft() {
for (int redIndex = 0; redIndex < MAX_CLR; redIndex++) {
int r = (redIndex * 256) / (MAX_CLR - 1);
r = (r == 256) ? 255 : r;
for (int greenIndex = 0; greenIndex < MAX_CLR; greenIndex++) {
int g = (greenIndex * 256) / (MAX_CLR - 1);
g = (g == 256) ? 255 : g;
for (int blueIndex = 0; blueIndex < MAX_CLR; blueIndex++) {
int b = (blueIndex * 256) / (MAX_CLR - 1);
b = (b == 256) ? 255 : b;
Color c = new Color(r, g, b);
colors.add(c);
}
}
}
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
add(new JButton(new AbstractAction("Clear Image") {
public void actionPerformed(ActionEvent e) {
bufferedImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_ARGB);
repaint();
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseListener(myMA);
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bufferedImage, 0, 0, null);
if (currentList != null) {
drawList(g, currentList, CURRENT_LIST_COLOR, 1f);
}
}
private void drawList(Graphics g, List<Point> ptList, Color color,
float strokeWidth) {
if (ptList.size() > 1) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
g2.setStroke(new BasicStroke(strokeWidth));
for (int j = 0; j < ptList.size() - 1; j++) {
int x1 = ptList.get(j).x;
int y1 = ptList.get(j).y;
int x2 = ptList.get(j + 1).x;
int y2 = ptList.get(j + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
g2.dispose();
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList = new ArrayList<Point>();
currentList.add(e.getPoint());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList.add(e.getPoint());
Graphics2D g2 = bufferedImage.createGraphics();
Color color = colors.get(random.nextInt(colors.size()));
drawList(g2, currentList, color, 3f);
currentList = null;
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (tracking && currentList != null) {
currentList.add(e.getPoint());
repaint();
}
}
}
private static void createAndShowGui() {
MouseTestHovercraft mainPanel = new MouseTestHovercraft();
JFrame frame = new JFrame("MouseMotion Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}