JFrame repaint() issues - Java

Mr Tickle picture Mr Tickle · Jun 20, 2011 · Viewed 11k times · Source

I want to be able to draw using Java's paint() on a JFrame. When I click the JFrame (anywhere for now) I want the JFrame to be repainted with the co-ordinates of the click - similar to this Java applet http://www.realapplets.com/tutorial/MouseClickExample.html

Currently Working:

  • Everything is drawn initially and the JFrame is properly displayed

Not Working:

  • JFrame does not repaint and update even when repaint() is declared

Here is my code - Please be as stringent as possible with it - I would like to improve my Java programming technique so (if you have time that is) point out every aspect I could improve on.

Any help would be very much appreciated.

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

class AreaForText extends JPanel implements MouseListener {

int xpos; 
int ypos;

JFrame myJFrame = new JFrame();

public void setJFrame() {

    myJFrame.setSize(300, 150);
    myJFrame.setTitle("Bigger Text!");
    myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myJFrame.setVisible(true);
    myJFrame.getContentPane().add(new AreaForText());
    myJFrame.addMouseListener(new AreaForText());

}

public void mouseClicked(MouseEvent me) {
    //Save the coordinates of the click lke this. 
    xpos = MouseInfo.getPointerInfo().getLocation().x; 
    ypos = MouseInfo.getPointerInfo().getLocation().y;
    System.out.print("Click" + "  x: " + xpos + "  y: " + ypos);
    myJFrame.invalidate();
    repaint();
    revalidate();
}


public void mouseEntered(MouseEvent e){
}

public void mouseReleased(MouseEvent e) { 
}

public void mousePressed(MouseEvent e) {
}

public void mouseExited(MouseEvent e) { 
}

public void paint(Graphics g) {

    System.out.print("hello");
    g.drawString("Hello World", 30, 80);
    g.fillRect(20,20,20,20);        
    g.drawString("("+xpos+","+ypos+")",xpos,ypos);

    }
}

class EnlargeText {

    public static void main(String args[]) {

       AreaForText test = new AreaForText();

       test.setJFrame();

    }

 } 

Answer

wolfcastle picture wolfcastle · Jun 20, 2011

You are creating 2 instances of AreaForText which is not what you want to do. One is added to the JFrame, and one is added to the listener. So the one that actually gets the mouse events and is calling repaint is not the same object that is being displayed.

Some of your code organization is not the best. You have a JPanel subclass that builds its own JFrame and puts itself into the panel. You should just pass in the JFrame if you really need it. I've made a few changes below.

EDIT. I fixed up some of the mouse listener stuff, you were getting the wrong X/Y co-ordinates, and also, you should just add the listener to the panel directly, not the JFrame, that way you don't have to translate the co-ordinates.

EDIT I changed the paint method to paintComponent, which is the preferred method to override here. Have a look at the Swing Paint Tutorial for more information.

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

class AreaForText extends JPanel implements MouseListener {

    private int xpos;
    private int ypos;


    public AreaForText() {
        super();
        this.addMouseListener(this);
    }

    public void mouseClicked(MouseEvent me) {
        // Save the coordinates of the click lke this.
        xpos = me.getX();
        ypos = me.getY();
        System.out.print("Click" + "  x: " + xpos + "  y: " + ypos);
        repaint();
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.print("hello");
        g.drawString("Hello World", 30, 80);
        g.fillRect(20, 20, 20, 20);
        g.drawString("(" + xpos + "," + ypos + ")", xpos, ypos);

    }
}

class EnlargeText {

    public static void main(String args[]) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame myJFrame = new JFrame("Bigger Text!");
                myJFrame.setSize(300, 150);
                myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myJFrame.getContentPane().add(new AreaForText());
                myJFrame.setVisible(true);
            }
        });
    }

}