Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

painting / origin puzzle
Hi,

I've tried to make a class that allows one to annotate an image
by clicking with the mouse; each mouse click will place a little "X"
or other graphic at that location.  The class is user-configurable, with
callbacks to handle what happens when you click, and a list
of callbacks to draw the graphics.

The puzzle:  after I click on the image, the repaint draws
the image origin _at the location of the mouse click_,
rather than at 0,0,  though I do not ask it to do this.

I've produced a simplified example, where the "image" is a just a
red square.   There is a base class "GRJImage" with a paintComponent
method that does this:

Graphics g2 = g.create();
g2.setColor(Color.red);
g2.fillRect(0, 0, getWidth(), getHeight()); // testing, show the
problem

Then a derived class "GRJTestImage" handles all the mouse callback
stuff.
It's paintComponent() is like this:

Graphics g2 = g1.create();   // save the context
super.paintComponent(g1); // draw the red rectangle
int npts = _drawList.size(); //d raw the graphics
for( int i = 0; i < npts; i++ ) {
Drawable d = (Drawable)_drawList.get(i);  d.draw(g2);
}
g2.dispose();

I do not see what is causing the fillRect to draw at a location
other than 0,0!  And various fiddling with copying the Graphics
object and reusing it has not resolved it.

Here are two files that isolate the problem.  If you compile and run,
you will see a red rectangle.  Increase the window size.
Then click inside the window, and the red rectangle will
move so it's upper-left is at the mouse location, rather
than covering the whole window.

This is on jdk1.4 on a mac, though I think it is my bug rather
than apple's.

----------------GRJImage.java----------------
import java.awt.*;
import javax.swing.*;

public class GRJImage extends JComponent
{
final int _verbose = 2;
int    _xres;
int    _yres;

public GRJImage()
{
}

public void setImage()
{
_xres = 300;
_yres = 200;
} //setImage


public Dimension getPreferredSize()
{
return new Dimension(_xres, _yres);
}


public void paintComponent(Graphics g)
{
Graphics g2 = g.create();

if (_verbose > 1) System.out.println("GRJImage.paint");

if (isOpaque()) {
//&& ((_xres != getWidth()) || (_yres != getHeight()))) {
// this is the specified desired behaviour for paintComponent,
// but is inefficient, so warn if we end up doing it.
System.out.println("PAINTING BACKGROUND "+_xres+" "+getWidth());
g2.setColor(getBackground());
g2.fillRect(0, 0, getWidth(), getHeight());
}

g2.setColor(Color.red);
g2.fillRect(0, 0, getWidth(), getHeight()); // testing, show the
problem

g2.dispose();
} //paintComponent

} //GRJImage

----------------GRJTestImage.java----------------
// GRJTestImage.java - debug the interface mouseclick puzzle

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
* displays an image, with manipulatible drawn overlays.
*
* _drawList is an arrayList of things to draw, each is passed
*  the Graphics2D and maintains its own location.  Each also
*  has a clicked() method that gets called when the image is clicked
*  near it.
*
* _clickList is a list of callbacks to call on each mouseClick.
* Register something with this in order to get something onto the
drawlist.
*
* Example usage:
* create an OnClick whose call() method creates a drawable
* located at the click location, adds it to the drawList,
* and optionally removes itself from the clickList.
*
* <pre>
*  GRJTestImage p = new GRJTestImage(pic);

p.addDrawable(_trackMarker);

