views:

1401

answers:

4

hi, I'm trying to make an applet which I can simply drag an image. And I want image object to listen events. So here is the applet code which simple run in a thread:

import java.awt.*;
import java.net.URL;
import javax.swing.JApplet;

public class Client extends JApplet implements Runnable {
 private static final long serialVersionUID = 1L;
 MediaTracker mediaTracker;
    Image [] imgArray;
    Tas t1;

    public void init() 
    { 
        mediaTracker = new MediaTracker(this);
        imgArray = new Image[1];

        URL base = getCodeBase(); 
        imgArray[0] = getImage(base,"okey.png");
        mediaTracker.addImage(imgArray[0],1);

        try {
   mediaTracker.waitForAll();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }

  t1 = new Tas(this, new Rectangle(0, 0, imgArray[0].getWidth(this), imgArray[0].getHeight(this)), imgArray[0]);

  Thread t = new Thread(this);
  t.start();
    }

    public void paint(Graphics g) 
    {
        t1.paint(g);
    }

 @Override
 public void run() {
  while(true){
   //System.out.println("run");
   repaint();
   try {
    Thread.sleep(200);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
}

And the class of object which holds image is:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Movable extends JPanel implements MouseListener {

public Client mainObj;
public Rectangle rect;
public Image image;

public Movable(Client mainObj, Rectangle rect, Image image) {
 this.mainObj = mainObj;
 this.rect = rect;
 this.image = image;
 addMouseListener(this);
}

public void paint(Graphics g) {
 g.drawImage(image, rect.x, rect.y, rect.width, rect.height, this);
}

@Override
public void mouseClicked(MouseEvent arg0) {
 System.out.println("clicked");
}

@Override
public void mouseEntered(MouseEvent arg0) {

}

@Override
public void mouseExited(MouseEvent arg0) {

}

@Override
public void mousePressed(MouseEvent arg0) {
 System.out.println("pressed");
}

@Override
public void mouseReleased(MouseEvent arg0) {

}
}

@SuppressWarnings("serial")
class Tas extends Movable{
    public String name = "";

    public Tas(Client mainObj, Rectangle rect, Image image) {
     super(mainObj, rect, image);
    }


}

I can see the image in my applet but nothing happens when I click in or out of the image. So what's wrong with this code.

A: 

First of all you should never override the paint method of a top level container (JApplet, JFrame, JDialog).

Then to do custom painting on other Swing components you override the paintComponent() method of the component, NOT the paint() method. Read the Swing tutorial on Custom Painting. So first fix those problems.

I'm not sure what the point of the Thread is but remove it from your code until you solve your other problems. If you are trying to do animation, then you should be using a Swing Timer, not a Thread.

If you want to see some code for dragging components you can take a look at Moving Windows for some generic code.

camickr
A: 

The simple answer is - you don't have code to do anything in mousePressed() or mouseReleased().

There are lots of other problems in the code though...

Simplest solution I could come up with -

public class Client extends JApplet {

private MouseInputAdapter myMouseListener = new MyMouseListener();

public void init() {
 // usually a very bad idea, but needed here 
 // since you want to move things around manually
 setLayout(null);

 // assuming this will get used often, so making it a method.
 addLabelForImage(getImage(getCodeBase(), "okay.png"));
}

private void addLabelForImage(Image image) {
 ImageIcon icon = new ImageIcon(image);
 JLabel l = new JLabel(icon);
 add(l);
 l.setSize(l.getPreferredSize());
 // you'll probably want some way to calculate initial position 
 // of each label based on number of images, size of images, 
 // size of applet, etc. - just defaulting to 100,100 now.
 l.setLocation(100, 100);
 l.addMouseListener(myMouseListener);
 l.addMouseMotionListener(myMouseListener);
}

// Made this a MouseInputAdapter because I assume you may want to handle
// other types of mouse events later...
private static class MyMouseListener extends MouseInputAdapter {
 @Override
 public void mouseDragged(MouseEvent e) {
  // when the mouse is dragged over a the component this listener is
  // attached to (ie - one of the labels) convert the point of the mouse
  // event from the internal component coordinates (0,0 is upper right 
  // corner of each label), to it's parent's coordinates (0,0 is upper
  // right corner of the applet), and set the components location to 
  // that point.
  Component theLabel = e.getComponent();
  Container theApplet = theLabel.getParent();
  Point labelPoint = e.getPoint();
  Point appletPoint = SwingUtilities.convertPoint(
    theLabel, labelPoint, theApplet );
  theLabel.setLocation(appletPoint);
 }
}

}
Nate
+1  A: 

Assuming that Tas in code #1 is Moveable in code #2...

You don't actually use the Moveable as a Component, but instead ask it to paint itself onto the Applet's graphics context, here:

public void paint(Graphics g) 
{
    t1.paint(g);
}

Instead you should add an instance of Moveable onto the Applet's container, wherein painting will become automatic, and it will start to receive mouse events. You can also remove that paint() method then too.

banjollity
yes a simple add(t1); solved my problem, thanks.
dhalsim
A: 

This is a working solution. It is not an applet but you can easily convert that. Hope it helps :

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class ImagePanel extends JPanel {

    Image image;
    Point2D axis = new Point2D.Double();
    boolean drag = false;
    Point2D dragPoint = new Point2D.Double();

    public ImagePanel(Image image) {
     this.image = image;
     setPreferredSize(new Dimension(300,300));
     addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
       drag = true;
       dragPoint = e.getPoint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
       drag = false;
      }
     });
     addMouseMotionListener(new MouseMotionAdapter() {
      @Override
      public void mouseDragged(MouseEvent e) {
       if (drag) {
        axis.setLocation(axis.getX()
          + (e.getPoint().x - dragPoint.getX()), axis.getY()
          + (e.getPoint().y - dragPoint.getY()));
        dragPoint = e.getPoint();
        repaint();
       }
      }
     });
    }

    @Override
    public void paintComponent(Graphics g) {
     g.setColor(Color.white);
     g.fillRect(0, 0, getWidth(), getHeight());
     g.drawImage(image, (int) axis.getX(), (int) axis.getY(), null);
    }

    public static void main(String[] args) {
     try {
      JFrame f = new JFrame();
      f.getContentPane().add(
        new ImagePanel(ImageIO.read(new File("image.jpg"))));
      f.pack();
      f.setVisible(true);
     } catch (IOException e) {
      e.printStackTrace();
     }
    }

}
Savvas Dalkitsis