Solved

simple drawing in java.

Posted on 1998-03-14
9
319 Views
Last Modified: 2013-11-23
Hi guys, I am doing a simple Java program of drawing on an applet. I have the basic stuff done with the following codes. But when I want to further extend my program, I got some problems that I can't fix. First when I finish a set of line segments, I want to double-click the mouse to quit and start another line segments. However, my first problem, I just can't find the double click method in Java! Do I need to make it myself in Java??? How?
And my second problem is when I want to start another part of drawing, how can I store the first part of drawing without being erasing  by the program? If you guys have any idea, just let me know. Thanks.

import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;


public class doodles extends Applet implements ActionListener, MouseListener, MouseMotionListener {

      Point pts[] = new Point[1000];
      Point ptStart, ptDrawTo;
      int ptindex=0;
      int draw_loop = 0;
     

      boolean bMouseDownFlag=false;
      boolean bMouseUpFlag=false;
      boolean FirstPress = true;

      public void init(){

      addMouseListener(this);
      addMouseMotionListener(this);
      }


      public void mousePressed(MouseEvent e){

      bMouseDownFlag = true;
      bMouseUpFlag = false;
      if (FirstPress == true)
      {ptStart = new Point(e.getX(),e.getY());
       FirstPress = false;  
      }
      }


      public void mouseReleased(MouseEvent e) {

      bMouseDownFlag = false;
      bMouseUpFlag=true;
      pts[ptindex++]=new Point(e.getX(),e.getY());
      repaint();
   
      }
         
        public void mouseDragged(MouseEvent e){
        }
       
         
        public void mouseClicked(MouseEvent e){
        }

        public void mouseEntered(MouseEvent e){
        }

        public void mouseExited(MouseEvent e){
        }

        public void mouseMoved(MouseEvent e){
        }

      public void paint(Graphics g){
         for (draw_loop = 0; draw_loop<ptindex-1;draw_loop++){

         g.drawLine(pts[draw_loop].x,pts[draw_loop].y,pts[draw_loop+1].x,pts[draw_loop+1].y);
                }
     
      }
     
      public void actionPerformed(ActionEvent e) {
      }

}
0
Comment
Question by:kelly_host
  • 5
  • 3
9 Comments
 
LVL 6

Expert Comment

by:jpk041897
ID: 1233565
1) The click count is contained in the event structure itself:

Event Fields

A large set of final variables exist that just define constants; these variables are discussed in later sections. Apart from these
items, the variables in each Event object are

     Object  target;
     long    when;
     int     id;
     int     x;
     int     y;
     int     key;
     int     modifiers;
     int     clickCount;
     Object  arg;
     Event   evt;

So you would need modify your code to:

 public void mousePressed(MouseEvent e){

          bMouseDownFlag = true;
          bMouseUpFlag = false;
          if (FirstPress == true)
          {
              ptStart = new Point(e.getX(),e.getY());
              FirstPress = false;  
          }
          if (e.clickCount > 1){
             // Process double click here
         }

}

2) Store the coordinate of your lines (objects?) in an array or vector so that you can modify the pannels (or whatever you are using as a drawing board) paint() method to redraw all the objects via iteration of the array/vector.
0
 

Author Comment

by:kelly_host
ID: 1233566
Hi JPK,
Thanks for you suggestion. But, now, I have another question: how can I distingulish the double click than the second point I want to draw, if I use the click count? When I press the mouse next time, it just same as a double-click for this problem! I am wondering maybe I need to use the timer to distingulish those two different event.

Also, I still don't know how to do set up a set of data structure to store the lines I have previously drawn and start another set of line. Can you show me in more detail?

Thanks.
0
 

Author Comment

by:kelly_host
ID: 1233567
Adjusted points to 200
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 6

Expert Comment

by:jpk041897
ID: 1233568
To distinguish the diffrent double clicks, you can set up a simple semaphore, I.e.: a flag that has two or more states.

For the simple case of distinguishing multiple line segments, you can set up a 2 state flag (semaphore) using a boolean. The code would be in the spirit of:

boolean dblClkFlag;
...

