2009-07-15 4 views
1

Ich versuche, ein Applet zu machen, das ich einfach ein Bild ziehen kann. Und ich möchte, dass ein Bildobjekt auf Ereignisse hört. Also hier ist der Applet-Code, der einfach laufen in einem Thread:Hinzufügen von MouseListener zu meinem Objekt in Java

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(); 
      } 
     } 
    } 
} 

Und die Klasse des Objekts, das Bild hält, ist:

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); 
    } 


} 

ich das Bild in meinem Applet sehen können, aber es passiert nichts, wenn ich Klicken Sie in oder aus dem Bild. Also, was ist mit diesem Code falsch?

Antwort

1

Unter der Annahme, dass Tas in Code # 1 in Code # 2 beweglich ist. ..

Sie eigentlich nicht die Verschiebbare als Komponente verwenden, aber es stattdessen selbst zu malen, fragt auf den Grafikkontext des Applet, hier:

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

Stattdessen sollten Sie eine Instanz von Moveable auf den Container des Applets hinzufügen, wobei das Zeichnen automatisch erfolgt und Mausereignisse erhalten. Sie können diese paint() -Methode auch entfernen.

+0

ja ein einfaches hinzufügen (t1); löste mein Problem, danke. – dhalsim

0

Zunächst sollten Sie die Paint-Methode eines Top-Level-Containers (JApplet, JFrame, JDialog) niemals überschreiben.

Dann benutzerdefinierte Bild auf anderen Swing-Komponenten zu tun, überschreiben Sie die PaintComponent() -Methode der Komponente, NICHT die Paint() -Methode. Lesen Sie das Swing-Tutorial unter Custom Painting. Also zuerst diese Probleme beheben.

Ich bin nicht sicher, was der Punkt des Threads ist, aber entfernen Sie es aus Ihrem Code, bis Sie Ihre anderen Probleme lösen. Wenn Sie versuchen, eine Animation auszuführen, sollten Sie einen Swing Timer verwenden, keinen Thread.

Wenn Sie Code zum Ziehen von Komponenten sehen möchten, können Sie einen Blick auf Moving Windows für einige generische Code.

0

Die einfache Antwort ist - Sie haben keinen Code, um etwas in MousePressed() oder MouseReleased() zu tun.

Es gibt viele andere Probleme im Code aber ...

Simplest Lösung kann ich kommen mit -

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); 
    } 
} 

} 
0

Dies ist eine funktionierende Lösung. Es ist kein Applet, aber Sie können das einfach konvertieren. Hoffe es hilft:

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(); 
     } 
    } 

}