We are playing around with mouseDragged and multipleObjects.
We are trying to create a board game that has 8 pieces that can be individually clicked and dragged to their respective location on the board (without using jpanel, jframe, etc). As of now we have created 8 individual pieces for the board game, however when you go to click/drag piece '2', it causes all of the pieces to come together under the top piece.
Our initial solution (not shown) is to use a button to cycle between players pieces, but we would like to try to do this without the use of a button. Any suggestions are welcome.
Board:
import java.applet.Applet;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.MalformedURLException;
import java.net.URL;
public class GameBoard extends Applet implements ActionListener,
MouseListener, MouseMotionListener
{
GamePiece gp1;
GamePiece gp2;
GamePiece gp3;
GamePiece gp4;
GamePiece gp5;
GamePiece gp6;
GamePiece gp7;
GamePiece gp8;
Image bg;
int xposR;
int yposR;
#Override
public void init()
{
System.out.println(getCodeBase().getPath().toString());
MediaTracker tracker = new MediaTracker(this);
try
{
bg = getImage(new URL("file:/C:/Backdroptest.png"));
}
catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
tracker.addImage(bg, 0);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(d);
gp1 = new GamePiece(0, 0, "blue");
gp2 = new GamePiece(40, 0, "red");
gp3 = new GamePiece(80, 0, "yellow");
gp4 = new GamePiece(120, 0, "green");
gp5 = new GamePiece(160, 0, "orange");
gp6 = new GamePiece(200, 0, "cyan");
gp7 = new GamePiece(240, 0, "gray");
gp8 = new GamePiece(280, 0, "magenta");
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void paint(Graphics g)
{
g.drawImage(bg, 0, 0, this);
gp1.display(g);
gp2.display(g);
gp3.display(g);
gp4.display(g);
gp5.display(g);
gp6.display(g);
gp7.display(g);
gp8.display(g);
}
#Override
public void actionPerformed(ActionEvent ev)
{
}
#Override
public void mousePressed(MouseEvent e)
{
}
#Override
public void mouseReleased(MouseEvent e)
{
}
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseMoved(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
#Override
public void mouseDragged(MouseEvent e)
{
gp1.setLocation(xposR, yposR);
gp2.setLocation(xposR, yposR);
xposR = e.getX();
yposR = e.getY();
repaint();
}
}
GamePieces
This part denotes the 8 individual pieces
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class GamePiece implements MouseListener, MouseMotionListener
{
int xpos;
int ypos;
int circleWidth = 30;
int circleHeight = 30;
Boolean mouseClick;
Color c;
public GamePiece(int x, int y, String cc)
{
xpos = x;
ypos = y;
mouseClick = true;
if (!mouseClick)
{
xpos = 50;
ypos = 50;
}
setColor(cc);
}
public void setLocation(int x, int y)
{
xpos = x;
ypos = y;
// mouseClick = true;
}
public void setColor(String s)
{
if (s.equals("blue"))
{
c = Color.blue;
}
else if (s.equals("red"))
{
c = Color.red;
}
else if (s.equals("yellow"))
{
c = Color.yellow;
}
else if (s.equals("green"))
{
c = Color.green;
}
else if (s.equals("orange"))
{
c = Color.orange;
}
else if (s.equals("cyan"))
{
c = Color.cyan;
}
else if (s.equals("gray"))
{
c = Color.gray;
}
else
c = Color.magenta;
}
public void display(Graphics g)
{
g.setColor(c);
g.fillOval(xpos, ypos, circleWidth, circleHeight);
}
#Override
public void mousePressed(MouseEvent e)
{
mouseClick = true;
}
#Override
public void mouseReleased(MouseEvent e)
{
}
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseMoved(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
#Override
public void mouseDragged(MouseEvent e)
{
if (mouseClick)
{
xpos = e.getX();
ypos = e.getY();
}
}
}
Related
Hi I'm using the Timer class and the repaint method for the JPanel, but whenever I hit DOWN and the space ship moves halfway down the screen, it shrinks and stays in place. It never reaches the bottom of the window. It is the same when I move it to the RIGHT.
Also when I try to place it in a differnt y position, the background isn't black anymore. Can someone help me with this please? Here is a sample of my code:
package javapaint;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SpaceShipFlight
{
private JFrame windowFrame;
private BufferedImage shipSprite;
private BufferedImage spaceBackground;
/** MAIN METHOD **/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
SpaceShipFlight window = new SpaceShipFlight();
window.windowFrame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/** CONSTRUCTOR **/
public SpaceShipFlight() throws IOException
{
/*************************************************************************
SPACE SHIP FLIGHT JFRAME
*************************************************************************/
windowFrame = new JFrame("Space Ship Flight");
windowFrame.setBounds(0, 0, 950, 700);
windowFrame.setBackground(Color.BLACK);
/*************************************************************************
SPACE SHIP FLIGHT SPRITES (FOR DRAWING)
*************************************************************************/
spaceBackground = ImageIO.read(new File("Space (Medium).png"));
// 450 x 374
shipSprite = ImageIO.read(new File("Ship Sprite.png"));
// 64 x 64 png of space ship
/*************************************************************************
SPACE SHIP FLIGHT JPANEL (FOR DRAWING)
*************************************************************************/
SpacePanel spacePanel = new SpacePanel();
windowFrame.add(spacePanel);
/*************************************************************************
SPACE SHIP FLIGHT TIMER
*************************************************************************/
Timer timer = new Timer(10, new AnimationListener(spacePanel));
timer.start();
/*************************************************************************
EVENT HANDLER TO MOVE SPACE SHIP
*************************************************************************/
/*
EventHandler <KeyEvent> moveShip = new EventHandler<KeyEvent> ()
{
#Override
public void handle(KeyEvent event)
{
if (event.getCharacter().equalsIgnoreCase("X"))
{
spacePanel.setX( spacePanel.getX() + 1 );
}
}
};
*/
KeyListener moveShip = new KeyListener()
{
#Override
public void keyTyped(KeyEvent e)
{
}
#Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_RIGHT && spacePanel.getX() < 375)
{
spacePanel.setX( spacePanel.getX() + 5 );
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT && spacePanel.getX() > 0)
{
spacePanel.setX( spacePanel.getX() - 5);
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_UP && spacePanel.getY() > 0)
{
spacePanel.setY( spacePanel.getY() - 5);
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_DOWN && spacePanel.getY() < 700)
{
spacePanel.setY( spacePanel.getY() + 5 );
spacePanel.repaint();
}
if (e.getKeyCode() == KeyEvent.VK_X)
{
System.out.printf("X: %d, Y: %d\n", spacePanel.getX(),
spacePanel.getY());
}
}
#Override
public void keyReleased(KeyEvent e)
{
}
};
windowFrame.addKeyListener(moveShip);
}
/** ANIMATION LISTENER CLASS **/
public static class AnimationListener implements ActionListener
{
private SpacePanel panel;
private Graphics graphics;
public AnimationListener(SpacePanel panel)
{
this.panel = panel;
this.graphics = panel.getGraphics();
}
#Override
public void actionPerformed(ActionEvent e)
{
panel.repaint();
}
}
/** SPACE PANEL SUBCLASS **/
public class SpacePanel extends JPanel
{
// Variables for the space ship's position temporarily placed here
private int x;
private int y;
// Constructor
public SpacePanel()
{
super();
x = 0;
y = 0;
}
// Getters
public int getX()
{
return x;
}
public int getY()
{
return y;
}
// Setters
public void setX(int newX)
{
x = newX;
}
public void setY(int newY)
{
y = newY;
}
#Override
public void paint(Graphics g)
{
g.drawImage(spaceBackground, 0, 0, this);
g.drawImage(shipSprite, x, y, this);
}
}
}
public class Screen extends Canvas implements Runnable {
private static final int MAX_FPS = 60;
private static final int FPS_SAMPLE_SIZE = 6;
private boolean[] keysPressed = new boolean[256];
private ArrayList<Character> characters = new ArrayList<>();
private ArrayList<Character> ai = new ArrayList<>();
private Thread thread;
private BufferedImage bg;
//for testing putposes
private Player slime = new Player("Slime.png", 100, 100);
private Player bird = new Player("Bird.png", 250, 250);
private Player giant = new Player("Giant.png", 250, 500);
private Player swordsman = new Player("Swordsman.png", 500, 250);
//screen dimensions
private int height = ((Toolkit.getDefaultToolkit().getScreenSize().height-32)/5*4);
private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private long prevTick = -1;
private LinkedList<Long> frames = new LinkedList<>();
private int averageFPS;
private boolean running;
public Screen() {
setSize(width, height);
try {bg = ImageIO.read(new File("GUI Images/success.jpg"));}
catch (Exception e) {Utilities.showErrorMessage(this, e);}
characters.add(slime);
// ai.add(bird);
//ai.add(giant);
// ai.add(swordsman);
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {keysPressed[e.getKeyCode()] = true;}
public void keyReleased(KeyEvent e) {keysPressed[e.getKeyCode()] = false;}
public void keyTyped(KeyEvent e) {}
});
addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
});
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
});
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {}
});
setVisible(true);
start();
}
public void paint(Graphics g){
BufferStrategy bs = getBufferStrategy();
if(getBufferStrategy() == null){
createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.drawImage(bg,0,0,width,height, null);
g.drawString(String.valueOf(averageFPS), 0, 0);
for (Character character : ai){
character.setY(character.getY() + (int)(Math.random() * 10 - 5));
character.setX(character.getX() + (int)(Math.random() * 10 - 5));
}
for (Character character : ai) {g.drawImage(character.getImage(), character.getX(), character.getY(), null);}
for (Character character : characters) {g.drawImage(character.getImage(), character.getX(), character.getY(), null);}
g.dispose();
bs.show();
}
public void run() {
while (running) {
tick();
repaint();
}
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
try {thread.join();}
catch (InterruptedException e) {Utilities.showErrorMessage(this, e);}
}
public void tick() {
if (keysPressed[KeyEvent.VK_W] && (slime.getY() > 0)) {slime.setY(slime.getY() - 1);}
if (keysPressed[KeyEvent.VK_S] && (slime.getY() < height)) {slime.setY(slime.getY() + 1);}
if (keysPressed[KeyEvent.VK_A] && (slime.getY() > 0)) {slime.setX(slime.getX() - 1);}
if (keysPressed[KeyEvent.VK_D] && (slime.getY() < width)) {slime.setX(slime.getX() + 1);}
// System.out.println(slime.getX() + ", " + slime.getY());
long pastTime = System.currentTimeMillis() - prevTick;
prevTick = System.currentTimeMillis();
if (frames.size() == FPS_SAMPLE_SIZE) {
frames.remove();
}
frames.add(pastTime);
// Calculate average FPS
long sum = 0;
for (long frame : frames) {
sum += frame;
}
long averageFrame = sum / FPS_SAMPLE_SIZE;
averageFPS = (int)(1000 / averageFrame);
// Only if the time passed since the previous tick is less than one
// second divided by the number of maximum FPS allowed do we delay
// ourselves to give Time time to catch up to our rendering.
if (pastTime < 1000.0 / MAX_FPS) {
try {
Thread.sleep((1000 / MAX_FPS) - pastTime);
System.out.println(averageFPS);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
There's my code, essentially this is just test code for the screen to see if I can properly paint objects to the screen, but there's erratic white frames that keep getting painted. They don't seem to be caused by any sort of input in particular, they just happen seemingly randomly during frame refreshes. Any ideas as to what it might be?
Don't override paint and use a BufferStrategy within it. Painting is usually done on a need to do bases (AKA "passive" rendering). BufferStrategy is a "active" rendering approach, where you take control of the paint process and update the buffer directly, the two don't tend to play well together
Take the logic from the current paint method and place it within your game loop.
This will require you to remove your call to start within the constructor, as the component won't have been added to a valid native peer (a component which is displayed on the screen).
Instead, create an instance of Screen, add it to your frame and then call start, for example...
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestScreen {
public static void main(String[] args) {
new TestScreen();
}
public TestScreen() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Frame frame = new Frame("Testing");
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Screen screen = new Screen();
frame.add(screen);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
screen.start();
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class Screen extends Canvas implements Runnable {
private static final int MAX_FPS = 60;
private static final int FPS_SAMPLE_SIZE = 6;
private boolean[] keysPressed = new boolean[256];
private ArrayList<Character> characters = new ArrayList<>();
private ArrayList<Character> ai = new ArrayList<>();
private Thread thread;
private BufferedImage bg;
private long prevTick = -1;
private LinkedList<Long> frames = new LinkedList<>();
private int averageFPS;
private boolean running;
public Screen() {
try {
bg = ImageIO.read(new File("GUI Images/success.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
keysPressed[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keysPressed[e.getKeyCode()] = false;
}
public void keyTyped(KeyEvent e) {
}
});
addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
});
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
}
});
}
#Override
public Dimension getPreferredSize() {
int height = ((Toolkit.getDefaultToolkit().getScreenSize().height - 32) / 5 * 4);
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
return new Dimension(width, height);
}
public void run() {
createBufferStrategy(3);
BufferStrategy bs = null;
while (running) {
bs = getBufferStrategy();
Graphics g = bs.getDrawGraphics();
g.drawImage(bg, 0, 0, getWidth(), getHeight(), null);
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.RED);
g.drawString(String.valueOf(averageFPS), 0, fm.getAscent());
g.dispose();
bs.show();
tick();
}
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tick() {
// if (keysPressed[KeyEvent.VK_W] && (slime.getY() > 0)) {
// slime.setY(slime.getY() - 1);
// }
// if (keysPressed[KeyEvent.VK_S] && (slime.getY() < height)) {
// slime.setY(slime.getY() + 1);
// }
// if (keysPressed[KeyEvent.VK_A] && (slime.getY() > 0)) {
// slime.setX(slime.getX() - 1);
// }
// if (keysPressed[KeyEvent.VK_D] && (slime.getY() < width)) {
// slime.setX(slime.getX() + 1);
// }
// // System.out.println(slime.getX() + ", " + slime.getY());
long pastTime = System.currentTimeMillis() - prevTick;
prevTick = System.currentTimeMillis();
if (frames.size() == FPS_SAMPLE_SIZE) {
frames.remove();
}
frames.add(pastTime);
// Calculate average FPS
long sum = 0;
for (long frame : frames) {
sum += frame;
}
long averageFrame = sum / FPS_SAMPLE_SIZE;
averageFPS = (int) (1000 / averageFrame);
// Only if the time passed since the previous tick is less than one
// second divided by the number of maximum FPS allowed do we delay
// ourselves to give Time time to catch up to our rendering.
if (pastTime < 1000.0 / MAX_FPS) {
try {
Thread.sleep((1000 / MAX_FPS) - pastTime);
System.out.println(averageFPS);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
}
I have these two classes:
public class Pencil extends JComponent implements MouseListener, MouseMotionListener{
Plansa plansa;
Graphics g;
public Pencil(Plansa newCanvas){
this.plansa = newCanvas;
this.plansa.setFlagShape(false);
}
#Override
public void mouseDragged(MouseEvent arg0) {
plansa.setMouseDragged(arg0);
this.plansa.setFlagShape(false);
plansa.paintComponent(plansa.getGraphics());
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent arg0) {
plansa.setMousePressed(arg0);
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
plansa.setMouseReleased(arg0);
this.plansa.setFlagShape(true);
plansa.paintComponent(plansa.getGraphics());
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
And this one:
public class Plansa extends JPanel{
Image image;
Pencil pencil;
//...
void init(){
this.setShape("freeLine");
this.setColor(Color.BLACK);
this.size=1;
this.type="round";
this.fill=false;
this.setBackground(Color.WHITE);
pencil = new Pencil(this);
addMouseListener(pencil);
addMouseMotionListener(pencil);
flagPaint = true;
flagShape = false;
}
public Plansa(){
this.setSize(800, 600);
init();
}
//...
#Override
public void paintComponent(Graphics g) {
g.setColor(currentColor);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(setBrush(size,type));
super.paintComponent(g);
switch(shape){
default: break;
case "freeLine":{
g.drawLine(xDragged, yDragged, xCurrent, yCurrent);
break;
}
case "rectangle":{
if(flagShape == true){
g.drawRect(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
if(fill == true) g.fillRect(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
}
break;
}
case "circle":{
if(flagShape == true){
int radius = (int)Math.sqrt(Math.max(xCurrent-xPressed,xPressed-xCurrent)*Math.max(xCurrent-xPressed,xPressed-xCurrent)+Math.max(yCurrent-yPressed,yPressed-yCurrent)*Math.max(yCurrent-yPressed,yPressed-yCurrent));
g.drawOval(xPressed, yPressed, radius, radius);
if(fill == true) g.fillOval(xPressed, yPressed, radius, radius);
}
break;
}
case "oval":{
if(flagShape == true){
g.drawOval(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
if(fill == true) g.fillOval(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
}
break;
}
case "line":{
if(flagShape == true){
g.drawLine(xPressed, yPressed, xCurrent, yCurrent);
}
break;
}
}
}
//...
}
My problem is that every time I call paintComponent() method, the JPanel clears and the only item that remains is the one I just drawn. Is there any way to avoid this?
After close inspection of the code, it appears that you're trying to use Components as "painters", it's a bit like using a sports car as a go-kart, a lot of extras for little gain.
Instead, you should define yourself a interface of some kine that provides the basic requirements of what you want to draw/paint and then define concrete class implementations that implement the functionality.
You would then maintain a List of some kind of all the drawings that can be painted.
While simple, the example below provides a jumping off point that could be enhanced that allow selection of drawings, re-ordering and removal (should you want it).
This, is, essentially, the same concept proposed by Doorknob (+1)
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestDraw {
public static void main(String[] args) {
new TestDraw();
}
public TestDraw() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Pencil());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Pencil extends JPanel implements MouseListener, MouseMotionListener {
private List<Drawable> drawables;
private Drawable activeDrawable;
private Point clickPoint;
public Pencil() {
drawables = new ArrayList<>(5);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable drawable : drawables) {
drawable.paint(g2d);
}
g2d.dispose();
}
#Override
public void mouseDragged(MouseEvent e) {
if (activeDrawable != null) {
Point p = e.getPoint();
Rectangle bounds = activeDrawable.getBounds();
int x = bounds.x;
int y = bounds.y;
int width = p.x - clickPoint.x;
int height = p.y - clickPoint.y;
if (width < 0) {
width *= -1;
x = p.x;
}
if (height < 0) {
height *= -1;
y = p.y;
}
bounds = new Rectangle(x, y, width, height);
System.out.println(bounds);
activeDrawable.setBounds(bounds);
repaint();
}
}
#Override
public void mouseClicked(MouseEvent e) {
}
protected Drawable createActiveShape(MouseEvent e) {
System.out.println("Anchor = " + e.getPoint());
Drawable drawable = new FreeLine(e.getPoint());
drawable.setLocation(e.getPoint());
return drawable;
}
#Override
public void mousePressed(MouseEvent e) {
// You could also check to see if the clicked on a drawable...
clickPoint = e.getPoint();
activeDrawable = createActiveShape(e);
drawables.add(activeDrawable);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
if (activeDrawable != null) {
Rectangle bounds = activeDrawable.getBounds();
if (bounds.width == 0 || bounds.height == 0) {
drawables.remove(activeDrawable);
}
}
clickPoint = null;
activeDrawable = null;
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
public interface Drawable {
public void setLocation(Point p);
public void setSize(Dimension dim);
public void setBounds(Rectangle bounds);
public Rectangle getBounds();
public void paint(Graphics2D g2d);
}
public abstract class AbstractDrawable implements Drawable {
private Rectangle bounds;
public AbstractDrawable() {
bounds = new Rectangle();
}
#Override
public void setLocation(Point p) {
bounds.setLocation(p);
}
#Override
public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}
#Override
public void setSize(Dimension dim) {
bounds.setSize(dim);
}
#Override
public Rectangle getBounds() {
return bounds;
}
}
public class FreeLine extends AbstractDrawable {
private Point anchor;
public FreeLine(Point anchor) {
this.anchor = anchor;
}
#Override
public void paint(Graphics2D g2d) {
Rectangle bounds = getBounds();
Point p1 = new Point(anchor);
Point p2 = new Point(bounds.getLocation());
if (p1.x > p2.x) {
p2.x = p1.x - bounds.width;
} else {
p2.x = p1.x + bounds.width;
}
if (p1.y > p2.y) {
p2.y = p1.y - bounds.height;
} else {
p2.y = p1.y + bounds.height;
}
g2d.draw(new Line2D.Float(p1, p2));
}
}
Store all the objects in an ArrayList and iterate through it when you are drawing.
You could have them all implement a custom interface, Drawable for example, then store in an ArrayList<Drawable>.
A better idea generally for progressive drawings is to use a BufferedImage as the canvas, as seen here.
Don't use/comment out:
super.paintComponent(g);
That line is the one that is doing the clearing.
i want to drag a box and i want my mouse cursor to be where i clicked in a rectangle while im draging rectangle. i tried this code and i got bunch of errors when i tried to drag.
import objectdraw.*;
import java.awt.*;
public class TouchWindow extends WindowController
{
private FilledRect a;
private boolean b;
private Location c;
private int x;
private int y;
public void begin()
{
b=false;
a=new FilledRect(0,0,50,50,canvas);
}
public void onMouseClick(Location pt)
{
if(a.contains(pt))
{
b=true;
pt=c;
}
}
public void onMouseDrag(Location pt2)
{
if(b==true)
{
x=(int)c.getX()-(int)pt2.getX();
y=(int)c.getY()-(int)pt2.getY();
a.move(x,y);
}
}
}
Hmm here is an example I had lying around, although not an applet it can be very simply ported.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ShapeMover {
public ShapeMover() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Shape Mover");
initComponents(frame);
frame.pack();
frame.setVisible(true);
}
public static void main(String s[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ShapeMover();
}
});
}
private void initComponents(JFrame frame) {
frame.getContentPane().add(new DragPanel());
}
}
class DragPanel extends JPanel {
Rectangle rect = new Rectangle(0, 0, 100, 50);
int preX, preY;
boolean isFirstTime = true;
Rectangle area;
boolean pressOut = false;
private Dimension dim = new Dimension(400, 300);
public DragPanel() {
setBackground(Color.white);
addMouseMotionListener(new MyMouseAdapter());
addMouseListener(new MyMouseAdapter());
}
#Override
public Dimension getPreferredSize() {
return dim;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if (isFirstTime) {
area = new Rectangle(dim);
rect.setLocation(50, 50);
isFirstTime = false;
}
g2d.setColor(Color.black);
g2d.fill(rect);
}
boolean checkRect() {
if (area == null) {
return false;
}
if (area.contains(rect.x, rect.y, rect.getWidth(), rect.getHeight())) {
return true;
}
int new_x = rect.x;
int new_y = rect.y;
if ((rect.x + rect.getWidth()) > area.getWidth()) {
new_x = (int) area.getWidth() - (int) (rect.getWidth() - 1);
}
if (rect.x < 0) {
new_x = -1;
}
if ((rect.y + rect.getHeight()) > area.getHeight()) {
new_y = (int) area.getHeight() - (int) (rect.getHeight() - 1);
}
if (rect.y < 0) {
new_y = -1;
}
rect.setLocation(new_x, new_y);
return false;
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
preX = rect.x - e.getX();
preY = rect.y - e.getY();
if (rect.contains(e.getX(), e.getY())) {
updateLocation(e);
} else {
pressOut = true;
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (!pressOut) {
updateLocation(e);
} else {
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (rect.contains(e.getX(), e.getY())) {
updateLocation(e);
} else {
pressOut = false;
}
}
public void updateLocation(MouseEvent e) {
rect.setLocation(preX + e.getX(), preY + e.getY());
checkRect();
repaint();
}
}
}
Can't seem to figure out how to only show one circle. Was trying to //g.clearRect(0, 0, 400, 400); but that clears the background too. Was also trying to just fill the background with yellow again but couldn't get that working either. Any suggestions?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JMouseFrame extends JFrame
implements MouseListener {
Container con = null;
int x, y;
int size;
public JMouseFrame() {
setTitle("JMouseFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
con = this.getContentPane();
addMouseListener(this);
}
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
size = 4;
}
repaint();
}
public void mouseEntered(MouseEvent e) {
con.setBackground(Color.yellow);
}
public void mouseExited(MouseEvent e) {
con.setBackground(Color.black);
}
public void paint(Graphics g) {
//g.clearRect(0, 0, 400, 400);
g.drawOval(x - size, y - size, size * 3, size * 3);
}
public static void main(String[] args) {
JMouseFrame mFrame = new JMouseFrame();
mFrame.setSize(400, 400);
mFrame.setVisible(true);
}
public void mouseReleased(MouseEvent e) {
}
}
It looks like you're mixing AWT and Swing painting. Instead, override paintComponent(), as suggested in the example below. See Painting in AWT and Swing for details.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see http://stackoverflow.com/questions/3898775 */
public class MousePanel extends JPanel {
private static final int SIZE = 20;
Point p = new Point(Short.MAX_VALUE, Short.MAX_VALUE);
public MousePanel() {
this.setPreferredSize(new Dimension(400, 400));
this.setBackground(Color.yellow);
this.addMouseListener(new MouseHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawOval(p.x - SIZE, p.y - SIZE, SIZE * 2, SIZE * 2);
}
private final class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
p = e.getPoint();
repaint();
}
}
private void display() {
JFrame f = new JFrame("MousePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MousePanel().display();
}
});
}
}
Addendum:
I can't figure out how to make the code you posted work with what I have...
You can restore your mouse methods to the MouseHandler almost verbatim. The only difference is the need to qualify this, e.g.
#Override
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
MousePanel.this.size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
MousePanel.this.size = 4;
}
repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
MousePanel.this.setBackground(Color.yellow);
}
#Override
public void mouseExited(MouseEvent e) {
MousePanel.this.setBackground(Color.black);
}