GRJTestImage.OnClick c = new GRJTestImage.OnClick() {
public void call(int x, int y) {
Drawable d = new GRJTestImage.plusMarker(x,y, Color.red);
p.addDrawable(d);
}
};
p.addOnClick(c);
*/
public class GRJTestImage extends GRJImage
{
final GRJTestImage _p;
ArrayList _drawList = new ArrayList();
ArrayList _clickList = new ArrayList();
int    _lx, _ly;   // location of last mouse click

//----------------------------------------------------------------

public int getX() { return _lx; }
public int getY() { return _ly; }

public void setX(int x) { _lx = x; }
public void setY(int y) { _ly = y; }

//----------------------------------------------------------------

// an OnClick handler is a high level click dispatcher
// c.f. drawable, which also does mouse handling, but is intended
// to be a single object such as a point or curve.
public interface OnClick
{
void call(int x, int y);
}

public void addOnClick(OnClick c)
{
System.out.println("adding clickable "+c);
_clickList.add(c);
}

public void removeOnClick(OnClick c)
{
System.out.println("removing clickable "+c);
_clickList.remove(c);
}

public void clearOnClick()
{
_clickList.clear();
}

//----------------------------------------------------------------

public interface Drawable
{
// GRJTestImage makes a copy of g, so this method does not need
// to restore its state, at least if the next draw() knows
// how to reset what this one changed
void draw(Graphics g);

// formerly had getX/getY to let the caller see if a mouse click is
// near this object.  That does not work for a polyline, so
// have the object itself do the test.
// int  getX();    int  getY();

// did this event hit near us == should we be called with
click/press/...
boolean hit(MouseEvent evt);

// implement null methods if not interested
void click(MouseEvent evt, GRJTestImage p);
void press(MouseEvent evt, GRJTestImage p);
void drag(MouseEvent evt, GRJTestImage p);
void release(MouseEvent evt, GRJTestImage p);
}

public void addDrawable(Drawable d) { _drawList.add(d); repaint(); }

public void removeDrawable(Drawable d)
{
_drawList.remove(d);
System.out.println("removing drawable "+d+
", "+_drawList.size()+" remaining");
repaint();
}

public void removeDrawables()
{
_drawList.clear();
repaint();
}

//---------------- example drawable ----------------

public static class plusMarker implements Drawable {
int  _x,_y;
Color   _c;

public plusMarker(int x, int y, Color c) {
_x = x; _y = y; _c = c;
}

public void draw(Graphics g)
{
g.setColor(_c);
g.drawLine(_x-5,_y,_x+5,_y);
g.drawLine(_x,_y+5,_x,_y-5);
} //plus

public boolean hit(MouseEvent evt)
{
int mx = evt.getX();
int my = evt.getY();
int dx = _x - mx;
int dy = _y - my;
int d2 = (dx*dx + dy*dy);
// distance < 3 pixels
return (d2 < 9);
} //hit

public void click(MouseEvent evt, GRJTestImage p)
{
System.out.println("ispopuptrigger = "+evt.isPopupTrigger());
System.out.println("getbutton = "+evt.getButton());

if (evt.getButton() == 3) {   // 3 is the right mouse button
System.out.println("removing...");
p.removeDrawable(this);
p.repaint();
}
else {
_x = evt.getX();
_y = evt.getY();
}
} //click

public void press(MouseEvent evt, GRJTestImage p) {}
public void drag(MouseEvent evt, GRJTestImage p) {}
public void release(MouseEvent evt, GRJTestImage p) {}

} //plusMarker

//----------------------------------------------------------------

public GRJTestImage(/*gr[] img*/)
{
//super(img);
super();

setBorder(BorderFactory.createLineBorder(Color.BLUE, 5));

if (false)
setDebugGraphicsOptions(DebugGraphics.LOG_OPTION|
//DebugGraphics.FLASH_OPTION|
DebugGraphics.BUFFERED_OPTION);

_p = this;

addMouseListener(new MouseAdapter() {

public void mouseClicked(MouseEvent evt)
{
System.out.println("mouse clicked.");
super.mouseClicked(evt);

_lx = evt.getX();
_ly = evt.getY();

// call all the "clickables"
for( int i = 0; i < _clickList.size(); i++ ) {
System.out.println("calling clickable #"+i+", "+_lx+","+_ly);
OnClick c = (OnClick)_clickList.get(i);
c.call(_lx, _ly);
}

// note call all the drawables also, let them handle
// mouse events as well!
System.out.println("calling drawables.click");
for( int i = 0; i < _drawList.size(); i++ ) {
System.out.println("calling drawable #"+i);
Drawable d = (Drawable)_drawList.get(i);
if (d.hit(evt)) d.click(evt, _p);
else  System.out.println("missed hit");
}

repaint();
} //mouseClicked


public void mousePressed(MouseEvent evt)
{
System.out.println("mouse pressed.");
super.mousePressed(evt);

System.out.println("calling drawables.press");
if (false)
for( int i = 0; i < _drawList.size(); i++ ) {
System.out.println("calling drawable #"+i);
Drawable d = (Drawable)_drawList.get(i);
if (d.hit(evt)) d.press(evt, _p);
}

repaint();
} //mousePressed


public void mouseReleased(MouseEvent evt)
{
System.out.println("mouse released.");
super.mouseReleased(evt);

System.out.println("calling drawables.release");
for( int i = 0; i < _drawList.size(); i++ ) {
System.out.println("calling drawable #"+i);
Drawable d = (Drawable)_drawList.get(i);
if (d.hit(evt)) d.release(evt, _p);
}

repaint();
} //mouseReleased

});

addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
System.out.println("calling drawables.drag");
for( int i = 0; i < _drawList.size(); i++ ) {
System.out.println("calling drawable #"+i);
Drawable d = (Drawable)_drawList.get(i);
if (d.hit(e)) d.drag(e, _p);
}
}
});

} //constructor


public void paintComponent(Graphics g1)
{
if (_verbose > 1) System.out.println("GRJTestImage.paint");

Graphics g2 = g1.create();

super.paintComponent(g1);

int npts = _drawList.size();
for( int i = 0; i < npts; i++ ) {
System.out.println("calling drawable #"+i);
Drawable d = (Drawable)_drawList.get(i);
d.draw(g2);
}

g2.dispose();
} //paint

//----------------------------------------------------------------

public static GRJTestImage showme()
{
JFrame f = new JFrame("foo");
GRJTestImage p = new GRJTestImage();
f.getContentPane().add(p);
//f.setSize(xres+20, yres+20);
f. setDefaultCloseOperation(WindowConstants
.DISPOSE_ON_CLOSE);
f.setVisible(true);
f.repaint();
return p;
} //showme


//----------------------------------------------------------------

public static void main(String[] cmdline)
{
System.out.println("GRJTestImage");

final GRJTestImage p = GRJTestImage.showme();

OnClick c = new OnClick() {
public void call(int x, int y) {
Drawable d = new GRJTestImage.plusMarker(x,y, Color.red);
p.addDrawable(d);
p.removeOnClick(this);
}
};

p.addOnClick(c);

} //main

} //GRJTestImage
----------------end----------------

Report this thread to moderator Post Follow-up to this message
Old Post
cerios
04-23-05 08:58 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

Java Help archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 07:22 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.