I am trying to draw some shapes(line, circle, rectangle) in a jpanel by using bufferdimage. so i tried the belove code.it works on buffering shapes but the problem is by dragging mouse it draws the shape like every single frame.
here is the code `
public class PanelClass extends JPanel {
BufferedImage img;
int x1,y1,x2,y2,StarterX,StarterY, h,w;
static int flag;
Graphics2D g2d ;
public PanelClass() {
MouseHandler handler = new MouseHandler();
this.addMouseListener(handler);
this.addMouseMotionListener(handler);
i made an object of bufferdimage here
img = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) img.getGraphics();
}
these parts are just because of getting the Coordinates of starting point of mouse events
public void starter(int oldX,int oldY){
x1 = oldX;
y1 = oldY;
}
public void finisher(int currentX,int currentY){
x2 = currentX;
y2 = currentY;
if(x1 > x2){
StarterX = x2;
}
else if(x2 > x1){
StarterX = x1;
}
if(y1 > y2){
StarterY = y2;
}
else if(y2 > y1){
StarterY = y1;
}
}
public int Diameter(int oldX,int oldY,int currentX,int currentY){
return (int) Math.sqrt ( (Math.pow(currentX - oldX, 2)) + (Math.pow(currentY - oldY, 2) ) ) ;
}
this method gets the coordinates and orders to paint.(this is just for making code a bit clear i use this method on paintComponent() )
public void painter(){
if(flag ==1){
g2d.setColor(Color.ORANGE);
g2d.setStroke(new BasicStroke(3.0f));
g2d.drawOval(StarterX ,StarterY,Diameter(x1, y1, x2, y2),Diameter(x1, y1, x2, y2));
g2d.setBackground(Color.YELLOW);
}
else if(flag == 2){
//fill oval;
g2d.setColor(Color.ORANGE);
g2d.setBackground(Color.YELLOW);
g2d.fillOval(StarterX ,StarterY,Diameter(x1, y1, x2, y2),Diameter(x1, y1, x2, y2) );
}
else if (flag == 3){
g2d.setColor(Color.ORANGE);
g2d.setStroke(new BasicStroke(3.0f));
g2d.drawRect(StarterX, StarterY,Math.abs(x2-x1) ,Math.abs(y2-y1));
g2d.setBackground(Color.YELLOW);
}
else if (flag == 4){
g2d.setColor(Color.ORANGE);
g2d.fillRect(StarterX, StarterY,Math.abs(x2-x1) ,Math.abs(y2-y1));
g2d.setBackground(Color.YELLOW);
}
else if (flag == 5){
g2d.setColor(Color.ORANGE);
g2d.setStroke(new BasicStroke(5.0f));
g2d.drawLine(x1, y1,x2,y2);
g2d.setBackground(Color.YELLOW);
}
}
public void flagSetter(int flag){
this.flag = flag;
}
at this method i used g.drawImage()
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
painter();
g.drawImage(img, 0,0, null);
}
class MouseHandler implements MouseListener,MouseMotionListener{
#Override
public void mousePressed(MouseEvent e) {
starter(e.getX(),e.getY());
}
#Override
public void mouseReleased(MouseEvent e) {
finisher(e.getX(),e.getY());
g2d.drawImage(img,0,0 ,null);
repaint();
if(flag == 1){
}
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseDragged(MouseEvent e) {
finisher(e.getX(),e.getY() );
// System.out.printf("%d %d ",currentX,currentY);
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
}
}`
actully i have no idea why it acts like that
So, the primary issue is the use of the BufferedImage, basically, you have to think of a BufferedImage like a real world canvas, once you paint something to it, it will remain (until you paint over it or clear it).
Overall, a better solution would be to follow a custom painting route and store the information you want painted in some kind of model.
This way, you update to the model, schedule a paint pass and when paintComponent is called, you paint the current state of the model.
For example:
Moving an Ellipse that has been drawn
Getting the (starting) X and Y coordinates of a Path2D shape drawn on Jpanel
Easier way to make a paint application in java?
Related
I want to implement a Rectangle shape feature exactly as in Paint in JAVA. I have built a program as following. I have built a class MyPaint where buttons and frame are defined. I have built another class inside the same program PadDraw, where a drawing pad is created where I can draw with pencil like in Paint. Then I have another class outside the program DrawRect where the rectangle shape feature is created.
I want to know if there is a way to integrate the rectangle in a way that if I click a button "Rectangle", the way of drawing should change and instead of drawing with pencil, I should draw rectangle shapes exactly like in Paint when the rectangle shape is pressed.
The piece of code for PadDraw class is as following:
class PadDraw extends JComponent {
private Image image;
private Graphics2D graphics2D;
private int currentX , currentY , oldX , oldY ;
public PadDraw(){
setDoubleBuffered(false);
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
currentX = e.getX();
currentY = e.getY();
if(graphics2D != null)
graphics2D.drawLine(oldX, oldY, currentX, currentY);
repaint();
oldX = currentX;
oldY = currentY;
}
});
}
public void paintComponent(Graphics g){
if(image == null){
image = createImage(getSize().width, getSize().height);
graphics2D = (Graphics2D)image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 5, 5, null);
}
While the piece of code of DrawRect class that I want to integrate in the program where MyPaint and PadDraw class are located is as following:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DrawRect extends JPanel {
int x, y, x2, y2;
public static void main(String[] args) {
JFrame f = new JFrame("Draw Box Mouse 2");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new DrawRect());
f.setSize(300, 300);
f.setVisible(true);
}
DrawRect() {
x = y = x2 = y2 = 0; //
MyMouseListener listener = new MyMouseListener();
addMouseListener(listener);
addMouseMotionListener(listener);
}
public void setStartPoint(int x, int y) {
this.x = x;
this.y = y;
}
public void setEndPoint(int x, int y) {
x2 = (x);
y2 = (y);
}
public void drawPerfectRect(Graphics g, int x, int y, int x2, int y2) {
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
g.drawRect(px, py, pw, ph);
}
class MyMouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
setStartPoint(e.getX(), e.getY());
}
public void mouseDragged(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
repaint();
}
public void mouseReleased(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
repaint();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
drawPerfectRect(g, x, y, x2, y2);
}
}
I'm trying to build Paint app and I doing something wrong in DrawingArea class.
The problem is when I try to draw second shape , the first shape or figure is auto deleting so I need to some idea about how to solve this.All answers acceptable.
THANKS FOR HELP.
There is part of DrawingArea.class codes :
#Override // GETTING FIRST (STARTING) COORDINATE WHEN THE MOUSE PRESSED
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
repaint();
}
#Override // GETTING RELEASED COORDINATE TO DRAW LINE.
public void mouseReleased(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
repaint();
}
public void mouseClicked(MouseEvent e) {
clickedX = true;
COUNT = e.getClickCount();
}
// GETTING COORDINATE TO DRAW FILLEDRECT,FILLEDOVAL,OVAL,RECT.
public void mouseDragged(MouseEvent e) {
draggedX = e.getX();
draggedY = e.getY();
repaint();
width = Math.abs(oldX - draggedX);
height = Math.abs(oldY - draggedY);
x = Math.min(draggedX, oldX);
y = Math.min(draggedY, oldY);
}
public void mouseMoved(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// CLEAR THE ALL SHAPES DRAWED ON DRAW AREA.
public void clear() {
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, (int) this.getWidth() + 55, (int) this.getHeight() + 55);
super.repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) {
image = new BufferedImage((int) this.getWidth(), (int) this.getHeight(), BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
g2.dispose();
g.setColor(initialColor);
if (shape == Shapers.PENCIL) {
g.setColor(currentColor);
g.fillOval(draggedX, draggedY, thickness, thickness);
} else if (shape == Shapers.OVAL) {
g.setColor(currentColor);
g.drawOval(oldX, oldY, draggedX, draggedX);
} else if (shape == Shapers.FILLEDOVAL) {
g.setColor(currentColor);
g.fillOval(oldX, oldY, draggedX, draggedY);
} else if (shape == Shapers.RECT) {
g.setColor(currentColor);
g.drawRect(x, y, width, height);
} else if (shape == Shapers.FILLEDRECT) {
g.setColor(currentColor);
g.fillRect(x, y, width, height);
} else if (shape == Shapers.LINE) {
g.setColor(currentColor);
g.drawLine(oldX, oldY, draggedX, draggedY);
oldX = draggedX;
oldY = draggedY;
} else if (shape == Shapers.ERASER) {
g.setColor(Color.WHITE);
g.fillRect(draggedX, draggedY, thickness, thickness);
} else if (shape == Shapers.TEXT) {
if (clickedX == true || COUNT == 2) {
String str = JOptionPane.showInputDialog("Write Your Text Here : ");
g.setFont(myFont);
g.setColor(currentColor);
if (str != null) {
g.drawString(str, oldX, oldY);
COUNT = 0;
} else {
return;
}
}
} else {
COUNT = 0;
return;
}
}
}
You need to either:
Store shapes to be painted in a List and then in the paintComponent() method you paint all the shapes in the List, or
Paint your shapes to a BufferedImage and then just paint the BufferedImage
Check out Custom Painting Approaches for working examples of both approaches and use the approach that best meets your requirement.
I'm trying to build Paint app and I doing something wrong in DrawingArea class.
The problem is when I try to draw second shape , the first shape or figure is auto deleting so I need to some idea about how to solve this.All answers acceptable.
THANKS FOR HELP.
There is part of DrawingArea.class codes :
#Override // GETTING FIRST (STARTING) COORDINATE WHEN THE MOUSE PRESSED
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
repaint();
}
#Override // GETTING RELEASED COORDINATE TO DRAW LINE.
public void mouseReleased(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
repaint();
}
public void mouseClicked(MouseEvent e) {
clickedX = true;
COUNT = e.getClickCount();
}
// GETTING COORDINATE TO DRAW FILLEDRECT,FILLEDOVAL,OVAL,RECT.
public void mouseDragged(MouseEvent e) {
draggedX = e.getX();
draggedY = e.getY();
repaint();
width = Math.abs(oldX - draggedX);
height = Math.abs(oldY - draggedY);
x = Math.min(draggedX, oldX);
y = Math.min(draggedY, oldY);
}
public void mouseMoved(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// CLEAR THE ALL SHAPES DRAWED ON DRAW AREA.
public void clear() {
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, (int) this.getWidth() + 55, (int) this.getHeight() + 55);
super.repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) {
image = new BufferedImage((int) this.getWidth(), (int) this.getHeight(), BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
g2.dispose();
g.setColor(initialColor);
if (shape == Shapers.PENCIL) {
g.setColor(currentColor);
g.fillOval(draggedX, draggedY, thickness, thickness);
} else if (shape == Shapers.OVAL) {
g.setColor(currentColor);
g.drawOval(oldX, oldY, draggedX, draggedX);
} else if (shape == Shapers.FILLEDOVAL) {
g.setColor(currentColor);
g.fillOval(oldX, oldY, draggedX, draggedY);
} else if (shape == Shapers.RECT) {
g.setColor(currentColor);
g.drawRect(x, y, width, height);
} else if (shape == Shapers.FILLEDRECT) {
g.setColor(currentColor);
g.fillRect(x, y, width, height);
} else if (shape == Shapers.LINE) {
g.setColor(currentColor);
g.drawLine(oldX, oldY, draggedX, draggedY);
oldX = draggedX;
oldY = draggedY;
} else if (shape == Shapers.ERASER) {
g.setColor(Color.WHITE);
g.fillRect(draggedX, draggedY, thickness, thickness);
} else if (shape == Shapers.TEXT) {
if (clickedX == true || COUNT == 2) {
String str = JOptionPane.showInputDialog("Write Your Text Here : ");
g.setFont(myFont);
g.setColor(currentColor);
if (str != null) {
g.drawString(str, oldX, oldY);
COUNT = 0;
} else {
return;
}
}
} else {
COUNT = 0;
return;
}
}
}
You need to either:
Store shapes to be painted in a List and then in the paintComponent() method you paint all the shapes in the List, or
Paint your shapes to a BufferedImage and then just paint the BufferedImage
Check out Custom Painting Approaches for working examples of both approaches and use the approach that best meets your requirement.
I have a problem in my program with the custom drawing part.
I want the user to click on the interface and then drag while the program draw a line which follow the cursor.
But the problem is, I can barely see it. Also, the line won't stay after the cursor's button release.
Custom draw line code:
public void drawTemporaryLine(int x1,int y1,int x2,int y2,ArrayList<Line> lines){
repaint();
g2d = (Graphics2D) getGraphics();
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.black);
for(Line l:lines){
g2d.drawLine(l.getX1(),l.getY1(),l.getX2(),l.getY2());
}
g2d.drawLine(x1, y1, x2, y2);
}
Mouse listener code:
#Override
public void mousePressed(MouseEvent e){
if(draw_on){
x = e.getX();
y = e.getY();
}
}
#Override
public void mouseDragged(MouseEvent e){
if(draw_on){
drawPanel.drawTemporaryLine(x, y, e.getX(), e.getY(),lines);
}
}
#Override
public void mouseReleased(MouseEvent e){
if(draw_on){
lines.add(new Line(x,y,e.getX(),e.getY()));
optionButtons[0].setSelected(false);
draw_on = false;
}
}
Is there any way to fix it? Thanks.
Try to override paintComponent.
I tried to reproduce it myself:
Try this :)
DrawPanel (extends JPanel)
private ArrayList<Line> lines = new ArrayList<Line>();
private Line tmpLine = null;
public DrawPanel() {
initComponents();
}
public void drawTemporaryLine(int x1, int y1, int x2, int y2) {
tmpLine = new Line(x1, y1, x2, y2);
}
public void setTemporaryLine(int x1, int y1, int x2, int y2) {
lines.add(new Line(x1, y1, x2, y2));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.black);
for (Line l : lines) {
g2d.drawLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
}
if (tmpLine != null) {
g2d.drawLine(tmpLine.getX1(), tmpLine.getY1(), tmpLine.getX2(), tmpLine.getY2());
}
}
NewJFrame (extends JFrame):
private DrawPanel draw = new DrawPanel();
private int x = 0;
private int y = 0;
public NewJFrame() {
initComponents();
setSize(800,600);
add(draw);
draw.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
draw.setTemporaryLine(x, y, evt.getX(), evt.getY());
draw.repaint();
}
public void mousePressed(java.awt.event.MouseEvent evt) {
x = evt.getX();
y = evt.getY();
}
});
draw.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
draw.drawTemporaryLine(x, y, evt.getX(), evt.getY());
draw.repaint();
}
});
}
My question has been alluded to in java draw line as the mouse is moved, however, I have not advanced far enough into this book to have covered JPanels, JFrames and Points as stated by the prior programmer who asked this question.
Answering this question definitely would help most beginner programmers better understand the graphics class and drawing, an often intricate process, especially for beginners.
According to the text I am using (as I am learning Java on my own), this was the example of how to draw a line using Java:
/*
* LineTest
* Demonstrates drawing lines
*/
import java.awt.*;
public class LineTest extends Canvas {
public LineTest() {
super();
setSize(300, 200);
setBackground(Color.white);
}
public static void main(String args[]) {
LineTest lt = new LineTest();
GUIFrame frame = new GUIFrame("Line Test");
frame.add(lt);
frame.pack();
frame.setVisible(true);
}
public void paint(Graphics g) {
g.drawLine(10, 10, 50, 100);
g.setColor(Color.blue);
g.drawLine(60, 110, 275, 50);
g.setColor(Color.red);
g.drawLine(50, 50, 300, 200);
}
}
The specification is:
Create an application that allows you to draw lines by clicking the initial
point and dragging the mouse to the second point. The application should
be repainted so that you can see the line changing size and position as you
are dragging the mouse. When the mouse button is released, the line is
drawn.
As you will recognize, running this program does not create any drawing by the user. I believe this error is encountered due to line 21: g.drawLine(x, y, x2, y2); being incorrect since this is the statement defining the drawing of the line.
Any help is greatly appreciated. Thank you in advance for all your time and cooperation regarding this matter.
My code to answer the question is:
import java.awt.*;
import java.awt.event.*;
public class LineDrawer extends Canvas
implements MouseListener, MouseMotionListener {
int x, y, x2, y2;
public LineDrawer() {
super();
setSize(300, 200);
setBackground(Color.white);
}
public void mouseClicked(MouseEvent me) {
int x = me.getX();
int y = me.getY();
int x2 = me.getX();
int y2 = me.getY();
}
public void paint(Graphics g) {
g.drawLine(x, y, x2, y2);
g.setColor(Color.blue);
}
public void mousePressed(MouseEvent me) {
repaint();
}
public void mouseDragged(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
}
public void mouseReleased(MouseEvent me) {
}
public void mouseMoved(MouseEvent me) {
}
public static void main(String args[]) {
LineDrawer ld = new LineDrawer();
GUIFrame frame = new GUIFrame("Line Drawer");
frame.add(ld);
frame.pack();
frame.setVisible(true);
}
}
P.S.: I have been hesitant to ask for help since I am concerned that other programmers would answer with methods that I have not yet learned.
int x1, y1, x2, y2;
public void mousePressed(MouseEvent e){
x1 = e.getX();
y1 = e.getY();
}
public void mouseDragged(MouseEvent e){
x2 = e.getX();
y2 = e.getY();
// Now Paint the line
repaint();
}
Hope it helps.
Let's start with
public void mouseClicked(MouseEvent me) {
int x = me.getX();
int y = me.getY();
int x2 = me.getX();
int y2 = me.getY();
}
You have previous declared x, y, x2 and y2, but in this method, you have overridden those decelerations with new ones, meaning that the previous declared variables will not be used and the event parameters will be ignored.
mouseClicked is fired AFTER a mousePressed and mouseReleased event, meaning that this is actually when the user has released the mouse button.
Extreme Coder has pointed out that MouseClicked is only fired when the mouse button is pressed and released at the same point, i.e. no dragging is involved - it's still not the right method to use, but the clarification is nice
What you should do is...
On mousePressed store the x, y position of the click and on mouseReleased store the x2, y2 position.
On the mouseDragged event, you should update the x2, y2 values and call repaint
public void mousePressed(MouseEvent me) {
// Mouse is down, but hasn't yet being released...
x = me.getX();
y = me.getY();
// We need to "override" any previous values...
x2 = x;
y2 = y;
repaint();
}
public void mouseDragged(MouseEvent me) {
x2 = me.getX();
y2 = me.getY();
repaint();
}
public void mouseReleased(MouseEvent me) {
// Here I would store the points so I could re-draw each new line...
}
Instead of using x, y, x2 and y2, it might be better to use two arrays, ie
private int[] startPoint;
private int[] endPoint;
Then you could do something like...
public void mousePressed(MouseEvent me) {
// Mouse is down, but hasn't yet being released...
startPoint = new int[2];
startPoint[0] = me.getX();
startPoint[1] = me.getY();
endPoint = startPoint;
repaint();
}
public void mouseDragged(MouseEvent me) {
endPoint = new int[2];
endPoint[0] = me.getX();
endPoint[1] = me.getY();
repaint();
}
Now I prefer paintComponent from JComponent, but I'll stick to you example for now..
public void paint(Graphics g) {
super.paint(g); // This is super important...
if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {
g.drawLine(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
}
}
Additional
This is of some concern...
public void paint(Graphics g) {
g.drawLine(x, y, x2, y2);
g.setColor(Color.blue);
}
The order of operation is VERY important. Setting the color AFTER you've painted the line with have no effect on you paint operations (but may effect paint operations that occur after you).
Also, you MUST call super.paint(g) - this is super important...
Examples
A "basic" example, using int[] arrays for point storage...
public class BasicLineDraw {
public static void main(String[] args) {
new BasicLineDraw();
}
public BasicLineDraw() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawLinePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawLinePane extends JPanel {
private int[] startPoint;
private int[] endPoint;
private List<int[][]> lines;
public DrawLinePane() {
lines = new ArrayList<int[][]>(25);
MouseAdapter handler = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
startPoint = new int[]{e.getX(), e.getY()};
endPoint = startPoint;
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
endPoint = new int[]{e.getX(), e.getY()};
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {
lines.add(new int[][]{startPoint, endPoint});
}
startPoint = null;
endPoint = null;
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {
g2d.setColor(Color.RED);
g2d.drawLine(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
}
g2d.setColor(Color.BLUE);
for (int[][] line : lines) {
g2d.drawLine(line[0][0], line[0][1], line[1][0], line[1][1]);
}
g2d.dispose();
}
}
}
And a more advanced example, using Point and Java's 2D Graphics API
public class LineDrawer {
public static void main(String[] args) {
new LineDrawer();
}
public LineDrawer() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawLinePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawLinePane extends JPanel {
private Point anchor;
private Point lead;
private List<Line2D> lines;
public DrawLinePane() {
lines = new ArrayList<Line2D>(25);
MouseAdapter handler = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
lead = null;
anchor = e.getPoint();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
lead = e.getPoint();
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
if (lead != null && anchor != null && !anchor.equals(lead)) {
lines.add(new Line2D.Float(anchor, lead));
}
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
if (lead != null && anchor != null) {
Composite composite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f));
g2d.draw(new Line2D.Float(anchor, lead));
g2d.setComposite(composite);
}
for (Line2D line : lines) {
g2d.draw(line);
}
g2d.dispose();
}
}
}