Rulers, mouse position

Hi,

I am working on a GUI that also features rulers at the top and on the left side; I have followed the tutorial at http://java.sun.com/docs/books/tutorial/uiswing/components/scrollpane.html -> "How a Scroll Pane Works"; I am not using a scrollpane but a JPanel; my two rulers are JPanels as well. This works perfectly.

Now I would like to draw a vertical / horizontal line in the rulers when I move the mouse in my JPanel - like it's done in various graphics programs.

Here is my code for the rulers:

publicclass Rulersextends JComponent{

privatestaticfinallong serialVersionUID = 1;

privatestaticfinalint SIZE = 20;

publicstaticfinalint HORIZONTAL = 0;

publicstaticfinalint VERTICAL = 1;

privateint tickHeight = 8;

privateint orientation;

public Rulers(int o){

orientation = o;

}

protectedvoid paintComponent(Graphics g){

super.paintComponent(g);

setBorder(BorderFactory.createLineBorder(Color.BLACK));

Graphics2D g2 = (Graphics2D) g;

if (isOpaque()){

g2.setColor(Color.WHITE);

g2.fillRect(0, 0, getWidth(), getHeight());

}

g2.setFont(new Font("SansSerif", Font.PLAIN, 10));

g2.setColor(Color.BLACK);

if (orientation == HORIZONTAL){

for (int i = 0; i < 700; i += 200){

g2.drawLine(i, SIZE, i, SIZE - tickHeight);

}

}else{

for (int i = 0; i < 500; i += 200){

g2.drawLine(SIZE, i, SIZE - tickHeight, i);

}

}

}

}

My main JPanel:

publicclass PlayerMgmtextends JComponentimplements MouseMotionListener{

privatestaticfinallong serialVersionUID = 1;

private List <Point2D>playerAllCoordinatesList =new ArrayList<Point2D>();

private Point2D playerCurrentPosition, playerLastPosition;

private Rectangle2D playerStartPosition =new Rectangle2D.Double(100, 100, 20, 20);

privatefinalint ELLIPSE_WIDTH = 20;

privatefinalint ELLIPSE_HEIGHT = 20;

privatefinalint ELLIPSE_WH_OFFSET = 10;

private Line2D connectingLine;

public PlayerMgmt(){

addMouseListener(new MouseAdapter(){

publicvoid mouseClicked(MouseEvent evt){

if (SwingUtilities.isLeftMouseButton(evt)){

playerAllCoordinatesList.add(new Point2D.Double(evt.getX(), evt.getY()));

}

if (SwingUtilities.isRightMouseButton(evt)){

if (playerAllCoordinatesList.size() > 0) playerAllCoordinatesList.remove(playerAllCoordinatesList.size() - 1);

}

repaint();

}

});

}

protectedvoid paintComponent(Graphics g){

super.paintComponent(g);

Graphics2D g2 = (Graphics2D) g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

if (isOpaque()){

g2.setColor(Color.WHITE);

g2.fillRect(0, 0, getWidth(), getHeight());

}

if (playerAllCoordinatesList.size() == 0){

playerAllCoordinatesList.add(new Point2D.Double(100.0, 100.0));

}

g2.setColor(Color.GREEN);

g2.draw(playerStartPosition);

g2.setColor(Color.BLACK);

for(int i=1 ; i < playerAllCoordinatesList.size(); i++){

playerCurrentPosition = playerAllCoordinatesList.get(i);

playerLastPosition = playerAllCoordinatesList.get(i-1);

connectingLine =new Line2D.Double(playerLastPosition.getX(), playerLastPosition.getY(), playerCurrentPosition.getX(), playerCurrentPosition.getY());

g2.draw(new Ellipse2D.Double(playerCurrentPosition.getX()-ELLIPSE_WH_OFFSET, playerCurrentPosition.getY()-ELLIPSE_WH_OFFSET, ELLIPSE_WIDTH, ELLIPSE_HEIGHT));

g2.draw(connectingLine);

}

}

publicvoid mouseDragged(MouseEvent arg0){

// TODO Auto-generated method stub

}

publicvoid mouseMoved(MouseEvent arg0){

// TODO Auto-generated method stub

}

}

My first problem is that I don't find a way how I can read the mouse coordinates in my class "Rulers". Do I later have to use threads to update the mouse position (and draw it) at every mouse move?

Thanks a lot!

[7899 byte] By [SFLa] at [2007-11-26 18:28:28]
# 1
there are mouseEntered/Exited/Over events.or track the mouse with a thread is simple enough. But swing provided loads of methods to do it.
grilleda at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...
# 2
Simple drawing example: http://forum.java.sun.com/thread.jspa?forumID=57&threadID=607073
camickra at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...
# 3
Hmmm... I know that I have to use the getX() and getY() method. However, I failed to read the mouse coordinates (coming from my class "PlayerMgmt") in my class "Ruler". How could I do this?
SFLa at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...
# 4
Use a mouse listener (I would use an inner class of Ruler) which listens to the drawing panel. On mouseMoved(), store the event point and repaint. In your Ruler.paintComponent() method, draw the tick at the relevant location according to the stored point. Job done.
itchyscratchya at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...
# 5

> Use a mouse listener (I would use an inner class of

> Ruler) which listens to the drawing panel. On

> mouseMoved(), store the event point and repaint. In

> your Ruler.paintComponent() method, draw the tick at

> the relevant location according to the stored point.

> Job done.

itchyscratchy, thank you. I just have a problem with the first part: "...which listens to the drawing panel." How can I tell my mouse listener to listen to the drawing panel? I now have the mouse listener:

public Rulers(int o) {

orientation = o;

addMouseListener(new MouseAdapter(){

public void mouseMoved(MouseEvent evt) {

}

});

}

Do I need a mouse listener in my drawing panel PlayerMgmt?

SFLa at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...
# 6

I was thinking of something like this,

public class Ruler extends JComponent

{

public static final int HORIZONTAL = 1;

public static final int VERTICAL = 2;

private static final int THICKNESS = 10;

private final int orientation;

private int size = 0;

private int mouseTick = 0;

public static final void install(JScrollPane p)

{

Component c = p.getViewportView();

Ruler h = new Ruler(HORIZONTAL);

h.attach(c);

p.setColumnHeader(h);

Ruler v = new Ruler(VERTICAL);

v.attach(c);

p.setRowHeader(v);

}

public Ruler(int orientation)

{

this.orientation = orientation;

}

public void paintComponent(Graphics g)

{

// override to render ruler ticks etc plus mouse tick

}

public Dimension getPreferredSize()

{

return new Dimension((orientation == HORIZONTAL) ? this.size : THICKNESS, (orientation == HORIZONTAL) ? THICKNESS : this.size);

}

public void attach(Component c)

{

c.addMouseMotionListener(new Mouse());

c.addComponentListener(new Size());

}

private class Mouse extends MouseMotionAdapter

{

public void mouseMoved(MouseEvent e)

{

mouseTick = (orientation == HORIZONTAL) ? e.getX() : e.getY();

}

}

private class Size extends ComponentAdapter

{

public void componentResized(ComponentEvent e)

{

Component c = e.getComponent();

size = (orientation == HORIZONTAL) ? c.getWidth() : c.getHeight();

}

}

}

itchyscratchya at 2007-7-9 6:02:39 > top of Java-index,Desktop,Core GUI APIs...