AppletTalk.com Forum Index AppletTalk.com
Java discussions newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

painting / origin puzzle

 
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java GUI Toolkits
View previous topic :: View next topic  
Author Message
cerios
Guest





PostPosted: Fri Apr 22, 2005 11:26 pm    Post subject: painting / origin puzzle Reply with quote



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----------------
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java GUI Toolkits All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.