how to drag object - java

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();
}
}
}

Related

repaint(); not Updating

I'm new to java, and as a challenge I'm following some tutorials on how to create a small game. I've managed to make a nice keyboard input reader but sadly I don't know why my repaint(); isn't working... The point is to change the ints Py and Px, they are responsible in changing the position of the player!
This is the class f2, a JPanel that is added to a Jframe in another file.
import java.awt.*;
import java.awt.event.*;
public class f2 extends JPanel implements Runnable{
keys keyh = new keys();
Thread gameThreadMain;
//background color
Color bg2 = new Color(81,89,98);
Color txt1 = new Color(237,237,237);
//width control
final int w = 700, h = 700;
int wp = 64, hp = 64;
//spawn cords
//
int spawn1x = (w / 2) - (wp / 2);
int spawn1y = (h / 2) - (hp / 2);
//Player Speed
int Px = spawn1x;
int Py = spawn1y;
int Ps = 4;
//FPS
int fps = 60;
public f2(){
/* this.addKet*/
this.setBackground(bg2);
this.setPreferredSize(new Dimension(w,h));
this.setDoubleBuffered(true);
/*this.setLayout();*/
}
public void startGameThreadMain(){
gameThreadMain = new Thread(this);
gameThreadMain.start();
}
#Override
public void run(){
double drawInterval = 1000000000/fps;
double nextDrawTime = System.nanoTime() + drawInterval;
while(gameThreadMain != null){
update();
repaint();
/*System.out.print("check");*/
try{
double remainingTime = nextDrawTime - System.nanoTime();
remainingTime = remainingTime / 1000000;
if (remainingTime < 0) {
remainingTime = 0;
}
Thread.sleep((long) remainingTime);
nextDrawTime += drawInterval;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update(){
//Keyboard
if(keyh.UpPressed == true) {
Py -= Ps;
}
else if(keyh.DownPressed == true) {
Py += Ps;
}
else if(keyh.LeftPressed == true) {
Px -= Ps;
}
else if(keyh.RightPressed == true) {
Px += Ps;
}else{
//
}
}
//player painter (this is the part where the 'repaint();' isn't working
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D player = (Graphics2D)g;
player.setColor(txt1);
player.fillRect(Px,Py,wp,hp);
System.out.println("repainted");
}
}```
//Thanks for reading!
startGameThreadMain is never called.
Swing is not thread AND is single threaded. You should never update the UI, or some state the UI depends on, from outside the context of the Event Dispatching Thread.
See Concurrency in Swing for more details and How to Use Swing Timers for one possible solution.
You should also be aware of:
How to Use Key Bindings
Painting in AWT and Swing
Performing Custom Painting
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
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 Player {
private int x;
private int y;
private Color backgroundColor = new Color(237, 237, 237);
private Shape shape;
public Player(int x, int y) {
this.x = x;
this.y = y;
this.shape = new Rectangle2D.Double(0, 0, getWidth(), getHeight());
}
public void setLocation(int x, int y) {
setX(x);
setY(y);
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return 64;
}
public int getHeight() {
return 64;
}
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(backgroundColor);
g2d.translate(getX(), getY());
g2d.fill(shape);
g2d.dispose();
}
}
public enum Movement {
UP, DOWN, LEFT, RIGHT;
}
public interface MovementObserver {
public void movementDidActiviated(Object source, Movement movement);
public void movementWasDeactiviated(Object source, Movement movement);
}
public class TestPane extends JPanel {
private Timer timer;
private Player player;
private Set<Movement> movements = new HashSet<>();
public TestPane() {
player = new Player(0, 0);
int spawnY = (getPreferredSize().width - player.getWidth()) / 2;
int spawnX = (getPreferredSize().height - player.getHeight()) / 2;
player.setLocation(spawnX, spawnY);
setBackground(new Color(81, 89, 98));
timer = new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (movements.contains(Movement.UP)) {
player.setY(player.getY() - 1);
} else if (movements.contains(Movement.DOWN)) {
player.setY(player.getY() + 1);
}
if (movements.contains(Movement.LEFT)) {
player.setX(player.getX() - 1);
} else if (movements.contains(Movement.RIGHT)) {
player.setX(player.getX() + 1);
}
repaint();
}
});
MovementObserver observer = new MovementObserver() {
#Override
public void movementDidActiviated(Object source, Movement movement) {
movements.add(movement);
}
#Override
public void movementWasDeactiviated(Object source, Movement movement) {
movements.remove(movement);
}
};
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Up.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Down.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "Left.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "Right.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Up.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Down.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "Left.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "Right.released");
am.put("Up.pressed", new MovementAction(Movement.UP, observer, true));
am.put("Down.pressed", new MovementAction(Movement.DOWN, observer, true));
am.put("Left.pressed", new MovementAction(Movement.LEFT, observer, true));
am.put("Right.pressed", new MovementAction(Movement.RIGHT, observer, true));
am.put("Up.released", new MovementAction(Movement.UP, observer, false));
am.put("Down.released", new MovementAction(Movement.DOWN, observer, false));
am.put("Left.released", new MovementAction(Movement.LEFT, observer, false));
am.put("Right.released", new MovementAction(Movement.RIGHT, observer, false));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 700);
}
#Override
public void addNotify() {
super.addNotify();
if (timer == null) {
return;
}
timer.start();
}
#Override
public void removeNotify() {
super.removeNotify();
if (timer == null) {
return;
}
timer.stop();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (player == null) {
return;
}
Graphics2D g2d = (Graphics2D) g.create();
player.paint(g2d);
g2d.dispose();
}
}
public class MovementAction extends AbstractAction {
private Movement movement;
private MovementObserver observer;
private boolean activate;
public MovementAction(Movement movement, MovementObserver observer, boolean active) {
this.movement = movement;
this.observer = observer;
this.activate = active;
}
public Movement getMovement() {
return movement;
}
public MovementObserver getObserver() {
return observer;
}
public boolean doesActivate() {
return activate;
}
#Override
public void actionPerformed(ActionEvent e) {
if (doesActivate()) {
getObserver().movementDidActiviated(this, getMovement());
} else {
getObserver().movementWasDeactiviated(this, getMovement());
}
}
}
}

How to stop flickering in java.awt.graphics?

So i started to learn Java and tried to create a basic pong game using java.awt.graphics.
After finishing it i saw that it was a lot of flickering to the point when the game was unplayable.
This is my main class named "pong"(What a creative name).
package pong;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class pong extends Applet implements Runnable,KeyListener {
public static void main(String[] args){}
public final int W=700,L=500;
p1 player1;
p1 player2;
ball b;
Thread thread;
public void init() {
resize(W,L);
this.addKeyListener(this);
player2 = new p1(1);
b = new ball();
thread= new Thread(this);
player1 = new p1(2);
thread.start();
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0,0,W,L);
if(!(b.getX()<-10 || b.getX()>690)){
player1.draw(g);
b.draw(g);
player2.draw(g);
}else if(b.getX()<-10){
g.setColor(Color.WHITE);
g.drawString("Right Player Won!",350,250);
}else{
g.setColor(Color.WHITE);
g.drawString("Left Player Won!",350,250);
}
}
#Override
public void update(Graphics g){
paint(g);
}
public void run() {
for(;;){
player1.move();
player2.move();
b.move();
colitionchecker(1);
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_UP)
player1.setUp(true);
else if (e.getKeyCode()==KeyEvent.VK_DOWN)
player1.setDown(true);
else if(e.getKeyCode()==KeyEvent.VK_W)
player2.setUp(true);
else if(e.getKeyCode()==KeyEvent.VK_S)
player2.setDown(true);
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_UP)
player1.setUp(false);
else if (e.getKeyCode()==KeyEvent.VK_DOWN)
player1.setDown(false);
else if(e.getKeyCode()==KeyEvent.VK_W)
player2.setUp(false);
else if(e.getKeyCode()==KeyEvent.VK_S)
player2.setDown(false);
}
public void colitionchecker(int num){
if(num == 1){
if(b.getX()<50 && b.getX()>20 && b.getY()>player2.getY() &&
b.getY()>=player2.getY()-80){
b.xv=-b.xv;
}
else{
if(b.getX()<700 && b.getX()>660 && b.getY()>=player1.getY() && b.getY()<=player1.getY()+80){
b.xv=-b.xv;
}
}
}
}
}
package pong;
import java.awt.*;
public class p1 implements paddle{
final double GRAVITY = 0.94;
double y=210,yv;
boolean up,down;
int player,x;
public p1(int player){
up=false; down=false;
if(player==1)
x=20;
else
x=660;
}
#Override
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(x, (int)y,20,80);
}
public void move() {
if (up){
yv -= 2;
}else if (down){
yv += 2;
}else if (!down && !up){
yv *= GRAVITY;
}
if(yv>=15)
yv=5;
else if(yv<=-5)
yv=-5;
y += yv;
if(y<=0)
y=0;
else if(y>=420)
y=420;
}
public void setUp(boolean up) {
this.up = up;
}
public void setDown(boolean down) {
this.down = down;
}
public int getY() {
return (int)y;
}
}
package pong;
import java.awt.*;
public class ball {
double xv, yv, x, y;
public ball(){
x = 350;
y = 250;
xv = 2;
yv = 1;
}
public int getY() {
return (int)y;
}
public int getX() {
return (int)x;
}
public void move(){
x+=xv;
y+=yv;
if(y<10)
yv=-yv;
if(y>490)
yv=-yv;
}
public void draw(Graphics g){
g.setColor(Color.WHITE);
g.fillOval((int)x-10,(int)y-10,20,20);
}
}
package pong;
import java.awt.*;
public interface paddle {
public void draw(Graphics g);
public int getY();
public void move();
}
I am really lost and any help will be much appreciated.
Thanks.
So i started to learn Java
So your first lesson is, Applets are dead - better to spend your time else where, either using Swing or JavaFX windows based UIs.
Applet is not double buffered, hence the flicker, both Swing and JavaFX, if used correctly are.
I'd also discourage you from using a Thread in this way, as most GUI frameworks are not thread safe
I'd recommend having a look at:
Creating a GUI With JFC/Swing
Getting Started with JavaFX
as a basic starting point
Swing based solution
Because I can do it quickly...
KeyListener is a poor choice which is going to haunt you, better to use the Key Bindings API, which has been designed to overcome its limitations
Things you're going to have to read up on...
2D Graphics
How to Use Key Bindings
How to Use Swing Timers
And as an overall basic example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private DefaultPaddle player1;
private DefaultPaddle player2;
private Ball b;
public TestPane() {
setBackground(Color.BLACK);
player1 = new DefaultPaddle(1);
player2 = new DefaultPaddle(2);
b = new Ball();
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "Player1.up.pressed", new UpAction(player1, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Player1.up.released", new UpAction(player1, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "Player1.down.pressed", new DownAction(player1, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Player1.down.released", new DownAction(player1, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Player2.up.pressed", new UpAction(player2, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Player2.up.released", new UpAction(player2, false));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Player2.down.pressed", new DownAction(player2, true));
addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Player2.down.released", new DownAction(player2, false));
Timer timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
player1.move();
player2.move();
b.move();
// colitionchecker(1);
repaint();
}
});
timer.start();
}
protected void addKeyBinding(KeyStroke ks, String name, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(ks, name);
am.put(name, action);
}
public void colitionchecker(int num) {
if (num == 1) {
if (b.getX() < 50 && b.getX() > 20 && b.getY() > player2.getY()
&& b.getY() >= player2.getY() - 80) {
b.xv = -b.xv;
} else {
if (b.getX() < 700 && b.getX() > 660 && b.getY() >= player1.getY() && b.getY() <= player1.getY() + 80) {
b.xv = -b.xv;
}
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
// if (!(b.getX() < -10 || b.getX() > 690)) {
player1.draw(g);
b.draw(g);
player2.draw(g);
// } else if (b.getX() < -10) {
// g.setColor(Color.WHITE);
// g.drawString("Right Player Won!", 350, 250);
// } else {
// g.setColor(Color.WHITE);
// g.drawString("Left Player Won!", 350, 250);
// }
g2d.dispose();
}
}
public class UpAction extends AbstractAction {
private DefaultPaddle paddle;
private boolean pressed;
public UpAction(DefaultPaddle paddle, boolean pressed) {
this.paddle = paddle;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Up " + pressed);
paddle.setUp(pressed);
}
}
public class DownAction extends AbstractAction {
private DefaultPaddle paddle;
private boolean pressed;
public DownAction(DefaultPaddle paddle, boolean pressed) {
this.paddle = paddle;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
paddle.setDown(pressed);
}
}
public interface Paddle {
public void draw(Graphics g);
public int getY();
public void move();
}
public class DefaultPaddle implements Paddle {
final double GRAVITY = 0.94;
double y = 210, yv;
boolean up, down;
int player, x;
public DefaultPaddle(int player) {
up = false;
down = false;
if (player == 1) {
x = 20;
} else {
x = 660;
}
}
#Override
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(x, (int) y, 20, 80);
}
public void move() {
if (up) {
yv -= 1;
} else if (down) {
yv += 1;
} else if (!down && !up) {
yv *= GRAVITY;
}
if (yv >= 15) {
yv = 5;
} else if (yv <= -5) {
yv = -5;
}
y += yv;
if (y <= 0) {
y = 0;
} else if (y >= 420) {
y = 420;
}
}
public void setUp(boolean up) {
this.up = up;
}
public void setDown(boolean down) {
this.down = down;
}
public int getY() {
return (int) y;
}
}
public class Ball {
double xv, yv, x, y;
public Ball() {
x = 350;
y = 250;
xv = 2;
yv = 1;
}
public int getY() {
return (int) y;
}
public int getX() {
return (int) x;
}
public void move() {
x += xv;
y += yv;
if (y < 10) {
yv = -yv;
}
if (y > 490) {
yv = -yv;
}
}
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval((int) x - 10, (int) y - 10, 20, 20);
}
}
}

Why is this graphics object not painting? (What am i doing wrong?)

So I am writing a program in Java, and one of the important things it needs to be able to do is render multiple objects onto the screen that can be dragged and dropped by the user. I have made a class (pasted below), but when I try to initialise one with
new DragNode();
it doesn't work.
Can someone please tell me what I am doing wrong?
Thanks,
Sam
public static class DragNode extends JLabel{
public static final long serialVersionUID=155L;
public class MA extends MouseAdapter{
public void mousePressed(MouseEvent e) {
preX = rect.x - e.getX();
preY = rect.y - e.getY();
if (rect.contains(e.getX(), e.getY())) {
updateLocation(e);
System.out.println("Mouse pressed on rectangle");
} 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();
}
}
public int x,y;
Rectangle rect,area;
int preX,preY;
boolean firstTime=true;
boolean pressOut=false;
private Dimension dim=getGraphPanelSize();
private Image Node_Sprite;
public DragNode(){
init();
}
public DragNode(int x,int y){
this.x=x;
this.y=y;
init();
}
public void init(){
//setBackground(Color.GRAY);
setOpaque(false);
addMouseMotionListener(new MA());
addMouseListener(new MA());
rect = new Rectangle(x, y, 50, 50);
area=new Rectangle(dim);
try{
Node_Sprite=ImageIO.read(new File("Node_Sprite.png"));
}catch(IOException ioe){}
}
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;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if (firstTime) {
rect.setLocation(x,y);
firstTime = false;
}
g2d.setColor(new Color(0,0,0,0));
g2d.drawImage(Node_Sprite, rect.x,rect.y,50,50,null);
}
}
When I replace the code for drawing the rectangle with
g2d.setColor(Color.red);
g2d.fillRect( rect.x, rect.y, 50, 50);
// g2d.drawImage(Node_Sprite, rect.x, rect.y, 50, 50, null);
It is drawn and can be dragged in the x-direction. So there might be something wrong with your image (does it exist in the specified folder?). I expected the dragging to be in both directions, so there might be an issue there as well for the y-direction.
EDIT: Ok, I tried it with an image as well, works well. I also saw that your "borders" 'dim' are set very narrow, so I increased them to 300/300 so I can drag around my image in both axis.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import net.miginfocom.swing.MigLayout;
public class DragNode extends JLabel {
public static final long serialVersionUID = 155L;
public static void main(String[] args) {
JLabel node = new DragNode();
JFrame frame = new JFrame("blupp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new MigLayout(""));
frame.getContentPane().add(node, "grow, push");
frame.setLocationRelativeTo(null);
frame.setSize(new Dimension(500, 300));
frame.setVisible(true);
}
public class MA extends MouseAdapter {
public void mousePressed(MouseEvent e) {
preX = rect.x - e.getX();
preY = rect.y - e.getY();
if (rect.contains(e.getX(), e.getY())) {
updateLocation(e);
System.out.println("Mouse pressed on rectangle");
} 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();
}
}
public int x, y;
Rectangle rect, area;
int preX, preY;
boolean firstTime = true;
boolean pressOut = false;
private Dimension dim = new Dimension(300, 300);
private Image Node_Sprite;
public DragNode() {
init();
}
public DragNode(int x, int y) {
this.x = x;
this.y = y;
init();
}
public void init() {
//setBackground(Color.GRAY);
setOpaque(false);
addMouseMotionListener(new MA());
addMouseListener(new MA());
rect = new Rectangle(x, y, 50, 50);
area = new Rectangle(dim);
try {
Node_Sprite = ImageIO.read(new File("Node_Sprite.png"));
} catch (IOException ioe) {}
}
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;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.green);
// g2d.fillRect(10, 10, 100, 100);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
if (firstTime) {
rect.setLocation(x, y);
firstTime = false;
}
g2d.setColor(Color.red);
// g2d.fillRect( rect.x, rect.y, 50, 50);
g2d.drawImage(Node_Sprite, rect.x, rect.y, 50, 50, null);
}
}
Not sure why you are extending JLabel. You are not using the label to paint text or an Icon. Instead you are actually doing the custom painting yourself so you should be extending JComponent.
Or the other approach is to just use a JLabel to display the image and then create your listener to drag the label to a new location and let the label to the painting. You can check out Component Mover which allows you to drag any component.

mouseMoved Event not working

I've been trying to work this code, it's like when you hover over the start button it should change its color to gray, but whenever i hover over it. nothing happens, can somebody tell me why? i didn't get any error and it seems like my mousemoved listener isn't recognized by the compiler, sorry for my english. I haven't finish it yet but here is the code:
class Contents extends JFrame implements Runnable {
private Image dbi;
private Graphics dbg;
private boolean isStarted, isHovered;
private int x,y,xDir,yDir,bx,by,timer,life,my,mx,mhx,mhy;
private Rectangle startgame = new Rectangle(80,100,150,40);
Contents()
{
super();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
if(isStarted)
setSize(600,600);
else
{
setSize(300,300);
setBackground(Color.BLUE);
}
setLocationRelativeTo(null);
isStarted = false;
isHovered = false;
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
mx = e.getX();
my = e.getY();
if(mx > startgame.x && mx < startgame.x+startgame.width &&
my > startgame.y && my < startgame.y+startgame.height)
{
isStarted = true;
}
}
public void mouseMoved(MouseEvent e)
{
mhx = e.getX();
mhy = e.getY();
if(mhx > startgame.x && mhx < startgame.x+startgame.width &&
mhy > startgame.y && mhy < startgame.y+startgame.height)
isHovered = true;
else
isHovered = false;
}
});
}
public void paint(Graphics g)
{
dbi = createImage(getWidth(), getHeight());
dbg = dbi.getGraphics();
draw(dbg);
g.drawImage(dbi,0,0,this);
repaint();
}
public void draw(Graphics g)
{
if(!isStarted)
{
if(!isHovered)
g.setColor(Color.GRAY);
else
g.setColor(Color.GREEN);
g.fillRect(startgame.x, startgame.y, startgame.width, startgame.height);
g.setFont(new Font("Serif",Font.BOLD,24));
g.setColor(Color.WHITE);
g.drawString("Start game", startgame.x+20, startgame.y+25);
g.drawString(String.format("hoverx: %d hovery: %d",mhx,mhy), 50,200);
}
else
{
}
}
public void run()
{
} }
public class Game {
public static void main(String[] args)
{
Contents c = new Contents();
} }
Just use Rectangle.contains(Point) to check if the point from the MouseEvent is inside the Rectangle. Here is an example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PaintedButton extends JPanel {
private static final Color HOVER_COLOR = Color.BLUE;
private static final Color NON_HOVER_COLOR = Color.GREEN;
private static final Rectangle2D RECTANGLE = new Rectangle2D.Double(50, 50,
200, 100);
private Color color = NON_HOVER_COLOR;
public PaintedButton() {
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
if (RECTANGLE.contains(p)) {
color = HOVER_COLOR;
} else {
color = NON_HOVER_COLOR;
}
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(color);
g2.fill(RECTANGLE);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PaintedButton());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

Multiple calls of paintComponent()

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.

Categories

Resources