alicedimarco
alicedimarco

Reputation: 325

Why isn't my paintComponent working?

What I want to do with my program is when I click the image, the rectangle will come out, together with the JOptionPane. However, the JOptionPane is the only thing popping up.

I tried changing methods and adding more classes, nothing worked >.< Can anyone shed some light to my problem? Here's a snippet of my code.

Below is where I call the filechooser which allows me to select my photo. Also, a bunch of other stuff like labels are here.

public Help(){

        fc.setDialogTitle("Choose an image file to begin:");
        int returnval = fc.showOpenDialog(null);
        if (returnval == JFileChooser.APPROVE_OPTION){ //when user selects a file, value returned will be JFileChooser.APPROVE_OPTION
            File file = fc.getSelectedFile(); //the File value of the selection is returned from a call on getSelectedFile
            try{
                image = ImageIO.read(file); //reads and loads File as image
            }
            catch (IOException e){}
                System.out.println("You chose to open this file: " + file.getName());
        }else
            System.out.println("No file selected.");

        icon = new ImageIcon(image);
        label = new JLabel(icon);
        tagName = new JLabel(input);

        label.addMouseListener(new ImagePanel());
        label.addMouseMotionListener(new ImagePanel());
        panel.add(tagName);
    }

And finally, my ImagePanel class, which contains the troublesome paintComponent. Also, a couple of mouseListeners.

class ImagePanel extends JPanel implements MouseListener, MouseMotionListener{

        @Override
        public void mouseClicked(MouseEvent event) {
            // TODO Auto-generated method stub

                x = event.getX();
                y = event.getY();

                input = JOptionPane.showInputDialog("Enter tag name");
                tagName.setText("You have tagged: " + input);
                System.out.println(input);
        }

        @Override
        public void mouseEntered(MouseEvent arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseReleased(MouseEvent arg0) {
            // TODO Auto-generated method stub

        }

        public void paintComponent(Graphics g){
            super.paintComponent(g);

                if(image != null && isRectPresent){
                    g.setColor(Color.DARK_GRAY);
                    g.drawRect(x-50, y-50, 100, 100);
                }
        }   

        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            // TODO Auto-generated method stub
        }
    }

You can compile the code and see for yourself. Give me a heads up if you know what to do :) Thank you so much!

Upvotes: 0

Views: 356

Answers (3)

camickr
camickr

Reputation: 324108

All kinds of weird stuff:

label.addMouseListener(new ImagePanel());
label.addMouseMotionListener(new ImagePanel()); 

You should not be creating a new JPanel just to add a listener to a component. You already have an instance of the panel.

addMouseMotionListener(this);  

Never add a listener to a component in a painting method. You can never control when the painting methods are invoked and you will end up with the same listener added multiple times.

Upvotes: 2

Ishtar
Ishtar

Reputation: 11662

  try{
       image = ImageIO.read(file); //reads and loads File as image
   }
   catch (IOException e){}

Here the code says: "let's try to read an image. If that fails (an exception is thrown) then ignore the problem and continue without the image.". Ignoring problems is always bad. We could at least print the problem and continue.

  try{
      image = ImageIO.read(file); //reads and loads File as image
  }
  catch (IOException e){
     e.printStackTrace();//print the exception
  }

Or print the problem and stop:

  try{
      image = ImageIO.read(file); //reads and loads File as image
  }
  catch (IOException e){
     e.printStackTrace();//print the exception
     System.exit(0);//stop executing
  }

The actual problem is most likely here:

if(image != null && isRectPresent){
   g.setColor(Color.DARK_GRAY);
   g.drawRect(x-50, y-50, 100, 100);
}

I think the problem is that the if condition is false (there is no image(perhaps there was an exception reading it...?) and/or isRectPresent is false) thus it does nothing! Include a break point at the if, launch your program in debug mode and inspect the variables image and isRectPresent when the program reaches this point. (If it doesn't get there, you know you got a different problem.) Good luck!

Upvotes: 0

Joop Eggen
Joop Eggen

Reputation: 109547

One note: a smaller example would have been answered earlier.

Assign the mouse events x and y to self-defined fields in ImagePanel, with other names, like:

int mx;
int my;

The other things to experiment with, is leaving out super.paintComponent. Furthermore maybe you want to use more methods on g:

Graphics2D g2 = (Graphics2D)g;

(Assigning to base classes x and y is never a good idea; better use setBounds for something like changing coordinates.)

Upvotes: 1

Related Questions