Java - Pulling line animation lags and invisible - java

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

Related

Implement in JAVA a rectangle shape feature like in Paint

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

drawing multiple shapes using bufferimage java swing

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?

How to pass Graphics objects between classes and methods to draw lines

I am making a gui program with the mouseListener and mouseMotionListener. I have the following Line class
public class Line {
private int x1, x2, y1, y2;
private Color color;
public Line(int x1, int x2, int y1, int y2, Color color)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color = color;
}
public void draw(Graphics page)
{
page.drawLine(x1, y1, x2, y2);
page.setColor(color);
}
}
here is my mouseReleased where i get the final points of the desired line.
public void mouseReleased (MouseEvent event)
{ // ending points
moving = false;
Point p2 = event.getPoint();
x2 = p2.x;
y2 = p2.y;
line = new Line(x1,x2,y1,y2,currentColor);
lineList.add(line);
canvas.paintComponent(??????????);
Here is the canvas method that should draw all of these lines in the array list "lineList". to the canvas
private class CanvasPanel extends JPanel
{
//this method draws all shapes specified by a user
public void paintComponent(Graphics page)
{
super.paintComponent(page);
setBackground(Color.WHITE);
for(int i = 0; i <lineList.size()-1;i++)
{
line.draw(page);
}
However I do not know how to pass the graphics object to the canvas class in order to actually draw my lines on the JPanel. Assuming i have all other info correct(initial line points, JPanel set correctly, and buttons set up) how do i pass these to actually make it draw the lines to the canvas. Thank you!
No, you don't want to pass a Graphics object anywhere, and in fact you don't paint from within the MouseListener or MouseMotionListener. Instead you change fields from within those classes, call repaint() and then use the field results in your paintComponent method.
In fact in your code, if CanvasPanel has access to the lineList, all you need to do is call repaint() on it after adding a new line into the lineList collection. That's it.
Also, don't set background within paintComponent but rather within the constructor. Also you need to swap your method calls in the Line's draw method. You need to set the color before drawing the line.
e.g.,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Drawing extends JPanel {
public static final Color BG = Color.WHITE;
public static final Color LINE_COLOR = Color.RED;
public static final Color CURRENT_LINE_COLOR = Color.LIGHT_GRAY;
public static final int PREF_W = 800;
public static final int PREF_H = PREF_W;
private List<Line> lineList = new ArrayList<>();
private Line currentLine = null;
private CanvasPanel canvasPanel = new CanvasPanel();
public Drawing() {
MyMouse myMouse = new MyMouse();
canvasPanel.addMouseListener(myMouse);
canvasPanel.addMouseMotionListener(myMouse);
setLayout(new BorderLayout());
add(canvasPanel);
}
private class CanvasPanel extends JPanel {
public CanvasPanel() {
setBackground(BG);
}
public void paintComponent(Graphics page) {
super.paintComponent(page);
// setBackground(Color.WHITE); // !! no, not here
for (Line line : lineList) {
line.draw(page);
}
if (currentLine != null) {
currentLine.draw(page);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
private class MyMouse extends MouseAdapter {
private int x1;
private int y1;
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
x1 = e.getX();
y1 = e.getY();
currentLine = null;
canvasPanel.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
Line line = createLine(e, LINE_COLOR);
lineList.add(line);
currentLine = null;
canvasPanel.repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
currentLine = createLine(e, CURRENT_LINE_COLOR);
repaint();
}
private Line createLine(MouseEvent e, Color currentColor) {
int x2 = e.getX();
int y2 = e.getY();
return new Line(x1, x2, y1, y2, currentColor);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Drawing());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Line {
private int x1, x2, y1, y2;
private Color color;
public Line(int x1, int x2, int y1, int y2, Color color) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color = color;
}
public void draw(Graphics page) {
// swap these calls!
page.setColor(color); //!! This first!
page.drawLine(x1, y1, x2, y2); // **Then** this
// !! page.setColor(color);
}
}

Delete all drawn shapes JAVA

I need to delete shapes individually or all of them!
please help I've tried deleting all contents from my arrayList "Figuras"
and removeAll from panel
public class PaintRodo extends JFrame {
JButton linea, circulo, rectangulo, trazo, llenar,borrar;
static int seleccion = 1;
Color trazoC = Color.BLACK;
Color llenarC = Color.lightGray;
JMenuBar barra;
public static void main(String[] args) {
new PaintRodo();
}
public PaintRodo() {
this.setSize(1000,700);
this.setTitle("Paint");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
Box miBox = Box.createHorizontalBox();
linea= AgregarIcono("./src/linea.png",2);
circulo= AgregarIcono("./src/circ.png",3);
rectangulo= AgregarIcono("./src/rect.png",4);
trazo = AgregarIconoColor("./src/trazo.png",5,true);
llenar = AgregarIconoColor("./src/llenar.png",6,false);
borrar = AgregarIcono("./src/borrador.png",7);
miBox.add(linea);
miBox.add(circulo);
miBox.add(rectangulo);
miBox.add(llenar);
miBox.add(trazo);
miBox.add(borrar);
panel.add(miBox);
this.add(panel,BorderLayout.NORTH);
this.add(new Lienzo(),BorderLayout.CENTER);
this.setVisible(true);
}
public JButton AgregarIcono (String icono, final int accion){
JButton boton = new JButton();
Icon iconos = new ImageIcon (icono);
boton.setIcon(iconos);
boton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
seleccion =accion;
}
});
return boton;
}
public JButton AgregarIconoColor (String icono, final int accion,final boolean grosor ){
JButton boton = new JButton();
Icon iconos = new ImageIcon (icono);
boton.setIcon(iconos);
boton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(grosor){
trazoC = JColorChooser.showDialog(null,"Elige el Contorno",Color.BLACK);
}
else{
llenarC = JColorChooser.showDialog(null,"Elige el Relleno",Color.BLACK);
}
}
});
return boton;
}
public class Lienzo extends JComponent{
ArrayList<Shape> figuras = new ArrayList<Shape>();
ArrayList<Color> arrLleno = new ArrayList<Color>();
ArrayList<Color> arrTrazo = new ArrayList<Color>();
Point inicio,fin;
public Lienzo(){
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e){
if (seleccion!=1){
inicio = new Point (e.getX(),e.getY());
fin=inicio;
repaint();
}
}
public void mouseReleased(MouseEvent e){
if (seleccion!=1){
Shape SAVEfig=null;
if (seleccion==2){
SAVEfig = crearLinea(inicio.x,inicio.y,e.getX(),e.getY());
}
else if (seleccion==3){
SAVEfig = crearCirculo(inicio.x,inicio.y,e.getX(),e.getY());
}
figuras.add(SAVEfig);
arrLleno.add(llenarC);
arrTrazo.add(trazoC);
repaint();
}
}
});//mouselistener
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
fin= new Point (e.getX(),e.getY());
repaint();
}
});//MotionListener
}//constructor lienzo
public void paint (Graphics g){
Graphics2D graFig = (Graphics2D)g;
graFig.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
graFig.setStroke (new BasicStroke(2));
Iterator<Color>contadorTrazo= arrTrazo.iterator();
Iterator<Color>contadorLleno= arrLleno.iterator();
graFig.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f));
this.setBackground(Color.LIGHT_GRAY);
for (Shape i: figuras){
graFig.setPaint(contadorTrazo.next());
graFig.draw(i);
graFig.setPaint(contadorLleno.next());
graFig.fill(i);
}
if (inicio!=null&&fin!=null){
graFig.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.40f));
graFig.setPaint(Color.LIGHT_GRAY);
Shape SAVEfig=null;
if (seleccion==2){
SAVEfig=crearLinea(inicio.x,inicio.y,fin.x,fin.y);
}
else if (seleccion==3){
SAVEfig=crearCirculo(inicio.x,inicio.y,fin.x,fin.y);
}
graFig.draw(SAVEfig);
}
}
private Rectangle2D.Float crearRectangulo(int x1, int y1,int x2 , int y2){
int x =Math.min(x1, x2);
int y = Math.min(y1, y2);
int ancho = Math.abs(x1-x2);
int alto = Math.abs(y1-y2);
return new Rectangle2D.Float(x,y,ancho,alto);
}
private Line2D.Float crearLinea(int x1, int y1, int x2, int y2){
return new Line2D.Float(x1, y1, x2, y2);
}
private Ellipse2D.Float crearCirculo( int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int ancho = Math.abs(x1 - x2);
int alto = Math.abs(y1 - y2);
return new Ellipse2D.Float(x, y, ancho, alto);
}
}//classLienzo
}//MainClass Paint rodo
I need to delete shapes individually or all of them!
Please help; I've tried deleting all contents from my arrayList "Figuras"
and (removeAll) from panel

Java Challenge on Permitting the User to Draw A Line

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

Categories