if (!dblClkFlag) // the user just double clicked so a line segment is starting...
{
   dblClkFlag = TRUE;
   // Process first point and rubberbanding or whatever
   ...
}
else // user has double clicked to indicate an end of line segnment
{  
   dblClkFlag = FALSE;
   // Process end of line, store in display list and draw the line segment
   ...
}

Now, regarding the data structure, the simplest one you can use is called a display list (which is the technique used by AutoCad amongst other products).

The general idea is to define a record (class in Java's case) that contains an opcode (indicating what type ofgraphics primitive is beeing used) and the basic data needed to re draw the primitive on demand.

For instance:

const int cont = 0; // indicates that this is not a new opcode but more data for the previous opcode
const int point = 1;
const int line = 2;
const int circle = 3;
const int box = 4;
...

Now, to generate a point you would need an x and y coordinate pair, a color and a width so the data would look like:

Opcode, X, Y, Color, Widht              

for example: 1, 10,27, Yellow, 3

a line would need two points

Opcode, X, Y, Color, Width                
Continue, X, Y, 0, 0

for example:

1, 10, 12, Red, 2
0, 20, 17, 0, 0

I.e.: A 2 point width red line from (10,12) to (20,17), the 0 opcode indicating that the secondline continues the definition of the first.

A Box could be defined qith top-left, lower right coord. pair, a circle with center point and radius, etc. You could also add additional columns for additional info such a line type (continious, dotted, etc).

Generaly speaking then, you could define a class such as:

Class GraphicsElement
{
   int Opcode;
   int X;
   int Y;
   int Color;
   int Width;

}

And you could then define an array of GraphicsElement to store the data, or better still a linked list or ordered array.

Once the data structure is defined, whenever you need to redraw the drawing, you can parse the array (or whatever) and redraw the grahics elements (primitives) one by one in order.

If you place the array in a class of its own with accesor methods (add, delete, modify, redraw, etc.) you could even make this class serializable for storage on a HD.

There are othe more complex Datastructures that are suitable for storage and querry on a DB but they are probably more than you need.

If you need help building some code let me know.
0
 

Author Comment

by:kelly_host
ID: 1233569
Hi jpk,
Thanks for your advices, now I can do the double click no problem. But, I still have difficulties to bulid the data structure to let me draw a different line after the double click. I want to use the method you told me,but I am not really understand the whole idea very much. Is it neccessary to use it? Is there any another simple way to do it? Can you give me some more help on this? Thanks,

public class doodles extends Applet implements ActionListener, MouseListener, MouseMotionListener {
     
      TextField text1; //Testing
      Point pts[] = new Point[1000];
      Point ptStart, ptDrawTo;
      int ptindex=0;
      int draw_loop = 0;
      boolean FirstPress = true;
      boolean bMouseClick = false;
      int ClickCount = 0;

      boolean mouseDrageFlag = false;
      boolean dblClkFlag;

      public void init(){

      text1 = new TextField(40); //Testing
      add(text1);
     
      addMouseListener(this);
      addMouseMotionListener(this);
      }


      public void mousePressed(MouseEvent e){

      if (FirstPress == true)
      {ptStart = new Point(e.getX(),e.getY());
       FirstPress = false;  
      }
      }


      public void mouseReleased(MouseEvent e) {

      pts[ptindex++]=new Point(e.getX(),e.getY());

      if (dblClkFlag==false)
      repaint();
   
      }
         
        public void mouseDragged(MouseEvent e){
       
        }
       
         
        public void mouseClicked(MouseEvent e){

        ClickCount++;

       
        if(ClickCount==2)
        {

        text1.setText("Double! ")  ;                                
        dblClkFlag=true;
        }
       
        }

        public void mouseEntered(MouseEvent e){
        }

        public void mouseExited(MouseEvent e){
        }

        public void mouseMoved(MouseEvent e){
        ClickCount = 0 ;
        text1.setText("Clear! ");
        }

      public void paint(Graphics g){
         for (draw_loop = 0; draw_loop<ptindex-1;draw_loop++){



         g.drawLine(pts[draw_loop].x,pts[draw_loop].y,pts[draw_loop+1].x,pts[draw_loop+1].y);
                }
      }
      public void actionPerformed(ActionEvent e) {
     
      }
}
0
 
LVL 6

Expert Comment

by:jpk041897
ID: 1233570
You don't have to use it. It really all depends on what you eventualy want to do with your app.

If you only intend to do lines with no other primitives like circles, splines, conics, etc. Then an array (or vector) of points should be enough. A vector being a somwhat better choice because it will grow as needed.

If on the other hand, you intend to build someting like a CAD, with "infinite" resolution zooms, clipping, hidden surface removale, rendering, or storing large ammounts of lines in  a DB then the kind of data structure I proposed becomes verry important.

The display list is far from the best way to store graphics data in memory, its just the simplest way to do it and still have some flexibility left over to grow into more complete applications.

Regarding more help, gladly, just pose specific questions I can answer for you or I'll end up writting a book on Computer Graphics data structures here :-)
0
 

Author Comment

by:kelly_host
ID: 1233571
I rewrite the program a little bit, but it is still not working. Wonder if any one can help me out? I just wonder if I can keep the line I have already drawn after using the repaint method. If I can keep the image there without being earsed, it will make my work more easier!

import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.applet.Applet;


public class doodles extends Applet implements ActionListener, MouseListener, MouseMotionListener {
     
      TextField txtLineIndex; //Testing
      TextField txtptindex;
      TextField xPt;
      TextField yPt;
     
      Point pts[][] = new Point[100][100];
      Point ptStart, ptDrawTo;
      int ptindex=0;
      int LineIndex=0;
      int draw_loop = 0;
      int NoOfLine =0;      

      boolean FirstPoint = true;
      boolean bMouseClick = false;
      int ClickCount = 0;

      boolean mouseDrageFlag = false;
      boolean dblClkFlag=false;


      public void init(){

      txtLineIndex = new TextField(10); //Testing
      add(txtLineIndex);
     
      txtptindex = new TextField(10); //Testing
      add(txtptindex);

      xPt = new TextField(10); //Testing
      add(xPt);

      yPt = new TextField(10); //Testing
      add(yPt);

     
      addMouseListener(this);
      addMouseMotionListener(this);
      }

      public void mousePressed(MouseEvent e){    
                                                 
      }


      public void mouseReleased(MouseEvent e) {

         pts[LineIndex][ptindex++]=new Point(e.getX(),e.getY());


         
         if (FirstPoint == false){        // Don't print for the 1st point        
         repaint();                                
         }
         
         
         FirstPoint = false;
     

   
      }
         
        public void mouseDragged(MouseEvent e){
       
        }
       
         
        public void mouseClicked(MouseEvent e){

        ClickCount++;

       
        if(ClickCount==2) //Double Click
        {

         

           dblClkFlag=true;
           LineIndex++;
           FirstPoint = true;
           ptindex = 0;

        }
       
        }

        public void mouseEntered(MouseEvent e){
        }

        public void mouseExited(MouseEvent e){
        }

        public void mouseMoved(MouseEvent e){
        ClickCount = 0 ;
       
        }

      public void paint(Graphics g){
     

      if (FirstPoint == false)  { // Testing
         txtLineIndex.setText(String.valueOf(LineIndex));
         txtptindex.setText(String.valueOf(ptindex-1));
         xPt.setText(String.valueOf(pts[LineIndex][ptindex-1].x));
         yPt.setText(String.valueOf(pts[LineIndex][ptindex-1].y));                  
         }


      for (NoOfLine=0; NoOfLine<LineIndex+1;NoOfLine++){
         for (draw_loop = 1; draw_loop<ptindex;draw_loop++){



         g.drawLine(pts[NoOfLine][draw_loop].x,pts[NoOfLine][draw_loop].y,pts[NoOfLine][draw_loop-1].x,pts[NoOfLine][draw_loop-1].y);
              }
     
      }
      }
     
      public void actionPerformed(ActionEvent e) {
     
     
      }

}

0
 

Author Comment

by:kelly_host
ID: 1233572
Adjusted points to 360
0
 
LVL 1

Accepted Solution

by:
jerrykun earned 360 total points
ID: 1233573
Try to add that in your code.


public void update(Graphics g)
{
&#160;paint(g);
}

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Configure a Bean in an XML file 4 42
ejb mdb examples 1 6
ejb entity bean example issue 2 16
web project error add remove 1 27
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

790 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question