-
Cannot display in JPanel
Hi guys,
I have problem with displaying components in JPanel. After I run this code my window application freezes. I discovered that if I take method move from private class DrawingPanel and make it as a member of its parent class then this code work. But unfortunately I have to have this method inside DrawingPanel class. Thanks for any help
Code:
/*
* Game.java
*
* Created on 18 July 2009, 08:04
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
*
*/
public class Game extends JFrame
{
// instance variables provided
private final int FRAME_WIDTH = 500;
private final int FRAME_HEIGHT = 500;
// TODO add myLauncher instance variable
Launcher myLauncher;
// TODO uncomment
protected Target myTarget = new Target(FRAME_WIDTH,FRAME_HEIGHT);
public Ray myRay;
/**
* Creates a new instance of Game
*/
public Game(String title)
{
super(title);
setSize(FRAME_WIDTH,FRAME_HEIGHT);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myLauncher = new Launcher(FRAME_WIDTH, FRAME_HEIGHT);
addKeyListener(new myKeyListener());
add(new DrawingPanel());
}
// inner class on which to draw everything
// TODO add code to show myLauncher
private class DrawingPanel extends JPanel
{
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
myTarget.paintComponent(g);
myLauncher.paintComponent(g);
// TODO ray section to be uncommented
if (myRay != null)
{
myRay.paintComponent(g);
//check for collision here - if not in here, then no ray to check!
if (isContact())
{
System.out.println("hit it!-----------------------------------");
myRay = null;
myTarget = null;
//need to stop the game now else it crashes
System.exit(0);
}
}
move(g);//IF I COMMENT THIS LINE AND MAKE MOVE AS A MEMBER OF PARENT CLASS AND THEN IN MAIN I JUST CALL MOVE THIS WORKS
}
public void move(Graphics g)
{
if (myRay != null)
{
if (myRay.move()) // means ray is off top of screen
{
myRay = null;
}
}
while (true)
{
myTarget.move();
repaint();
try
{
Thread.sleep(50);
}
catch(InterruptedException e)
{
System.exit(0);
}
}
}
/*DUMMY BODY
*/
public boolean isContact()
{
return false;
}
}
// TODO add KeyListener inner class and keyPressed method
private class myKeyListener extends KeyAdapter
{
@Override
public void keyPressed(KeyEvent ke)
{
if (ke.getKeyCode() == KeyEvent.VK_LEFT)
{
myLauncher.moveLeft();
}
if (ke.getKeyCode() == KeyEvent.VK_RIGHT)
{
myLauncher.moveRight();
}
if (ke.getKeyCode() == KeyEvent.VK_UP && myRay == null)
{
myRay = new Ray(FRAME_WIDTH, FRAME_HEIGHT);
}
}
}
}
///////////////////////////////////////////////////////////////
/*
* Target.java
*
* Created on 18 July 2009, 08:06
*
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.color.ColorSpace;
/**
*
*
*/
public class Target
{
private final int RADIUS; // RADIUS of circle drawn as part of spaceship
private Point pos;//position of top left hand corner of box holding whole spaceship
private final Color SPACE_SHIP_COLOUR; // colour of spaceship
private int sideChange; // amount of sideways movement per step
private final int HEIGHT, WIDTH; // of frame
public Target(int frameWidth, int frameHeight)
{
RADIUS = 10;
WIDTH = frameWidth;
HEIGHT = frameHeight;
//creates point with random x and y coordinates
pos = new Point((int) Math.random() * (WIDTH - RADIUS) + RADIUS,
(int) Math.random() * (HEIGHT / 2 - RADIUS) + RADIUS);
SPACE_SHIP_COLOUR = Color.GRAY;
//generating pseudorandom number
int START = -6;
int END = 6;
int range = END - START;
for (int i = 0; i < 100; ++i)
{
sideChange = (int) (Math.random() * range + START);
if (sideChange == 0)//zero not allowed
{
continue;
}
}
}
public void paintComponent(Graphics g)
{
g.setColor(SPACE_SHIP_COLOUR);
g.fillOval(pos.x, pos.y, 40, 20);
g.drawOval(pos.x + 10, pos.y - 10, 20, 20);
}
public void move()
{
if (pos.x < WIDTH)
{
pos.translate(sideChange,0);
}
}
public Rectangle getLocation()
{
return new Rectangle(pos.x,pos.y - 10, 40, 30);
}
}
/////////////////////////////////////////////////////////////
/*
* Launcher.java
*
* Created on 18 July 2009, 08:08
*
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
/**
*
*
*/
public class Launcher
{
private final Color LAUNCHER_COLOUR = Color.BLACK; // colour
private final int LAUNCHER_HEIGHT, LAUNCHER_WIDTH; // width and height of the base of the launcher
private int x, y; // x and y position of the top left hand corner of the base of the launcher
private final int SIDE_MOVE; // amount of sideways movement
/** Creates a new instance of Launcher */
public Launcher(int frameWidth, int frameHeight)
{
LAUNCHER_WIDTH = frameWidth/10;
LAUNCHER_HEIGHT = 10;
x = frameWidth/2-LAUNCHER_WIDTH/2; // roughly central
y = frameHeight - 100;
SIDE_MOVE = 5;
}
public void paintComponent(Graphics g)
{
g.setColor(LAUNCHER_COLOUR);
g.fillRect(x, y, LAUNCHER_WIDTH, LAUNCHER_HEIGHT);
g.fillRect(x + LAUNCHER_WIDTH/2 - 5, y - 10, LAUNCHER_HEIGHT, LAUNCHER_HEIGHT);
}
public void moveRight()
{
x += SIDE_MOVE;
}
public void moveLeft()
{
x -= SIDE_MOVE;
}
public Point rayPosition()
{
return new Point(x + LAUNCHER_WIDTH/2,y + LAUNCHER_HEIGHT);
}
}
////////////////////////////////////////////
/*
* Ray.java
*
* Created on 18 July 2009, 08:09
*
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
/**
*
*
*/
public class Ray
{
private final int RAY_LENGTH;
private final Color RAY_COLOUR = Color.RED;
private int x, y;
private final int RAY_MOVE;
/** Creates a new instance of Ray */
public Ray(int frameWidth, int frameHeight)
{
x = frameWidth/2; // roughly central
y = frameHeight - 110;
RAY_MOVE = 5;
RAY_LENGTH = 50;
}
public void paintComponent(Graphics g)
{
g.setColor(RAY_COLOUR);
g.drawRect(x, y-RAY_LENGTH, 2, RAY_LENGTH);
}
public boolean move()
{
boolean offTopOfScreen;
y = y - RAY_MOVE;
// if ray off top of screen tell M257InvadersGame
offTopOfScreen = (y + RAY_LENGTH <= 0);
return offTopOfScreen;
}
public void setPos(Point currentPos)
{
x=currentPos.x;
y=currentPos.y;
}
public Rectangle getLocation()
{
return new Rectangle(x,y-RAY_LENGTH, 2, RAY_LENGTH);
}
}
//////////////////////////////
public class Main
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Game myGame = new Game("Game");
myGame.setVisible(true);
}
}
-
Welcome to the forum. One of your problems is that you have program logic in your paintComponent method, and this shouldn't be done as paint/paintComponent should concern itself with painting only. You should have a game engine that moves things, changes class variables, calls repaint, and then the paintCompnent uses those class variables to decide what to paint where.
Your next problem is that you're freezing the event dispatch thread or EDT, the single thread responsible for drawing the swing app and for interacting with the user, with a while (true) loop. Don't use while (true) (and don't use Thread.sleep(...) ) in the EDT. Instead, since this is a simple animation, use a Swing Timer.
I suggest you go to the Java tutorials and read up on use of Swing Timers. Also search this forum for their use with animations and you'll see many examples. Much luck!
-
Thanks, I'll try to fix it as you suggest.