import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.sound.sampled.*;
import java.util.ArrayList;
public class Board extends JPanel implements ActionListener
{
Timer time;
Image Border;
Image Dude;
Image Road;
Image GZombie;
Image RZombie;
Image BZombie;
MovingPiece player;
public Board()
{
//set this window to be the one receiving keystrokes
addKeyListener(new AL());
setFocusable(true);
ImageIcon dude = new ImageIcon("Dude.png"); //player
Dude=dude.getImage();
// Cx and Cy are changed in move methods, they are change in (x/y)
// X Y W H CxCy Speed Image
player=new MovingPiece(200,300,50,50,0,0,2,Dude);
time=new Timer(5,this);
time.start();
}
public void actionPerformed(ActionEvent e){
player.setX(player.getX() + player.getCx()); //adds my x to my change in x
player.setY(player.getY() + player.getCy()); //im sure u can figure this one out...
//redraw the screen
repaint();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(player.getImage(),player.getX(),player.getY(),null); //draw player
}
//the key listener, it is a private class inside of the Board class
private class AL extends KeyAdapter{
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
System.out.println(key); //*THIS IS WHAT WONT RUN*
if(key==KeyEvent.VK_W){player.moveUp();} //this changes my cy to be -speed which is -2
if(key==KeyEvent.VK_A){player.moveDown();} //this changes my cy to be speed which is 2
if(key==KeyEvent.VK_S){player.moveLeft();} //I made this simple.. this is cx
if(key==KeyEvent.VK_D){player.moveRight();} //take a guess.
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
if(key==KeyEvent.VK_W){player.setCy(0);} //stops my changes in y so I don't move up/down
if(key==KeyEvent.VK_A){player.setCx(0);} //quite repetitive.
if(key==KeyEvent.VK_S){player.setCy(0);}
if(key==KeyEvent.VK_D){player.setCx(0);}
}
}
}
Basically my keyadapter wont run. The print of what key is, is not important.
But it is an indicator to see if the method is running, or if the problem was with my move methods.
well since it isn't printing, then the method itself is not running. and thus it is not my move methods. it must be this adapter. I just want to know why it isn't working. I have set focusable which is all the other forums say to do. so. please help. thanks in advance
Related
I have tried and tried, I looked up many examples for keeping Shapes on the screen but can't seem to adapt to my code. In Summary, a left click prints a square, a right click prints a circle. I would like to fill the window with squares (rects) and circles. Any help and explanation so I can learn the concept would be great. I understand I have to keep track on the coordinates, perhaps in a loop but can seem to get it to work. Thanks again.
import java.awt.*;
import javax.swing.JFrame;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
public class MouseButtonTester extends JFrame implements MouseListener
{
private int mouseX, mouseY;
private int mouseButton;
private boolean isFirstRun;
private static final int WIDTH = 640;
private static final int HEIGHT = 480;
private static final long serialVersionUID = 0; //use this if you do not like warnings
public MouseButtonTester() //constructor
{
super("Mouse Button Tester");
//set up all variables
mouseX = mouseY = 0;
mouseButton = 0;
isFirstRun = true;
//set up the Frame
setSize(WIDTH,HEIGHT);
setBackground(Color.WHITE);
setVisible(true);
//start trapping for mouse clicks
addMouseListener(this);
}
public void mouseClicked(MouseEvent e)
{
mouseX=e.getX(); //Tracks x coordinates
mouseY=e.getY(); //Tracker y coordinates
mouseButton = e.getButton(); //gets button number
repaint();
}
public void paint( Graphics window ) // Draws the Window
{
if(isFirstRun)
{
window.setColor(Color.WHITE);
window.fillRect(0,0,WIDTH, HEIGHT);
//change isFirstRun
}
window.setFont(new Font("TAHOMA",Font.BOLD,12));
window.setColor(Color.BLUE);
window.drawString("MOUSE BUTTON TESTER", 420,55);
draw(window);
}
public void draw(Graphics window)
{
if(mouseButton==MouseEvent.BUTTON1) //left mouse button pressed
{
//window.drawString("BUTTON1", 50,200); //debug code
window.setColor(Color.RED);
window.drawRect(mouseX,mouseY,10,10);
}
//right mouse button pressed
{
if (mouseButton == MouseEvent.BUTTON2)
window.setColor(Color.BLUE);
window.drawOval(mouseX,mouseY,10,10);
}
//any other mouse button pressed
{
}
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) { }
}
------ Main Method --------------
public class MouseButtonTesterRunner
{
public static void main(String[] args)
{ MouseButtonTester prog = new MouseButtonTester();
}
}
First, start by having a read through:
Performing Custom Painting
Painting in AWT and Swing
So you can get a understanding how painting in Swing works, how you can work with it and your responsibilities when doing so.
Next, have a read through:
How can I set in the midst?
Java JFrame .setSize(x, y) not working?
How to get the EXACT middle of a screen, even when re-sized
Graphics rendering in title bar
for reasons why you should avoid overriding paint of top level containers like JFrame
Finally...
Painting in Swing is destructive, that is, every time your component is painted, you are expected to completely repaint the component state from scratch.
In order to achieve your goal, you will need to maintain a cache of the items you want to paint.
The concept itself it's very difficult, but there might be some "gotchas" along the way
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Point> circles;
private List<Point> squares;
public TestPane() {
circles = new ArrayList<>();
squares = new ArrayList<>();
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
circles.add(e.getPoint());
} else if (SwingUtilities.isRightMouseButton(e)) {
squares.add(e.getPoint());
}
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// I'm picky
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Point p : circles) {
g2d.drawOval(p.x, p.y, 10, 10);
}
g2d.setColor(Color.BLUE);
for (Point p : squares) {
g2d.drawRect(p.x, p.y, 10, 10);
}
g2d.setFont(new Font("TAHOMA", Font.BOLD, 12));
g2d.setColor(Color.BLUE);
FontMetrics fm = g2d.getFontMetrics();
String text = "MOUSE BUTTON TESTER";
int x = getWidth() - fm.stringWidth(text) - 10;
int y = getHeight() - (fm.getAscent() - fm.getHeight()) - 10;
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}
I suggest creating 2 classes.
1) Circle class
2) Square Class
Those classes will store info that you need, like X, y etc..
Initialize an array list that stores those objects & read from it in your paint method, proceed with painting them just like you do in your code.
(On a click event you simply create new object (circle/square) and add it into your array list)
So here's how i understand how your code works so far: The user left clicks, those coordinates are recorded, and a square is rendered on the screen at those coordinates.
When we click the coordinates are updated and on the next draw, the square is moved to a new position.
You were on the right track about needing a loop.
Here's the logic you need to implement:
Create an ArrayList as a member variable. The type can be a pair<int,int> object. So this arraylist will hold a list of X,Y coordinates. This arraylist will look something like this:
ArrayList<pair<int,int>> myRightClickCoords;
Once you make that list, every time the user clicks, record the click coordinates and insert them into the arraylist. That will look something like this:
myRightClickCoords.insert(new pair<int,int>(e.getX(),e.getY()));
Then, once that is added to your code, in your draw function, you can have a look that runs through the entire myRightClickCoords list and runs drawRect for each set of coordinates.
Once you get that working, you can do the same thing for left click and circles. Good luck!
I've made about 30 different google searches and didn't come up with an answer, so I came here. So I'm trying to move the player's rectangle (the black square) left and right across the screen. It worked fine when I used regular graphics, but now that I'm using Graphics2D the repaint() seems to do nothing (i.e. when you press the left and right arrow keys, the rectangle doesn't move).
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class boxface extends JComponent implements KeyListener {
private boxobj obj;
private int x=0, y=650;
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()== KeyEvent.VK_RIGHT)
moveRight();
else if(e.getKeyCode()== KeyEvent.VK_LEFT)
moveLeft(); }
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
Rectangle player = new Rectangle(x, y, 50, 50);
Rectangle floor = new Rectangle(0, 700, 750, 700);
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.GREEN);
g2.fill(floor);
g.setColor(Color.BLACK);
g2.fill(player); }
public void moveLeft() {
if(x > 0) {
x -= 50;
repaint(); }}
public void moveRight() {
if(x < 700) {
x += 50;
repaint(); }}
public boxface(){
this.obj=new boxobj();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false); }
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(400, 200, 756, 779);
f.setMinimumSize(new Dimension(756, 0));
f.setResizable(false);
f.getContentPane().add(new boxface());
f.setVisible(true);
}
});
final java.util.Timer tmr = new java.util.Timer();
tmr.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println("A second has passed.");
/* the idea is that I could make a square with random
* dimensions (within a certain limit), so that every
* time the timer loops, a new, random square is made.
* I just can't seem to move the rectangles using
* repaint(); because they're Graphics2D rectangles,
* and I can't find a way around this.
*
* An example of this can be shown if you run this
* code; the "player" rectangle cannot be moved, even
* though keylistener is picking up inputs and the
* rectangle's co-ordinates are being changed. In
* other words, repaint(); isn't doing anything. */
}
},0,1000);
}//end main
}//end class
Also, the "boxobj" class is just an empty class right now. It's where I plan to put the initialization of the random rectangles. I'll just put it in here for easy copy-paste.
public class boxobj {
}
The problem is that you're updating the x variable, but painting the player object.
When you construct player (via Rectangle player = new Rectangle(x, y, 50, 50);) it takes a copy of the value of x at the time that line is executed. Since you're declaring and initializing at the same time, we know that x is zero so player will be instantiated with (0, 650, 50, 50).
Later on, the user hits the right arrow key and your event listener fires. This increases x to 50 and calls repaint but, importantly, does not update the player object at all. When the paintComponent method gets called by the painting system player is still (0, 650, 50, 50).
Essentially x and y record the player's position, but you're using the player object to draw the player and those variables are not getting updated in tandem.
The best way to correct this is to store the player's position in exactly one place. You can either keep x and y and modify your paintComponent method to use those, or you could throw away those two variables and modify the player object instead (with player.setLocation). Either way will work.
I am recreating the game space invaders and have reached the point of firing a projectile. I've been using the KeyListener class successfully so that when the spacebar is pressed my projectile fires. The issue is that it only updates it's position after it has been fired, so it fires from the position that laser canon was last placed not its current position.
My laserCanon class
/*
*The properties and behaviors of the laser canon
*/
package spaceinvaders;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Polygon;
public class LaserCanon extends GameObject{
private int pnlWidth;//GamePanel width
private int pnlHeight;//GamePanel height
private final int moveInc = 15;//number of pixels moved when when arrow key is pressed
//Constructor
public LaserCanon(int pnlWidth, int pnlHeight){
super();
this.pnlWidth = pnlWidth;
this.pnlHeight = pnlHeight;
getLocation().x=pnlWidth;//sets initial location of canon
getLocation().y=pnlHeight;//sets intial location of canon
setColor(Color.green);//canon is green
setVisible(true);
}
public LaserCanon(){
super();
}
//draws laser canon using GamePanel height and width
#Override
public void draw(Graphics g){
g.setColor(this.getColor());
Polygon triangle = new Polygon();//canon is in shape of triangle
triangle.addPoint(getLocation().x, getLocation().y);//bottom right point
triangle.addPoint(getLocation().x-100, getLocation().y);//bottom right point
triangle.addPoint(getLocation().x-50, getLocation().y-75);//top point
g.fillPolygon(triangle);
}
//returns each property in a string
#Override
public String toString(){
String string = super.toString();
string = getPnlWidth() + "|" + getPnlHeight() + "|" + getMoveInc();
return string;
}
//moves canon left
public void moveLeft(){
if(getLocation().getX()>50){
System.out.println("Left key pressed\n" + getLocation().getX());
getLocation().x-=moveInc;
}
}
//moves canon right
public void moveRight(){
if(getLocation().getX()<pnlWidth){
System.out.println("Right key pressed\n" + getLocation().getX());
getLocation().x+=moveInc;
}
}
//accessor and mutator methods
My Projectile Class
public class Projectile extends GameObject{
private int speed;//speed at which the projectile moves
private int locX;
private int locY;
private GamePanel gamePanel;
//constructor
public Projectile(int speed, GamePanel gp){
super();
this.speed = speed;
gamePanel = gp;
//sets location of projectile to same location as canon Starting at top point
this.locX = gamePanel.getLaserCanon().getLocation().x-50;
this.locY = gamePanel.getLaserCanon().getLocation().y-75;
setColor(Color.cyan);//projectile is cyan
setVisible(false);//not visible to start
}
public Projectile(){
super();
}
#Override
public void draw(Graphics g){
if(isVisible())
g.setColor(this.getColor());
else
g.setColor(Color.black);
Polygon triangle1 = new Polygon();
triangle1.addPoint(getLocX()-5, getLocY());//bottom left point
triangle1.addPoint(getLocX()+5, getLocY());//bottom right point
triangle1.addPoint(getLocX(), getLocY()-15);//top middle point
Polygon triangle2 = new Polygon();
triangle2.addPoint(getLocX(), getLocY()+3);//bottom middle point
triangle2.addPoint(getLocX()-5, getLocY()-10);//bottom left point
triangle2.addPoint(getLocX()+5, getLocY()-10);//bottom right point
g.fillPolygon(triangle1);
g.fillPolygon(triangle2);
}
public int move(){
setLocY(getLocY() - getSpeed());
return getLocY();
}
//accessor and mutators
And my game panel class to hold each of the former:
package spaceinvaders;
import java.awt.Color;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.BorderFactory;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class GamePanel extends JPanel implements KeyListener{();
private LaserCanon laserCanon;
private Projectile projectile;
private Timer projectileTimer;//used to animate the projectile fired from LaserCanon
//constructor
public GamePanel(){
setSize(800,800);//size of panel
setBackground(Color.BLACK);//background
setBorder(BorderFactory.createLineBorder(Color.red, 3));//border
laserCanon = new LaserCanon(getWidth(), getHeight());
projectile = new Projectile(20,this);
projectileTimer = new Timer(50, new TimerListener());
//instantiate other GameObjects
//gives focus to this panel for KeyListener
this.setFocusable(true);
this.requestFocus();
this.addKeyListener(this);
repaint();
}
#Override
public void keyPressed(KeyEvent k){
int key = k.getKeyCode();
if(key == k.VK_LEFT){//if left arrow is pressed
getLaserCanon().moveLeft();
repaint();
}
else if(key == k.VK_RIGHT){//if right arrow is pressed
getLaserCanon().moveRight();
repaint();
}
else if(key == k.VK_SPACE){
System.out.println("fired!");
getProjectile().setVisible(true);
getProjectileTimer().start();
}
}
#Override
public void keyReleased(KeyEvent k){
//dummy method
}
#Override
public void keyTyped(KeyEvent k){
//dummy method
}
private class TimerListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
if(getProjectile().move()>-15){
repaint();
}
else{
getProjectileTimer().stop();
getProjectile().setVisible(false);
projectile.setLocX(laserCanon.getLocation().x-50);
projectile.setLocY(laserCanon.getLocation().y-75);
repaint();
}
}
}
//used to call draw methods
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
getLaserCanon().draw(g);
getProjectile().draw(g);
}
After placing
projectile.setLocX(laserCanon.getLocation().x-50);
projectile.setLocY(laserCanon.getLocation().y-75);
in my TimerListener class after it has detected that the projectile is no longer on screen I realized that I need another set of these methods somewhere else and have been playing around with it, but I can't seem to figure out where. Anywhere else I place them solves the position problem, but I lose the animation.
Basically, where ever my laser canon goes I need my projectile to follow and fire from the laser canon's position. How can I get that to happen?
Side note: There is an abstract class GameObject that holds the visibility, location (using the Point class), and color of my projectile and laser canon.
I found that by adding in a moveLeft() and moveRight() methods like those that are in my LaserCanon class, to my projectile class it would move with the canon rather than depending on the cannon to move.
I have a simple applet that animates a rectangle along the x-axis of the canvas. The problem is that it flickers. I have tried to Google this problem, but I didn't come up with anything useful or anything that I understood.
I am relatively new to Java.
Thanks!
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class simpleAnimation extends JApplet implements ActionListener {
Timer tm = new Timer(10, this);
int x = 0, velX = 2;
public void actionPerformed(ActionEvent event) {
if (x < 0 || x > 550){
velX = -velX;
}
x = x + velX;
repaint();
}
public void paint ( Graphics g ) {
super.paint(g);
g.setColor(Color.RED);
g.fillRect(x, 30, 50, 30);
tm.start();
}
}
**********UPDATED CODE WITHOUT FLICKER**********
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class simpleAnimation extends JApplet implements ActionListener
{
Graphics bufferGraphics;
Image offscreen;
Dimension dim;
int x = 3, velX = 2;
Timer tm = new Timer(10, this);
public void init()
{
dim = getSize();
offscreen = createImage(dim.width,dim.height);
bufferGraphics = offscreen.getGraphics();
}
public void paint(Graphics g)
{
bufferGraphics.clearRect(0,0,dim.width,dim.width);
bufferGraphics.setColor(Color.red);
bufferGraphics.fillRect(x,50,50,20);
g.drawImage(offscreen,0,0,this);
tm.start();
}
public void update(Graphics g)
{
paint(g);
}
public void actionPerformed(ActionEvent evt)
{
if ( x < 0 || x > 550){
velX = -velX;
}
x = x + velX;
repaint();
}
}
I used this applet as a template.
I always struggle with this concept of double buffering.
Here is my example that overrides paint() of the JApplet and a paintComponent() of a JPanel, which uses double buffering by default.
I don't see any difference in the apparent flickering.
//<applet code="SimpleAnimation.class" width="600" height="300"></applet>
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class SimpleAnimation extends JApplet implements ActionListener {
Timer tm = new Timer(10, this);
int x = 0, velX = 2;
JPanel panel;
public void init()
{
panel = new JPanel()
{
#Override
public Dimension getPreferredSize()
{
return new Dimension(50, 100);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(x, 30, 50, 30);
}
};
add(panel, BorderLayout.SOUTH);
tm.start();
}
public void actionPerformed(ActionEvent event) {
if (x < 0 || x > 550){
velX = -velX;
}
x = x + velX;
repaint();
// panel.repaint();
}
public void paint ( Graphics g ) {
super.paint(g);
g.setColor(Color.RED);
g.fillRect(x, 30, 50, 30);
}
}
I test the code using: appletviewer SimpleAnimation.java
Is my concept of double buffering flawed, or my implementation, or both?
The problem is, top level containers like JApplet aren't double buffered. This means that when it's updated, the screen flickers as each action is done directly onto the screen.
Instead, you should create a custom component, using something like a JPanel, and override its paintComponent method and perform your custom painting actions there.
Because Swing components are double buffered the results of the paint action are buffered before they are painted to the screen, making it a single action
Take a look at Performing Custom Painting for more details
What you're doing now works like this:
public void paint ( Graphics g ) {
// draw the entire area white
super.paint(g);
g.setColor(Color.RED);
// draw a rectangle at the new position
g.fillRect(x, 30, 50, 30);
}
So with every step, you first wipe out your rectangle, and then draw it fresh. Thus the flickering - the pixels under the rectangle keep changing from white to red to white to red to white to red...
Now observe that the smallest amount of painting you need to do is (supposing rectangle moves to the right) this:
draw velx pixels on the left WHITE
draw velx pixes on the right RED
If you do that, your animation will be smooth.
Computing that can be quite challenging though, especially when your shape is more complicated than just a square / your movement is more complex. That's where double buffering comes in.
With double buffering, you create an in-memory image that is the same size as your screen. You paint your entire theme there. Then you paint that image on your screen all at once.
When doing that, there won't be an intermediate step of "entire screen is WHITE"; thus no flickering. But note that you end up re-painting the entire screen rather than just the area that changed, which isn't ideal. Consider using clipping - a technique where you repaint a pre-defined area of the image and not the entire thing.
Thanks for checking out this Question. I think I've just about scratched through my skull in frustration.
So what I've got is a 'JFrame' containing a 'JPanel'. The 'JPanel' contains a little colored Square which is supposed to move X pixels whenever I click the window.
Well, essentially everything behaves as it should, with one exception. When the blue square moves to the right, it leaves a trail of other squares behind it. It is not supposed to leave the trail, however, when I re-size the window, the trail vanishes.
Catalyst.java
package Prototype;
import java.awt.*;
public class Catalyst {
public static void main(String[] args){
World theWorldInstance = new World("Prototype", 100,100, 600,100); /*title,xpos,ypos,width,height*/
}
}
World.java
package Prototype;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class World extends JFrame {
Level mainPanel;
public World(String title, int x, int y, int width, int height) {
setTitle(title);
setBounds(x,y,width,height);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBackground(new Color(0x00000000));
initLevel();
}
public void initLevel(){
mainPanel = new Level();
Container visibleArea = getContentPane();
visibleArea.add(mainPanel);
setVisible(true);
add(mainPanel);
}
}
Level.java
package Prototype;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Level extends JPanel implements MouseListener, ActionListener {
Square x;
public Level() {
System.out.println("This is working correctly[JPANEL Cons]");
addMouseListener(this);
x = new Square();
}
public void paintComponent(Graphics g){
x.draw(g);
}
public void actionPerformed(ActionEvent e){
}
public void mousePressed(MouseEvent e){
requestFocus();
x.move();
repaint();
System.out.println("Focus Acquired");
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
}
Square.java
package Prototype;
import java.awt.*;
public class Square {
private Point position;
private int size;
private final int displacement;
public Square(){
position = new Point(10,10);
size = 20;
displacement = 5;
}
public void draw(Graphics g){
g.setColor(Color.blue);
g.fillRect(position.x-(size/2), position.y-(size/2), size,size );
g.setColor(Color.black);
g.drawRect(position.x-(size/2), position.y-(size/2), size,size );
}
public void move() {
position.x += displacement;
}
}
Those are all my files. I hope I've phrased everything properly and provided all the content required. Whenever I've done something similar in the past this has never happened. I assume I'm missing something small, or I've done something stupid. If you can help me, thanks in advance!
There's another way of doing this. You can simply call the parent object's paintComponent method to clear the panel.
Add this to your constructor in Level :
this.setBackground(Color.BLACK);
And this as the first call in paintComponent:
super.paintComponent(g);
You can use g.clearRect(x, y, width, height), and provide the said coordinates, where you want the painting to be cleared from. Or you can give the dimensions of whole of the JPanel/JComponent where you are drawing, though doing this keep one thing in mind, that the said drawing is not a heavy work, else too much of cleaning will put extra burden on the painting calls.