How to create a new tool?

This web is incomplete. We are working on it!'''''

This document aims to explain the general operation of a tool, and for this, we explain it by the addition of a new tool used in the new user GUI.

What is the new tool?

This new tool will allow the fixation of two model elements, ie, which will not change their position to a restrictions change (such as changing the distance between two points), unless is changed a restriction between this two fixed elements.

Now we will explain better, with a visual example.

  • We have our model, which consists of four segments and four points:
  • For example, we have two fixed points, which we now see yellow:
  • We going to increas the restriction of distance (d0):
  • We can see that with increasing distance, the elements that were fixed, not changed their position:
  • Now, back to the original model and we fix two new points, we can see yellow too:
  • If we increase the restriction distance, we see that the model changes the dynamics of displacement:

Step 1: Insert the new tool in a toolbar

As this tool only be used in the new user GUI, we can create a new kind of toolbar that Integrate these new tools, the UserToolBar. ProblemViewer incorporate a new constant, FIXED_ELEMENTS:

public class UserToolBar extends ProblemViewerEditorToolBar{
    
  private AbstractButton fixedElements;
    
  public UserToolBar(ProblemViewer pv){
    super(pv);
    fixedElements = new JToggleButton(Images.ARC);
    fixedElements.setToolTipText(Gettext._("Fixed Elements"));
    fixedElements.addActionListener(this);
    group1.add(fixedElements);
        
    visualToolBar.add(fixedElements);
  }    

  public void actionPerformed(ActionEvent e) {    
    ...
    else if(active == fixedElements){
            currentTool = ProblemViewer.FIXED_ELEMENTS;
    } 
    ...
  }
}

Step 2: Create the new tool: FixedElementsTool (Part I)

All tools will extend of MouseEditorTool:

package solBCN.gUI.tools;

public class FixedElementsTool extends MouseEditorTool{

  public PruebasTool(Editor e){
    super(e);
  }

}

Recognize elements

We use the RecognizerTool class, which is used to recognize model elements. More specifically, we use the class PointRecognizerTool and LineRecognizerTool, because we have to recognize points and lines. Then we will have the first private attributes, we must also create methods enableSetup (invoked when this tool is enabled) and disableSetup (nvoked when this tool is disabled), and modify the constructor:

public class FixedElementsTool extends MouseEditorTool{
  private PointRecognizerTool pointRecognizer;
  private LineRecognizerTool lineRecognizer;
 
  public FixedElementsTool(Editor e, PointRecognizerTool pr, LineRecognizerTool ln) {
    super(e);
    pointRecognizer = pr;
    lineRecognizer = ln;      
  }
  
  protected void enableSetup() {
    super.enableSetup();
    // Activate the recognizers
    pointRecognizer.enable();
    lineRecognizer.enable();
    // Unselect selected elements
    Canvas2D c = editor.getCanvas2D();
    c.unselect();
    c.setCursor(CursorManager.getCrossCursor());
    c.repaint(true);
  }

  protected void disableSetup() {
    super.disableSetup();
    pointRecognizer.disable();
    lineRecognizer.disable();
    editor.getCanvas2D().setCursor(CursorManager.getDefaultCursor());
  }
  
}

States of the FixedElementsTool

We have to monitor several states depending on if we do not have fixed elements, or if we have one or two. We add new constants in the class FixedElementsTool, one new method to change state:

public class FixedElementsTool extends MouseEditorTool{
  ...  
  
  /**
   * Tool state.
   */
  private int state;
  
  /**
   * Initial state.
   */
  public static final int EMPTY = 0;

  /**
   * Intermediate state, first selection is a point.
   */
  public static final int POINT = 1;

  /**
   * Intermediate state, first selection is a point.
   */
  public static final int LINE = 2;

  /**
   * Final state, first selection is a point and last a point.
   */
  public static final int POINT_POINT = 3;
  
  /**
   * Final state, first selection is a point and last a line.
   */
  public static final int POINT_LINE = 4;

  /**
   * Final state, first selection is a line and last a point.
   */
  public static final int LINE_POINT = 5;
  
  /**
   * Final state, first selection is a line and last a line.
   */
  public static final int LINE_LINE = 6;

  ...

  private void updateState(int s) {
    state = s;

    if (state == POINT_POINT || state == POINT_LINE || state == LINE_LINE || state == LINE_POINT){
      lineRecognizer.disable();  
      pointRecognizer.disable();  
    }
    else{
      lineRecognizer.enable();
      pointRecognizer.enable();  
    }
  }

 ...
}


Events of the FixedElementsTool

MouseClick Event

Invoked when a mouse button has been clicked on a component (pressed, released, but not dragged). If we click with main button we fix one element, if we do click with other button, we cancel the fixed elements.

public class FixedElementsTool extends MouseEditorTool{
  ...

  /**
   * Invoked when a mouse button has been clicked on a component
   * (pressed, released, but not dragged).
   * @param mae mouse automata event
   */
  public void mouseClick(MouseAutomataEvent mae) {
    if (mae.getButton() == mainButton) handlePick(mae.getCursor());
    else handleCancel();
  }
  ...
}

The private void !handlePick(Pixel p) manages the state of our tool, it paints different the selected element and fix this element. But now, we will focus on selection of the elements and changes of state.

public class FixedElementsTool extends MouseEditorTool{

  ...

  /**
   * Selected elements (first and second).
   */
  private Drawable2D drawable2DElement1, drawable2DElement2;

  ...

  private void handlePick(Pixel p) {
    Canvas2D c = editor.getCanvas2D();
    Drawable2D d = null; 
    switch(state) {
      case EMPTY:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement1 = d;
          c.unselect();
          drawable2DElement1.setSelected(true);
          updateState(LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement1 = d;
          c.unselect();
          drawable2DElement1.setSelected(true);
          updateState(POINT);                  
        }
        break;
      
      case POINT:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          lineRecognizer.disable();   
          updateState(POINT_LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          pointRecognizer.disable();
          updateState(POINT_POINT);
        }
        break;

      case LINE:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          lineRecognizer.disable();   
          updateState(LINE_LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          pointRecognizer.disable();
          updateState(LINE_POINT);
        }
        break;                  
    }                 
  }
  ... 
} 

The private void !handleCancel() will cancel the last fixed element, and it will update state:

public class FixedElementsTool extends MouseEditorTool{
  ...
  private void handleCancel() {
    // Undo the last selection
    Canvas2D c = editor.getCanvas2D();
    switch(state) {
      case EMPTY:
        break;
      case POINT:
        drawable2DElement1.setSelected(false);
        drawable2DElement1 = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(EMPTY);
        break;
      case LINE:
        drawable2DElement1.setSelected(false);
        drawable2DElement1 = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(EMPTY);
        break;
      case POINT_POINT:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(POINT);
        break;    
      case POINT_LINE:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(POINT);
        break;    
      case LINE_LINE:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(LINE);
        break;
      case LINE_POINT:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(LINE);
        break;
    }  
  }
  ... 
} 

Now we can to select and unselect elements to fix, when we active the new tool. But it is only visual, we haven't a source code to fix the elements that we select.

Step 3: Create a new painter (Part I)

In this step, we explain the creating of a point painter, later we will explain the other painter (to lines) faster.

Paint the fixed elements

A Painter is is the abstract superclass of the ViewElement painters hierarchy. A painter has a default appearance used only if ViewElement.getAppearance() returns NULL.

Every ProblemModelElement has got assigned an Painter class that inherits from Painter (eg !MEPoint is assigned to BasicPointPainter, and these are SINGLETON instances):

We can see the classes as BasicPointPainter, that implements the abstract classes, and these are just painting the element. In the method setupPainters() in GUI, we can see how each ProblemModelElement is assigned to your Painter (PainterManager is a container to manage painters simply):

  private void setupPainters() {
    PainterManager.add(MEPoint.class,BasicPointPainter.create());
    PainterManager.add(MELine.class,BasicLinePainter.create());
    PainterManager.add(MECircle.class,BasicCirclePainter.create());
    PainterManager.add(MEArc.class,BasicArcPainter.create());
    PainterManager.add(MESegment.class,BasicSegmentPainter.create());
    PainterManager.add(MEDistPL.class,BasicDistPLPainter.create());
    PainterManager.add(MEDistPP.class,BasicDistPPPainter.create());
    PainterManager.add(MEAngleLL.class,BasicAngleLLPainter.create());
    PainterManager.add(MERadius.class,BasicRadiusPainter.create());
    PainterManager.add(MECenter.class,BasicCenterPainter.create());
    PainterManager.add(MEOnPC.class,BasicOnPCPainter.create());
    PainterManager.add(MEOnPL.class,BasicOnPLPainter.create());
    PainterManager.add(METanCC.class,BasicTanCCPainter.create());
    PainterManager.add(METanLC.class,BasicTanLCPainter.create());
  }

The idea of this tool is to show a different draw of the fixed element, and therefore, must create or modify a Painter. To have clearer ideas, we will see a sequence from that we go to paint a element until it is painted:

Now we come to several alternatives which we explain below. These alternatives are explained in general to Point element, but it would be the same for any other element that we need.

Alternative I: Modify BasicPointPainter

We may create a method in BasicPointPainter (or PointPainter and that BasicPointPainter implements it), and that this call to a new method in !Canvas2DUtils to carry out a new drawing.

This alternative is not very accurate, since the BasicPointPainter class has the target to paint a basic point and no other kind point. A modification of the class (that could be done), would go against the specification and against the POO. It is better to create a new class for this committed.

Alternative II: Creating FixedElementsPainter and BasicFixedElementsPainter classes alternative

Create a new abstract class called FixedElementsPainter where the BasicFixedElementsPainter implements it. This class could to paint every element that we fix (points and lines) in another way.

The problem is that now the new class has to fulfill the functionality of a new element of the problem (a geometry or a restriction, the new !Painter should be assigned to your ProblemModelElement), and this not is thus, all the opposite, we must modify the drawing to that the user understand what elements are fixed. We clearly see that with this scheme we may be away from a consistent solution, so we discard it.

Alternative III: Creating FixedPointPainter class as subclass of BasicPointPainter

We can also create a new FixedPointPainter class that extends of BasicPointPainter and in addition of the inherited, incorporate the new functionality that paints the element different if it is fixed.

We do not need to extend the functionality of a BasicPointPainter, if not that we want paint a different point.

Alternative IV: Creating FixedPointPainter class as subclass of PointPainter

We can see the class TexturePointPainter that follows a similar concept to ours (it paints a point with a texture), and create a new class FixedPointPainter that implements to PointPainter.

Now it seems that everything is more consistent, we have the abstract class PointPainter that extends of Painter, and different implementations for different ways to paint the point. In the event that an element is fixed, it will be painted through of FixedPointPainter, on the opposite, it will be painted through of BasicPointPainter.

Creating of FixedPointPainter (alternative IV)

This class is called whenever there is a Canvas2D repaint and there are points in the problem. So when this class implements the method "paint" must distinguish whether is a point fixed or not, to be able to call to a right method "paint" or other of Canvas2DUtils.

We must have some attributes that us indicate whether there is a fixed point (or two) and what is this point (or points).

public class FixedPointPainter extends PointPainter {
    
  protected static final FixedPointPainter painter = new FixedPointPainter();
  
  private int state;
  private PointXY fixedPoint1, fixedPoint2;
  
  private FixedPointPainter() {
     
    apDefault = new Appearance();
    apDefault.setPaintColor(new Color(90,90,255));
  }
  
  public static FixedPointPainter create() {
    return painter;
  }

  public void fixPoint(PointXY p){      
      if (fixedPoint1 ==null) fixedPoint1 = p;
      else if (fixedPoint2 ==null) fixedPoint2 = p;
  }
  
  public void dropPoint(PointXY p){    
      if (fixedPoint1 == p) fixedPoint1 = null;
      else if  (fixedPoint2 == p) fixedPoint2 = null;
  }

  /**
   * Paints a view element.
   * @param ve view element
   * @return element bounding box (in world coordinates)
   */
  public BoundingBox paint(ViewElement ve) {
    ModelView mv = ve.getModelView();
    ProblemModel model = (ProblemModel)mv.getModel();
    MEPoint mep = (MEPoint)ve.getModelElement();
    PointXY pxy = mep.getPointXY(model);
    return paint(mv.getCanvas2D(),ve.getAppearance(),pxy,mep.getName());
  }

  /**
   * Paints a <i>point</i> in a canvas.
   * @param c canvas
   * @param a appearance
   * @param pxy point (in world coordinates)
   * @return bounding box (in world coordinates)
   */
  public BoundingBox paint(Canvas2D c, Appearance a, PointXY pxy, String name) {
    // Apply the appearance
    Appearance ap = (a!=null) ? a : apDefault;
    ap.apply(c.getGraphics2D());
    
    // Paint the point
    int size = ap.getPointSize();   
     
    if (fixedPoint1!=null && pxy==fixedPoint1) Canvas2DUtils.paintFix(c, pxy, size);
    else if (fixedPoint2!=null && pxy==fixedPoint2) Canvas2DUtils.paintFix(c, pxy, size);
    else Canvas2DUtils.paint(c, pxy, size); 

    // Return the bounding box
    double d = c.getCoordMapper().getWorldDist(size/2);
    return new BoundingBox(pxy.getX()-d,pxy.getY()-d,pxy.getX()+d,pxy.getY()+d);    
  }  
}

And create a new paint method in Canvas2DUtils that it paints the point of a different way.

public class Canvas2DUtils {

  ...

  /**
   * Paints a fix point in a canvas.
   * @param canvas2D canvas
   * @param pxy point (in world coordinates)
   * @param w point width (in pixels)
   * @param toFix is true, then it paint a fixed point, else a normal point
   */
  public static void paintFix(Canvas2D canvas2D, PointXY pxy, int w) {
        // Get the point graphic coordinates ...
        CoordMapper cm = canvas2D.getCoordMapper();    
        Pixel pix = cm.getPixel(pxy);

        // ... and draw the coordinate system glyph!!
        Graphics2D g2D = canvas2D.getGraphics2D();
        g2D.drawOval(pix.getX()-w,pix.getY()-w,2*w,2*w);
        g2D.fillArc(pix.getX()-w,pix.getY()-w,2*w,2*w,0,90);
        g2D.fillArc(pix.getX()-w,pix.getY()-w,2*w,2*w,180,90);
  }

  ...
}

Step 4: Create the new tool: FixedElementsTool (Part 2)

Incorporate the new painter

Now we have to insert new code in our class we created in step 1, so you can visualize the points when we click with FixedElementsTool on. We modify the methods HandlePick?(Pixel p) and handleCancel(), to change the display of the point (see the "NEW CODE" paragraph):

public class FixedElementsTool extends MouseEditorTool{
 
  ...

  private void handlePick(Pixel p) {
    Canvas2D c = editor.getCanvas2D();
    
    // NEW CODE //
    ProblemModel model;
    PointXY pxy;
    PointPainter pointPainter;

    Drawable2D d = null; 
    switch(state) {
      case EMPTY:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement1 = d;
          c.unselect();
          drawable2DElement1.setSelected(true);
          updateState(LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement1 = d;
          c.unselect();
          drawable2DElement1.setSelected(true);
          updateState(POINT);                  
          
          // NEW CODE //       
          model = (ProblemModel)editor.getModel();
          pxy = ((MEPoint)((ViewElement)drawable2DElement1).getModelElement()).getPointXY(model);
          pointPainter = (PointPainter)((ViewElement)drawable2DElement1).getPainter();
          ((FixedPointPainter)pointPainter).fixPoint(pxy);                       
          pointPainter.paint(c, ap, pxy, null);
          c.repaint(true);                   
        }
        break;
      case POINT:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true); 
          updateState(POINT_LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          updateState(POINT_POINT);

          // NEW CODE //        
          model = (ProblemModel)editor.getModel();
          pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
          pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
          ((FixedPointPainter)pointPainter).fixPoint(pxy);                       
          pointPainter.paint(c, ap, pxy, null);
          c.repaint(true);   
        }
        break;
      case LINE:
        d = c.getElement(p);
        if (lineRecognizer.recognized(d)) {
          // Line selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          updateState(LINE_LINE);
        }
        else if (pointRecognizer.recognized(d)) {
          // Point selected
          drawable2DElement2 = d;
          c.unselect();
          drawable2DElement2.setSelected(true);
          drawable2DElement1.setSelected(true);
          updateState(LINE_POINT);
                  
          // NEW CODE //
          model = (ProblemModel)editor.getModel();
          pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
          pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
          ((FixedPointPainter)pointPainter).fixPoint(pxy);                       
          pointPainter.paint(c, ap, pxy, null);
          c.repaint(true); 
        }
        break;                  
    }                 
  }  

  private void handleCancel() {
    // Undo the last selection
    Canvas2D c = editor.getCanvas2D();
    
    // NEW CODE //
    ProblemModel model;
    PointXY pxy;
    PointPainter pointPainter;
    
    switch(state) {
      case EMPTY:
        break;
      case POINT:
        drawable2DElement1.setSelected(false);


        // NEW CODE //
        model = (ProblemModel)editor.getModel();
        pxy = ((MEPoint)((ViewElement)drawable2DElement1).getModelElement()).getPointXY(model);
        pointPainter = (PointPainter)((ViewElement)drawable2DElement1).getPainter();
        ((FixedPointPainter)pointPainter).dropPoint(pxy);                       
                
        drawable2DElement1 = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(EMPTY);        
        
        // NEW CODE //
        pointPainter.paint(c, ap, pxy, null);
        c.repaint(false);
        
        break;
      case LINE:
        drawable2DElement1.setSelected(false);
        drawable2DElement1 = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(EMPTY);
        break;
      case POINT_POINT:
        drawable2DElement2.setSelected(false);

        // NEW CODE //
        model = (ProblemModel)editor.getModel();
        pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
        pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
        ((FixedPointPainter)pointPainter).dropPoint(pxy);                       
                
        drawable2DElement2 = null;
        tp = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(POINT);
        
        pointPainter.paint(c, ap, pxy, null);
        c.repaint(true);
        
        break;    
      case POINT_LINE:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        tp = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(POINT);
        break;    
      case LINE_LINE:
        drawable2DElement2.setSelected(false);
        
        // NEW CODE //
        model = (ProblemModel)editor.getModel();
        pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
        pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
        ((FixedPointPainter)pointPainter).dropPoint(pxy);
        
        drawable2DElement2 = null;
        tp = null;
        lineRecognizer.enable();
        c.repaint(true);
        updateState(LINE);
        
        // NEW CODE //
        pointPainter.paint(c, ap, pxy, null);
        c.repaint(true);
        
        break;
      case LINE_POINT:
        drawable2DElement2.setSelected(false);
        drawable2DElement2 = null;
        tp = null;
        pointRecognizer.enable();
        c.repaint(true);
        updateState(LINE);
        break;
    }  
  }

  ...

}

Add the FixedMode concept

The connection between this tool and the other classes would be:

When UserToolBar detected that has been done click on the new tool, it will warn to editor UserPoblemEditor using the new method setView2FixedMode(boolean fixedMode):

public class UserProblemEditor extends ProblemViewerEditor {
  
  ...

  public void setView2FixedMode(boolean fixedMode){        
    FixedElementsTool fixedElementsTool = (FixedElementsTool) tools[FIXED_ELEMENTS];
    fixedElementsTool.setFixedMode(fixedMode);
  }

  ...
 
}

Then we create a new method in the tool and it will be called from the editor to tell you that now is active, ie, we are in fixedmode. Now, the tool can get your information of the elements that have fixed and re-painted them. This new method is setFixedMode(boolean setMode):

public class FixedElementsTool extends MouseEditorTool{

  ...

  public void setFixedMode(boolean setMode){
    Canvas2D c = editor.getCanvas2D();
    ProblemModel model;
    PointXY pxy;
    PointPainter pointPainter;
      
    model = (ProblemModel)editor.getModel();
      
    if (setMode){
      if (drawable2DElement1!=null){              
        pxy = ((MEPoint)((ViewElement)drawable2DElement1).getModelElement()).getPointXY(model);
        pointPainter = (PointPainter)((ViewElement)drawable2DElement1).getPainter();
        ((FixedPointPainter)pointPainter).fixPoint(pxy);                       
        pointPainter.paint(c, ap, pxy, null);
              c.repaint(true);           
          }
          if (drawable2DElement2!=null){       
              pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
              pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
              ((FixedPointPainter)pointPainter).fixPoint(pxy);                       
              pointPainter.paint(c, ap, pxy, null);
              c.repaint(true);           
          }          
      }
      else{
          if (drawable2DElement1!=null){
              pxy = ((MEPoint)((ViewElement)drawable2DElement1).getModelElement()).getPointXY(model);
              pointPainter = (PointPainter)((ViewElement)drawable2DElement1).getPainter();
              ((FixedPointPainter)pointPainter).dropPoint(pxy);          
         }
         if (drawable2DElement2!=null){
             pxy = ((MEPoint)((ViewElement)drawable2DElement2).getModelElement()).getPointXY(model);
             pointPainter = (PointPainter)((ViewElement)drawable2DElement2).getPainter();
             ((FixedPointPainter)pointPainter).dropPoint(pxy);
         }     
         if ((drawable2DElement1!=null) || (drawable2DElement1!=null)) c.repaint(true);  
      }      
  }

  ...

}

Conclusion

In this paper we saw how to start a new tool. We have talked adding a new button to the ToolBar?, create a new Tool, a Painter, we have explained the functioning of the Recognized classes, of the Mouse events and of the communication between the Tool and GUI.

Now, we will program more specific of each tool, but the basics to understand the tools parts is discussed.

Attachments