Buffalo
Buffalo

Reputation: 4042

Java graphics trouble

I have a JComponent with a listener on it. On the JComponent, I draw a big image and the mouse listener adds small images where clicks occur (one big map on which I add some dots).

How can I programatically draw something outside the paintComponent method?

 public void paintComponent(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;

   g2.drawImage(img1, 0, 0, this);
   g2.finalize();

 }

 private MouseListener listener; 

 public void initListener() {
   myCanvas = this;
   listener = new MouseAdapter() {
     public void mouseClicked(MouseEvent e) {
       myCanvas.getGraphics().drawImage(img,e.getX(),e.getY(), myCanvas);
     }
   };
   addMouseListener(listener);

 }

My problem is with this:

public void drawDot(int x, int y){
 myCanvas.getGraphics().drawImage(img, x, y, myCanvas);
}

It doesn't do anything. I have tried repaint().

Upvotes: 1

Views: 152

Answers (3)

Jack
Jack

Reputation: 133577

You have to manage the drawing inside the paintComponent method. Java Graphics is not stateful, you have to take care of what you actually need to draw whatever you want inside the method. Every time the paint method is called, everything must be drawn again, there is nothing that "stays" on the canvas while adding other components

This means that you should store a list of elements that the paint method will take care to draw, eg. ArrayList<Point> points, then in paint method you should iterate them:

for (Point p : points)
  draw the point

so that you just add the point to the list with the listener and call repaint. You can find guidelines for Swing/AWT drawing here..

A particual API has the behavior you would like to have though, it is called Cocos2D and it has a port for Android/Java that you can find here.

Upvotes: 2

sharpner
sharpner

Reputation: 3937

that is not how draw works, the draw method paints everything which is in the method itself on every repaint, that means if you call a method to draw something once, it will only be drawed for one repaint cycle and that's it.

if you want something t be drawn on click you have to add it on on click to a collection and draw the whole collection in every paint cycle, so it will stay permanently.

Upvotes: 0

chubbsondubs
chubbsondubs

Reputation: 38706

You can't do this. All drawing occurs in the paintComponent() method. What you should do is build a model that represents what you want to draw, and modify the model in your mouse listener. Then call repaint() to ask that this component be redrawn when the model is modified. Inside your paint() method render the full paint from the model. For example:

List<Point> pointsToDrawSmallerImage = new ArrayList<Point>();

...

listener = new MouseAdapter() {
    public void mouseClicked(MouseEvent evt ) {
        pointsToDrawSmallerImage.add( evt.getPoint() );
        repaint();
    }
}
...

public void paintComponent(Graphics g) {
    g.clear();   // clear the canvas
    for( Point p : pointsToDrawSmallerImage ) {
       g.drawImage(img, p.x, p.y, myCanvas);           
    }
}

Upvotes: 2

Related Questions