Free line drawing java2d app connects lines of each new drawing - java

I'm building an app that recognises lines drawn with mouse and creates music. I'm new to java2d so heres the problem i'm having:
When you draw, and then make another drawing, the last point of the previous drawing connects to the first of the new one. I havent been able to figure out how to fix this. Below is the code.
Another question is: I would like to store each stroke of drawing (from mousePressed to mouseReleased) into a ArrayList of type Shape, how can I go into that?
I'd like to be pointed in the right direction as I havent been able to find helpful info online. Thanks!
public class DrawBoard extends JPanel implements MouseListener,
MouseMotionListener {
public JLabel status;
public Point pstart, pfinish;
private Shape currentShape = null;
private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Shape> lines = new ArrayList<Shape>();
public DrawBoard() {
Dimension size = getPreferredSize();
size.setSize(1024, 800); // w, h
setPreferredSize(size);
setOpaque(false);
status = new JLabel("default");
add(status, BorderLayout.SOUTH);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
status.setText(String.format("Clicked at %d,%d", e.getX(), e.getY()));
}
// Where the drawing happens
#Override
public void mousePressed(MouseEvent e) {
status.setText("you pressed down the mouse");
this.pstart = e.getPoint();
}
#Override
public void mouseDragged(MouseEvent e) {
status.setText("you draged the mouse");
points.add(e.getPoint());
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
status.setText("you release the mouse click");
pfinish = e.getPoint();
}
// End of where the drawing happens
#Override
public void mouseEntered(MouseEvent e) {
status.setText("you entered the area");
}
#Override
public void mouseExited(MouseEvent e) {
status.setText("mouse exited the area");
}
#Override
public void mouseMoved(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet.");
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(5));
for (int i = 0; i < points.size() - 2; i++) {
Point p1 = points.get(i);
Point p2 = points.get(i + 1);
g2.drawLine(p1.x, p1.y, p2.x, p2.y);
}
}
}
I have modified it using BufferedImage and it works for drawing normally, now the only thing does nto work is the clear method, i have tried different methods but none have worked. My new code is Below:
public class DrawBoard extends JPanel implements MouseListener, MouseMotionListener{
public JLabel status;
private JLabel imgLabel;
public Point pstart, pfinish;
private Shape currentShape = null;
private List<Point> points = new ArrayList<Point>();
private List<BufferedImage> lines = new ArrayList<BufferedImage>();
private static final int BI_WIDTH = 1024;
private static final int BI_HEIGHT = 800;
private BufferedImage bImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
BufferedImage.TYPE_INT_ARGB);
public DrawBoard(){
Graphics2D g2d = bImage.createGraphics();
g2d.dispose();
Dimension size = getPreferredSize();
size.setSize(1024,800); //w, h
setPreferredSize(size);
status = new JLabel("default");
add(status, BorderLayout.SOUTH);
addMouseListener(this);
addMouseMotionListener(this);
imgLabel = new JLabel(new ImageIcon(bImage)) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintInLabel(g);
}
};
imgLabel.setOpaque(false);
setOpaque(false);
add(imgLabel, BorderLayout.CENTER);
}
private void paintInLabel(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE); // this colour is when mouse is pressed
g2d.setStroke(new BasicStroke(5));
if (points.size() < 2) {
return;
}
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
#Override
public void mouseClicked(MouseEvent e) {
status.setText(String.format("Clicked at %d,%d", e.getX(), e.getY()));
}
// Where the drawing happens
#Override
public void mousePressed(MouseEvent e) {
status.setText("you pressed down the mouse");
this.pstart = e.getPoint();
points.add(e.getPoint());
}
#Override
public void mouseDragged(MouseEvent e) {
status.setText("you draged the mouse");
points.add(e.getPoint());
imgLabel.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
status.setText("you release the mouse click");
Graphics2D g2d = bImage.createGraphics();
g2d.setColor(Color.blue); // this is the final colour
g2d.setStroke(new BasicStroke(5));
if (points.size() >= 2) {
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
g2d.dispose();
points.clear();
imgLabel.repaint();
}
// End of where the drawing happens
#Override
public void mouseEntered(MouseEvent e) {
status.setText("you entered the area");
}
#Override
public void mouseExited(MouseEvent e) {
status.setText("mouse exited the area");
}
#Override
public void mouseMoved(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void clearDrawBoard() {
imgLabel.setIcon(null);
}
}

A few solutions and suggestions:
Don't draw from a single List<Point> as there's no way of knowing where one line ends and another begins.
Consider drawing each line to a BufferedImage once it is complete and display that BufferedImage in your JComponent in its paintComponent method. You would place it in the BufferedImage in the mouseReleased(...) method.
Or consider creating an List<List<Point>> so you can iterate through each line as needed. You would add the new List<Point> to the original List in the mouseReleased(...) method.
Consider using your List<Shape> and fill it with Line2D objects that can be drawn. The Line2D would be added to the List<Shape> in the mouseReleased(...) method.
Also: You should not override paint(...) but rather `paintComponent(...).
Also: Don't forget the #Override annotation for safer coding.
For example, please see my code and answer here.

Related

Trouble With Color Changing In My Java Swing Paint Application

Should I still be practicing Java Swing?
I'm trying to add functionality to my Java Swing Paint Application by adding a choice to change brush colors. However, when I'm finished choosing a different color in the color chooser, all of the old marks change into that chosen color along with my new line marks. I wanted the old marks to stay the same color as before.
(Pictures below)
Using black ink. Drawing something.
Deciding to change the color to green
Both the old AND new lines change to green.
This is not the entire application(tell me if you need the rest), but I believe the problem has something to do with incorrect table manipulation. The "shapeFill" table which matches colors to the lines("shapes" table) is not working correctly.
public class TestPane extends JComponent{
private List<List<Point>> points;
private ArrayList<Shape> shapes = new ArrayList<Shape>();
public TestPane() {
points = new ArrayList<>(100);
MouseAdapter ma = new MouseAdapter() {
private List<Point> currentPath;
#Override
public void mousePressed(MouseEvent e) {
currentPath = new ArrayList<>(100);
currentPath.add(e.getPoint());
points.add(currentPath);
}
#Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
currentPath.add(dragPoint);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
currentPath = null;
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Iterator<Color> fillCounter = shapeFill.iterator();
for(Shape s : shapes) { // I believe problem is somewhere around here?
g2d.setPaint(fillCounter.next());
g2d.setStroke(new java.awt.BasicStroke(10));
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (List<Point> path : points) {
Point from = null;
for (Point p : path) {
if (from != null) {
Shape line = new Line2D.Float(from.x, from.y, p.x, p.y);
g2d.draw(line);
shapes.add(line);
shapeFill.add(lineColor);
}
from = p;
}
}
g2d.dispose();
}
}
public JButton createButton(String title) {
JButton button = new JButton(title);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == colorChooser) {
Color chooser = JColorChooser.showDialog(null, "Select color", lineColor);
lineColor = chooser;
shapeFill.add(chooser);
repaint();
}else if(e.getSource() == shapeFillArrayList) {
System.out.print("\n");
for(Color index : shapeFill) {
System.out.println(index);
}
}
}
});
return button;
}

Drawing shape on mouse drag

class MyPanel extends JPanel implements Observer, MouseMotionListener, MouseListener {
private MyModel model;
private View view;
private String mode;
private Rectangle rectangle;
private Square square;
public MyPanel(MyModel model, View view) {
this.setBackground(Color.black);
this.setPreferredSize(new Dimension(300, 300));
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.model = model;
this.model.addObserver(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
ArrayList<Rectangle> rectangles = this.model.getRectangles();
for (Rectangle r : getRectangles()) {
int width = Math.abs(r.getStartPoint().getX() - r.getEndPoint().getX());
int height = Math.abs(r.getStartPoint().getY() - r.getEndPoint().getY());
}
ArrayList<Square> squares = this.model.getSquares();
for (Square sqr : getSquares()) {
int xPosition = Math.min(sqr.getStartPoint().getX(), sqr.getEndPoint().getX());
int yPosition = Math.min(sqr.getStartPoint().getY(), sqr.getEndPoint().getY());
int width = Math.abs(sqr.getStartPoint().getX() - sqr.getEndPoint().getX());
int height = Math.abs(sqr.getStartPoint().getY() - sqr.getEndPoint().getY());
}
g2d.dispose();
}
public void update(Observable o, Object arg) {
this.repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (this.mode.equals("Rectangle")) {
this.rectangle.setEndPoint(e.getX(), e.getY());
this.model.addRectangle(this.rectangle);
}
else if (this.mode.equals("Square")) {
// What code should I add here?
this.model.addSquare(this.square);
}
}
// MouseListener below
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {
if (this.mode.equals("Rectangle")) {
this.rectangle = new Rectangle(e.getX(), e.getY());
}
else if (this.mode.equals("Square")) {
this.square = new Square(e.getX(), e.getY());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (this.mode.equals("Rectangle")) {
this.rectangle.setEndPoint(e.getX(), e.getY());
this.model.addRectangle(this.rectangle);
this.rectangle = null;
}
else if (this.mode.equals("Square")) {
this.model.addSquare(this.square);
this.square = null;
}
}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
}
The user chooses a mode, rectangle or square. Then they can draw a square or a rectangle with their mouse (live feedback is shown). Here is my drawing panel class. I was successfully able to implement the rectangle mode. The user can draw a rectangle and as they move their mouse, the rectangle is shown in mid construction. I want to do the same for the square mode. For some reason, I'm having a hard time doing this. How would I show a perfect square in mid construction when the user is moving their mouse and how would I draw it once released? What code should I add to my paintComponent method, mouseDragged, mousePressed and mouseReleased method to do this? It was easy for a rectangle because there was no constraint but I'm not sure how to do it for a square with my current implementation.
int width = Math.abs(r.getStartPoint().getX() - r.getEndPoint().getX());
int height = Math.abs(r.getStartPoint().getY() - r.getEndPoint().getY());
I would guess that the "size" of the square would be the maximum of the above two values.
Then I would think you would just use:
r.drawStyle(g2d, xPosition, yPosition, size, size);

Java Graphics2D to erase to a alpha background

I'm making an application that has a drawing board where you draw with your mouse, it draws ontop of an Label in a BUfferedImage. What I'm trying to implement right now is an eraser, the problem is I cannot find anywhere help to make an eraser to clearRect() to an alpha background. (I cannot have a defined color background since the user can change the background to any image he wants). To sum up:
How can you erase/overwrite Graphics2D pixels with alpha pixels? The way i found was with clearRect but you need to specify a background color.
The following is my DrawBoard class which constains everything to draw.
public class DrawBoard extends JPanel implements MouseListener, MouseMotionListener{
public JLabel status;
private JLabel imgLabel; // this is where the drawing happens
public Point pstart, pfinish;
private List<Point> points = new ArrayList<Point>();
private List<BufferedImage> lines = new ArrayList<BufferedImage>();
private static final int BI_WIDTH = 1024;
private static final int BI_HEIGHT = 800;
private static int STROKESIZE = 7;
private BufferedImage bImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
BufferedImage.TYPE_INT_ARGB);
public Color currentColor;
public static boolean eraser = false;
private int xX1, yY1;
public DrawBoard(){
Graphics2D g2d = bImage.createGraphics();
g2d.dispose();
Dimension size = getPreferredSize();
size.setSize(1024,800); //w, h
setPreferredSize(size);
//status = new JLabel("default");
//add(status, BorderLayout.SOUTH);
addMouseListener(this);
addMouseMotionListener(this);
imgLabel = new JLabel(new ImageIcon(bImage)) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintInLabel(g);
}
};
imgLabel.setOpaque(false);
setOpaque(false);
add(imgLabel, BorderLayout.CENTER);
}
private void paintInLabel(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getColor()); // this colour is when mouse is pressed
g2d.setStroke(new BasicStroke(STROKESIZE));
if (points.size() < 2) {
return;
}
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
#Override
public void mouseExited(MouseEvent e){
}
#Override
public void mouseEntered(MouseEvent e){
}
#Override
public void mouseMoved(MouseEvent e){
}
// Where the drawing happens
#Override
public void mousePressed(MouseEvent e) {
//status.setText("you pressed down the mouse");
xX1 = e.getX();
yY1 = e.getY();
points.add(e.getPoint());
}
#Override
public void mouseDragged(MouseEvent e) {
//status.setText("you draged the mouse");
points.add(e.getPoint());
imgLabel.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
//status.setText("you release the mouse click");
Graphics2D g2d = bImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getColor()); // this is the final colour
g2d.setStroke(new BasicStroke(STROKESIZE));
if (points.size() >= 2) {
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
g2d.dispose();
points.clear();
imgLabel.repaint();
}
// End of where the drawing happens
public void clearDrawBoard() {
}
private Color getColor() {
return ColourToolbar.selectedColor;
}
private void setColor(Color col){
this.currentColor = col;
}
#Override
public void mouseClicked(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
}
You should set a custom Composite for your Graphics2D, specifically AlphaComposite.Clear before drawing the rectangle. Don't forget to reset the composite to the default (SRC_OVER) when you are done, because the same Graphics object will be reused to paint other components.

Add panel ontop of panel and both are visible

I'm making a music/drawing application which you free draw lines with your mouse and a TrackBar passes horizontally through it and reads the lines and uses the x and y coordinate to modify music.
The problem I'm having is that TrackBar class is a JPanel and DrawBoard class is a JPanel which I add inside a Frame. But which ever is on-top is the one that will show, what I want is for them to both show, and the TrackBar to pass on top of the lines drawn.
Below Is the source code of this 3 classes and took out some unncesesary code:
The MainFrame class where I add them (with the current setup the TrackBar doesnt appear but the Drawing board appears since it overlaps it):
public class MainFrame extends JFrame {
public static ColourToolbar colourBar;
public static TrackBar tb;
public MainFrame(){
super("VIPE by Prestige WorldWide");
// Top colour toolbar for tones
colourBar = new ColourToolbar();
this.getContentPane().add(colourBar, BorderLayout.NORTH);
// This class ImagePanel is a JPanel which I overite the paintCOmponent to have background
ImagePanel bg = new ImagePanel();
bg.setLayout(new BorderLayout());
Dimension size = getPreferredSize();
size.setSize(1024,800); //w, h
bg.setPreferredSize(size);
this.getContentPane().add(bg, BorderLayout.CENTER);
// I add the TrackBar to the ImagePanel since its the Background
tb = new TrackBar();
bg.add(tb, BorderLayout.CENTER);
// I add the drawing board but It will overlap the Trackbar
DrawBoard dboard = new DrawBoard();
bg.add(dboard, BorderLayout.CENTER);
// The control toolbar where the settings and control buttons are.
Toolbar toolBar = new Toolbar();
this.getContentPane().add(toolBar, BorderLayout.SOUTH);
}
public static void main(String[] args){
MainFrame frame = new MainFrame();
frame.setBackground(Color.WHITE);
frame.setSize(1024,768);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
//frame.pack();
frame.setVisible(true);
}
}
Now the TrackBar class:
public class TrackBar extends JPanel{
private TrackBarAction tba = new TrackBarAction(this);
public static int TIME = 9;
public Timer t = new Timer(TIME, tba);
public static double x = 0, y = 0, velX = 1.0, velY = 0;
private int SKIP = 120;
public TrackBar(){
this.setOpaque(false);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
//g2d.drawRect((int)x, (int)y, 10, 800);
Rectangle2D r2d = new Rectangle2D.Double(x, y, 8.0, 800.0); // x,x, w, h
g2d.setPaint(Color.DARK_GRAY);
g2d.fill(r2d);
g2d.draw(r2d);
}
public void reset(){
t.stop();
x = 0;
y = 0;
velX = 0.5;
velY = 0;
this.repaint();
}
public void skipForward(){
if(x+SKIP <= 1024){
x += SKIP;
} else {
x = 1024 - x;
}
this.repaint();
}
public void skipBackwards(){
if(x-SKIP >= 0){
x -= SKIP;
} else {
x = 0;
}
this.repaint();
}
}
And now the DrawBoard class:
public class DrawBoard extends JPanel implements MouseListener, MouseMotionListener{
(..)
public Color currentColor;
public static boolean eraser = false;
private int xX1, yY1;
public DrawBoard(){
Graphics2D g2d = bImage.createGraphics();
g2d.dispose();
Dimension size = getPreferredSize();
size.setSize(1024,800); //w, h
setPreferredSize(size);
//status = new JLabel("default");
//add(status, BorderLayout.SOUTH);
addMouseListener(this);
addMouseMotionListener(this);
imgLabel = new JLabel(new ImageIcon(bImage)) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintInLabel(g);
}
};
imgLabel.setOpaque(false);
setOpaque(false);
add(imgLabel, BorderLayout.CENTER);
}
private void paintInLabel(Graphics g) {
if(!eraser){
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getColor()); // this colour is when mouse is pressed
g2d.setStroke(new BasicStroke(STROKESIZE));
if (points.size() < 1) {
return;
}
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
}
// Where the drawing happens
#Override
public void mousePressed(MouseEvent e) {
//status.setText("you pressed down the mouse");
if(!eraser){
xX1 = e.getX();
yY1 = e.getY();
points.add(e.getPoint());
}
}
#Override
public void mouseDragged(MouseEvent e) {
//status.setText("you draged the mouse");
Graphics2D g2d = bImage.createGraphics();
// this is the eraser code
if(eraser){
//Graphics2D g2d = bImage.createGraphics();
System.out.println("eraser = true");
System.out.println("Stroke = " + STROKESIZE);
g2d.setComposite(AlphaComposite.Clear);
g2d.setColor(new Color(0, 0, 0, 0));
g2d.drawRect(e.getX(), e.getY(), STROKESIZE, STROKESIZE);
g2d.fillRect(e.getX(), e.getY(), STROKESIZE, STROKESIZE);
// g2d.setColor(c);
imgLabel.repaint();
}else {
//g2d.setComposite();
points.add(e.getPoint());
System.out.println("point = " + e.getPoint());
imgLabel.repaint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
//status.setText("you release the mouse click");
if(!eraser){
Graphics2D g2d = bImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getColor()); // this is the final colour
g2d.setStroke(new BasicStroke(STROKESIZE));
if (points.size() >= 2) {
for (int i = 1; i < points.size(); i++) {
int x1 = points.get(i - 1).x;
int y1 = points.get(i - 1).y;
int x2 = points.get(i).x;
int y2 = points.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
g2d.dispose();
points.clear();
imgLabel.repaint();
}
//imgLabel.repaint();
}
// End of where the drawing happens
public void clearDrawBoard() {
}
private Color getColor() {
return ColourToolbar.selectedColor;
}
private void setColor(Color col){
this.currentColor = col;
}
#Override
public void mouseClicked(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
}
BorderLayout can only have one component add to each of it a 5 positions. By adding the DrawPanel to the center position, you are effectively removing the TrackPanel.
Instead, set the layout manager of the TrackBar to BorderLayout and add the DrawPanel to it.
You could also use a JLayeredPane, but the management becomes more involved

java draw line as the mouse is moved

I would like to add a feature to my application which allows the user to draw a straight line by clicking the mouse at the start location and releasing it at the end location. The line should move as the mouse moves until it is finally released; similar to the way that a line can be drawn using the Microsoft Paint application.
How can implement this so that the line is repainted as it moves without repainting other things that may already be drawn in that rectangular area?
Try this...Draw a red line on the screen as the mouse is moved (dragged).
public static void main(String args[]) throws Exception {
JFrame f = new JFrame("Draw a Red Line");
f.setSize(300, 300);
f.setLocation(300, 300);
f.setResizable(false);
JPanel p = new JPanel() {
Point pointStart = null;
Point pointEnd = null;
{
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
pointStart = e.getPoint();
}
public void mouseReleased(MouseEvent e) {
pointStart = null;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
pointEnd = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
pointEnd = e.getPoint();
repaint();
}
});
}
public void paint(Graphics g) {
super.paint(g);
if (pointStart != null) {
g.setColor(Color.RED);
g.drawLine(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
}
}
};
f.add(p);
f.setVisible(true);
}
The MouseListener interface is your friend for this. You can just implement mousePressed and mouseReleased functions. The MouseListener interface has the following methods that you can play around with:
public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mousePressed(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }
JFrame frame = new JFrame("Lines");
frame.add(new JComponent() {
private Shape line = null;
{
line = new Line2D.Double(100, 100, 200, 200);
prevPoint = new Point();
newPoint = new Point();
MouseAdapter mouseAdapter = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
prevPoint = e.getPoint();
System.out.println("Prev Point=" + prevPoint.toString());
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
int dx = 0;
int dy = 0;
dx = (int) (prevPoint.x - e.getPoint().getX());
dy = (int) (prevPoint.y - e.getPoint().getY());
Line2D shape = (Line2D) line;
int x1 = (int) (shape.getX1() - dx);
int y1 = (int) (shape.getY1() - dy);
int x2 = (int) (shape.getX2() - dx);
int y2 = (int) (shape.getY2() - dy);
Point startPoint = new Point(x1, y1);
Point endPoint = new Point(x2, y2);
if (shape != null) {
shape.setLine(startPoint, endPoint);
prevPoint = e.getPoint();
repaint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
repaint();
}
};
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(Color.BLUE);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (line != null) {
g2d.draw(line);
}
}
});
frame.setSize(650, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
This will move the line as the mouse is moved..
Hope this helps..

Categories

Resources