I've created my own extended JPanel to able the user to sign on it, after that save the signature and delete from the panel:
public class PanelParaFirmar extends JPanel
{
private MouseHandler mouseHandler = new MouseHandler();
private int index = 0;
private Point[] arr = new Point[100000];
public PanelParaFirmar()
{
this.setBackground(Color.WHITE);
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
protected void paintComponent(Graphics g)
{
this.paintComponents(g);
for (int i = 0; i < index - 1; i++)
g.drawLine(arr[i].x, arr[i].y, arr[i + 1].x, arr[i + 1].y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
arr[index] = new Point(e.getX(), e.getY());
index++;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
arr = new Point[100000];
index = 0;
}
#Override
public void mouseDragged(MouseEvent e) {
//updateUI();
//save();
arr[index] = new Point(e.getX(), e.getY());
index++;
repaint();
}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
};
Before click on it all it's right:
But when I started to sign, it repaints the rootPane:
How can I paint just the line?
In addition to the fact that you should override paintComponent and not paintComponents , and call its super implementation, here is how you could manage multiple lines for one signature .
Create a list of lines ( a line is nothing else than a list of Point) to represent the signature.
When the mouse is pressed, add a new line to the list, and add the current point to this line.
When the mouse is dragged, add the current point to the current line.
Finally, your paint method will paint each line one after the other, without making junctions between them :
import java.awt.Color;
import java.awt.Graphics;
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;
public class PanelParaFirmar extends JPanel {
private final MouseHandler mouseHandler = new MouseHandler();
private final List<List<Point>> lines = new ArrayList<>();
private List<Point> currentLine;
public static void main(final String[] args) {
JFrame fr = new JFrame();
fr.setSize(400, 200);
fr.getContentPane().add(new PanelParaFirmar());
fr.setVisible(true);
}
public PanelParaFirmar() {
this.setBackground(Color.WHITE);
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
for (List<Point> line : lines) {
for (int i = 0; i < line.size() - 1; i++) {
Point thisPoint = line.get(i);
Point nextPoint = line.get(i + 1);
g.drawLine(thisPoint.x, thisPoint.y, nextPoint.x, nextPoint.y);
}
}
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(final MouseEvent e) {
currentLine = new ArrayList<Point>();
currentLine.add(new Point(e.getX(), e.getY()));
lines.add(currentLine);
repaint();
}
#Override
public void mouseDragged(final MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
currentLine.add(p);
repaint();
}
}
}
Also note that since you are using a MouseAdapter , you don't have to implement the methods you don't need (like mouseClicked).
My experience in Java is very little but I like programming and everything I make I want it to be as good as possible. Having studied Java for a total time of at most 2 days, it is not so easy.
I've been asked to make a Logic Gate Simulator. I've done everything besides the GUI. It is not necessary as given by our teacher but it is for me as communication with the user in such a program is complicated. A GUI will make it much more clear.
I would like to create the gates on a canvas and then be able to move them around. I started by making an AND gate and got it to move around with the mouse when clicked.
I noticed, however, that now I have a canvas on top of everything. Every label,button, etc I add is behind the canvas. It seems like the canvas is necessary in order to move the gate as it is actually repainted when I move it.
The gate AND is made inside a class with paintComponent. Will I have to make every gate in this single class so they can be on the same canvas? How can I make every gate,label,button share the same canvas ?
Here is my code finally.Gates move with a double-click. It is long though.
Main:
package Pack;
import java.util.Scanner;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class Main {
public static JFrame f;
public static void main(String[] args) {
ShapeAnd sh=new ShapeAnd();
ShapeOr sh2=new ShapeOr();
f=new JFrame();
f.add(sh);
f.add(sh2);
f.setVisible(true);
f.setSize(700,600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("LGS");
f.getContentPane().setBackground(Color.RED);
}
}
OR:
package Pack;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class ShapeOr extends JPanel implements MouseListener,MouseMotionListener{
int preX,preY,preX2,preY2,difX,difY;
Graphics g2;
GeneralPath Or;
int lim1x,lim2x,lim1y,lim2y;
boolean check;
public ShapeOr() {
preX=15;
preY=0;
addMouseMotionListener(this);
addMouseListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
lim1x=preX;
lim2x=preX+80;
lim1y=preY;
lim2y=preY+60;
int x1Points[] = {preX,preX+50,preX+60,preX+70,preX+80,preX+70,preX+60,preX+50,preX,preX+10,preX+20,preX+30,preX+20,preX+10,preX};
int y1Points[] = {preY,preY,preY+5,preY+15,preY+30,preY+45,preY+55,preY+60,preY+60,preY+55,preY+45,preY+30,preY+15,preY+5,preY};
GeneralPath Or = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
x1Points.length);
Or.moveTo(preX-15,preY+15);
Or.lineTo(preX+20,preY+15);
Or.moveTo(preX-15,preY+45);
Or.lineTo(preX+20,preY+45);
Or.moveTo(preX,preY);
for (int index = 1; index < x1Points.length; index++) {
Or.lineTo(x1Points[index], y1Points[index]);
};
Or.closePath();
g2.draw(Or);
//check=false;
}
public void mousePressed(MouseEvent e) {
difX=preX-e.getX();
difY=preY-e.getY();
}
public void updateLocation(MouseEvent e){
preX=e.getX()+difX;
preY=e.getY()+difY;
repaint();
}
public void mouseReleased(MouseEvent e) {
check=false;
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
int mouseX=e.getX();
int mouseY=e.getY();
if(mouseX>lim1x && mouseX<lim2x && mouseY>lim1y && mouseY<lim2y){
check=true;
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
if(check==true){
updateLocation(e);
}
}
}
AND:
package Pack;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class ShapeAnd extends JPanel implements MouseListener,MouseMotionListener{
int preX,preY,preX2,preY2,difX,difY;
Graphics g2;
GeneralPath And;
int lim1x,lim2x,lim1y,lim2y;
boolean check;
public ShapeAnd() {
addMouseMotionListener(this);
addMouseListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
lim1x=preX+15;
lim2x=preX+95;
lim1y=preY;
lim2y=preY+75;
int x1Points[] = {preX,preX+ 50, preX+60,preX +70,preX+80,preX+70,preX+60,preX+50,preX+0};
int y1Points[] = {preY+0,preY+ 0,preY+5,preY+15,preY+30,preY+45,preY+55,preY+60,preY+60};
GeneralPath And = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
x1Points.length);
And.moveTo(preX,preY+15);
And.lineTo(preX+15,preY+15);
And.moveTo(preX,preY+45);
And.lineTo(preX+15,preY+45);
And.moveTo(preX+15,y1Points[0]);
for (int index = 1; index < x1Points.length; index++) {
And.lineTo(x1Points[index]+15, y1Points[index]);
};
And.closePath();
g2.draw(And);
//check=false;
}
public void mousePressed(MouseEvent e) {
difX=preX-e.getX();
difY=preY-e.getY();
}
public void updateLocation(MouseEvent e){
preX=e.getX()+difX;
preY=e.getY()+difY;
repaint();
}
public void mouseReleased(MouseEvent e) {
check=false;
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
int mouseX=e.getX();
int mouseY=e.getY();
if(mouseX>lim1x && mouseX<lim2x && mouseY>lim1y && mouseY<lim2y){
check=true;
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
if(check==true){
updateLocation(e);
}
}
}
PS:Needs a better title, I know.
Thank you for your code post as that helps clarify things quite a bit. My assumption was correct -- you're making your gates extend a GUI component, adding a lot of unnecessary "weight" to them, and making them hard to move around as you'd like, or place multiple ones of them on your GUI.
Suggestions for a solution include:
Make your gates much more light-weight by not having them extend JPanel or any GUI component.
Instead make them "logical" (non-GUI components) that can be drawn by a single drawing component via a public void draw(Graphics2d g2) method. I usually use the paintComponent(Graphics g) method of a single JPanel to do this drawing.
Give this drawing JPanel an ArrayList of your gate objects, and then draw the gates by iterating through the list in the JPanel's single paintComponent method.
Add to the same JPanel a MouseAdapter as both mouse listener and motion listener, and allow this listener to change the state of any of your gate shapes that have been clicked or dragged on.
Allow the gates to draw themselves by giving them a draw(...) method that a drawing component can call,
Give your gate objects a public boolean contains(Point p) method that allows you to tell if the mouse clicks on them
And give them getter and setter methods for their positions, so that this can be checked and changed.
Utilize the functionality classes that derive from the Shape interface (by composition) to help give your own shape the ability to draw itself and move. I've used Path2D objects for this as they can be easily moved by using AffineTransforms.
Example code forthcoming....
All Gate objects can share the same interface,...
interface MyGate {
void draw(Graphics2D g2);
void setPoint(Point p);
Point getPoint();
boolean contains(Point p);
}
an example gate class that implements the above interface
class OrGate implements MyGate {
private Path2D path;
private Point point = new Point(0, 0); // initial Point
public OrGate() {
// initialize the Path2D and give it a winding rule
path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
// lots of "magic" numbers below, a code design "smell"
// better to not do this. Perhaps have a data file to hold
// this information, and have it read on program startup
int preX = 15;
int preY = 0;
int x1Points[] = { preX, preX + 50, preX + 60, preX + 70, preX + 80, preX + 70, preX + 60,
preX + 50, preX, preX + 10, preX + 20, preX + 30, preX + 20, preX + 10, preX };
int y1Points[] = { preY, preY, preY + 5, preY + 15, preY + 30, preY + 45, preY + 55,
preY + 60, preY + 60, preY + 55, preY + 45, preY + 30, preY + 15, preY + 5, preY };
path.moveTo(preX - 15, preY + 15);
path.lineTo(preX + 20, preY + 15);
path.moveTo(preX - 15, preY + 45);
path.lineTo(preX + 20, preY + 45);
path.moveTo(preX, preY);
for (int index = 1; index < x1Points.length; index++) {
path.lineTo(x1Points[index], y1Points[index]);
}
path.closePath();
}
#Override
public void draw(Graphics2D g2) {
// simple method that leverages the Path2D path object
g2.draw(path);
}
#Override
public boolean contains(Point p) {
// simple method that leverages the Path2D path object
return path.contains(p);
}
#Override
public Point getPoint() {
return point;
}
#Override
public void setPoint(Point p) {
Point pOld = this.point;
Point pNew = p;
this.point = p;
// create a transform that helps us move our Path2D
int tx = pNew.x - pOld.x;
int ty = pNew.y - pOld.y;
AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
path.transform(at); // and then move it
}
}
Main JPanel that shows use of the MouseAdapter and drawing/dragging of shapes:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class MainGates2 extends JPanel {
private static final int PREF_W = 700;
private static final int PREF_H = 600;
private List<MyGate> gates = new ArrayList<>();
public MainGates2() {
// create a few Gates
MyGate gate1 = new OrGate();
gate1.setPoint(new Point(200, 300)); // move this guy
MyGate gate2 = new OrGate();
// add them to the gates ArrayList
gates.add(gate1);
gates.add(gate2);
// create our mouse listener / adapter and add to JPanel
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// rendering hints to smooth graphics
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through collection and draw
for (MyGate myGate : gates) {
myGate.draw(g2);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
// give our JPanel some size
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
private MyGate selectedGate = null;
private Point p0; // initial Gate location
private Point p1; // first mouse press location
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
p1 = e.getPoint();
for (int i = gates.size() - 1; i >= 0; i--) {
if (gates.get(i).contains(e.getPoint())) {
selectedGate = gates.get(i);
p0 = selectedGate.getPoint();
return;
}
}
p1 = null;
}
#Override
public void mouseReleased(MouseEvent e) {
if (selectedGate != null) {
dragShape(e);
// de-select the gate
selectedGate = null;
p0 = null;
p1 = null;
}
}
public void mouseDragged(MouseEvent e) {
if (selectedGate != null) {
dragShape(e);
}
}
private void dragShape(MouseEvent e) {
Point p2 = e.getPoint(); // current mouse location
int x = p0.x + p2.x - p1.x;
int y = p0.y + p2.y - p1.y;
Point p = new Point(x, y);
selectedGate.setPoint(p);
repaint();
};
}
private static void createAndShowGui() {
// main JPanel
MainGates2 mainPanel = new MainGates2();
JFrame frame = new JFrame("Main Gates2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I have to draw line as the mouse moves, after the mouse click, the line should be continued to draw until double clicked.
Say point A, point B and point C. when mouse clicked at point A, the drawing of line should be started. when mouse is clicked on point B, the prev line should be there along with that new line should be started drawing from point B unless double clicked. Should be the same for point C and so on until the mouse is double clicked. After some research, I have written below code, it works perfectly fine, but it works for dragging NOT MOUSE MOVE event, I tried to transfer code to mouseMoved event but the prev lines are disappearing. Can someone help me fix this?
public class WorkingLines {
public WorkingLines() {
JFrame jf = new JFrame("Free Hand Drawing Example");
Board draw = new Board();
jf.add(draw);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(600, 500);
jf.setVisible(true);
}
public static void main(String a[]) {
new WorkingLines();
}
}
class Board extends JPanel implements MouseListener, MouseMotionListener {
ArrayList<pts> list = new ArrayList<pts>();
Point start, end;
public Board() {
start = null; /* Initializing */
end = null;
// this.setBackground(Color.BLACK);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
super.paint(g2);
// g.setColor(Color.BLACK);
for (pts p : list) {
System.out.println("Drawing Lines!!!=>");
g.drawLine((int) p.getStart().getX(), (int) p.getStart().getY(), (int) p.getEnd().getX(),
(int) p.getEnd().getY());
}
if (start != null && end != null) {
System.out.println("Drawing happening!!!=>");
g.drawLine(start.x, start.y, end.x, end.y);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent me) {
start = me.getPoint();
System.out.println("Start initialized!!");
for (pts pt : list) {
System.out.println("Point x coordinate =>" + pt.start.getX());
}
repaint();
}
#Override
public void mouseReleased(MouseEvent me) {
end = me.getPoint();
pts pt = new pts(start, end);
list.add(pt);
repaint();
if (me.getClickCount() == 2) {
start = null;
end = null;
}
}
#Override
public void mouseDragged(MouseEvent me) {
System.out.println("Mouse Moved=>" + start);
end = me.getPoint();
repaint();
}
#Override
public void mouseMoved(MouseEvent me) {
}
}
class pts {
Point start = null;
Point end = null;
public pts(Point start, Point end) {
this.start = start;
this.end = end;
}
public Point getStart() {
return this.start;
}
public Point getEnd() {
return this.end;
}
}
Note the flag added:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class WorkingLines {
public WorkingLines() {
JFrame jf = new JFrame("Free Hand Drawing Example");
JPanel draw = new DrawBoard();
jf.add(new Label("Click....move mouse, click again"), BorderLayout.NORTH);
jf.add(draw);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(600, 500);
jf.setVisible(true);
}
public static void main(String a[]) {
new WorkingLines();
}
}
class DrawBoard extends JPanel implements MouseListener, MouseMotionListener {
ArrayList<pts> list = new ArrayList<>();
Point start, end;
private boolean isDrawing = false; //a flag
public DrawBoard() {
start = null; end = null; /* Initializing */
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
super.paintComponent(g2);
for (pts p : list) {
g.drawLine((int) p.getStart().getX(), (int) p.getStart().getY(), (int) p.getEnd().getX(),
(int) p.getEnd().getY());
}
if ((start != null) && (end != null)) {
g.drawLine(start.x, start.y, end.x, end.y);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent me) {
if(! isDrawing) {
start = me.getPoint();
isDrawing = ! isDrawing;
}else {
pts pt = new pts(start, end);
list.add(pt);
start = end;
}
}
#Override
public void mouseReleased(MouseEvent me) {
if (me.getClickCount() == 2) {
start = null;
end = null;
isDrawing = false;
}
}
#Override
public void mouseDragged(MouseEvent me) {}
#Override
public void mouseMoved(MouseEvent me) {
end = me.getPoint();
repaint();
}
}
class pts {
Point start = null, end = null;
public pts(Point start, Point end) {
this.start = start;
this.end = end;
}
public Point getStart() { return start; }
public Point getEnd() { return end; }
}
Could you please help me to know how to
create a ColorImage object by using the default constructor of the ColorImage class?
create a Canvas object by calling the Canvas constructor with arguments. The first and second arguments of the constructor are the width and the height of the ColorImage. The width and height of a ColorImage have obtain by using the getWidth() and getHeight() methods in the ColorImage class.
public class MyPaint {
public static void main(String[] args) {
new PaintFrame("JavaPainter",100,300);
}
}
class MyCanvas extends JPanel implements MouseListener, MouseMotionListener {
private Vector<Point> curve;
private Vector<Vector<Point>> curves;
private Point ptFrom = new Point();
private Point ptTo = new Point();
MyCanvas() {
curve = new Vector<Point>();
curves = new Vector<Vector<Point>>();
this.setPreferredSize(new Dimension(1, 1));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
g.setColor(Color.RED);
for (Vector<Point> points : curves) {
Point pt0 = points.get(0);
for (int i = 1; i < points.size(); ++i) {
Point pt = points.get(i);
g.drawLine(pt0.x, pt0.y, pt.x, pt.y);
pt0 = pt;
}
}
}
#Override
public void mousePressed(MouseEvent e) {
ptFrom.x = e.getX();
ptFrom.y = e.getY();
curve.add((Point) ptFrom.clone());
}
#Override
public void mouseReleased(MouseEvent e) {
ptTo.x = e.getX();
ptTo.y = e.getY();
curve.add((Point) ptTo.clone());
curves.add(new Vector<Point>(curve));
curve.clear();
}
#Override
public void mouseDragged(MouseEvent e) {
ptTo.x = e.getX();
ptTo.y = e.getY();
curve.add((Point) ptTo.clone());
Graphics g = getGraphics();
g.setColor(Color.RED);
g.drawLine(ptFrom.x, ptFrom.y, ptTo.x, ptTo.y);
ptFrom.x = ptTo.x;
ptFrom.y = ptTo.y;
}
#Override
public void mouseEntered(MouseEvent e) {
// do nothing
}
#Override
public void mouseExited(MouseEvent e) {
// do nothing
}
#Override
public void mouseClicked(MouseEvent e) {
// do nothing
}
#Override
public void mouseMoved(MouseEvent e) {
// do nothing
}
}
class PaintFrame extends JFrame {
private MyCanvas canvas = new MyCanvas();
PaintFrame(String title) {
super(title);
Container cp = getContentPane();
cp.add(canvas);
setSize(300, 200);
setVisible(true);
}
PaintFrame(String title,Integer length,Integer width) {
super(title);
Container cp = getContentPane();
cp.add(canvas);
setSize(width, length);
setVisible(true);
}
}
From other place http://blog.csdn.net/fduan/article/details/8062556
I'm attempting to implement the dragging functionality of shapes on a canvas. My Shape class inherits from JPanel.
Absolutely nothing happens when I click on a shape, drag it and let go of the mouse button. It just remains where it was originally. Any ideas?
You need a few basic things:
A field for the shape itself (you already had)
Fields to keep track of the offset of the click within the shape (already had)
A field to keep track of if you're dragging
Overwrite the paintComponent method to paint your shape
A MouseListener and MouseMotionListener added to the Panel (MouseAdapter does both of these)
Here's a basic working example.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DrawTest extends JPanel{
//Shape doesn't have a location field - you'd have to keep track of
//this yourself if you're set on using the shape interface
private Rectangle shape = new Rectangle(100, 100);
// The location within the shape you clicked
private int xOffset = 0;
private int yOffset = 0;
// To indicate dragging is happening
boolean isDragging = false;
public DrawTest(){
MouseAdapter listener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// Starts dragging and calculates offset
if(shape.contains(e.getPoint())){
isDragging = true;
xOffset = e.getPoint().x - shape.x;
yOffset = e.getPoint().y - shape.y;
}
}
#Override
public void mouseReleased(MouseEvent e) {
// Ends dragging
isDragging = false;
}
#Override
public void mouseDragged(MouseEvent e) {
// Moves the shape - doesn't actually need to be a method
// but is because you had it as one
if(isDragging){
moveShape(e);
}
}
private void moveShape(MouseEvent e) {
Point newLocation = e.getPoint();
newLocation.x -= xOffset;
newLocation.y -= yOffset;
shape.setLocation(newLocation);
repaint();
}
};
//Add a mouse mostion listener (for dragging) and regular listener (for clicking)
addMouseListener(listener);
addMouseMotionListener(listener);
}
// So we have a play area to work with
public Dimension getPreferredSize(){
return new Dimension(400,300);
}
//Paints the shape
public void paintComponent(Graphics g){
super.paintComponent(g);
g.clearRect(0,0,getWidth(), getHeight());
g.fillRect(shape.x, shape.y, shape.width, shape.height);
}
public static void main(String[] args)
{
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Tried a small simple example
Dragging the rectangle will make it move with the cursor it also checks the bounds so the rectangle cannot be dragged off screen:
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, 100, 50)) {
return true;
}
int new_x = rect.x;
int new_y = rect.y;
if ((rect.x + 100) > area.getWidth()) {
new_x = (int) area.getWidth() - 99;
}
if (rect.x < 0) {
new_x = -1;
}
if ((rect.y + 50) > area.getHeight()) {
new_y = (int) area.getHeight() - 49;
}
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();
}
}
}
Reference:
http://www.java2s.com/Code/Java/Event/MoveShapewithmouse.htm