JavaのオブジェクトにmouseListenerを追加する
質問
画像をドラッグするだけでできるアプレットを作成しようとしています。そして、画像オブジェクトにイベントをリッスンさせたいと思います。ここでは、スレッド内で単純に実行されるアプレット コードを示します。
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();
}
}
}
}
画像を保持するオブジェクトのクラスは次のとおりです。
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);
}
}
アプレットに画像が表示されますが、画像をクリックしてもクリックしても何も起こりません。では、このコードの何が問題なのか。
解決
...コード#1のタスコード#2に移動可能であると仮定すると
あなたは、実際のコンポーネントとして可動を使用していますが、その代わりここで、アプレットのグラフィックスコンテキスト上に自分自身をペイントするためにそれを聞かないます:
public void paint(Graphics g)
{
t1.paint(g);
}
の代わりに絵が自動になりますここで、あなたは、アプレットのコンテナに可動のインスタンスを追加する必要があり、それがマウスイベントを受け取るために開始します。あなたは、あまりにもそのpaint()メソッドを削除することができます。
他のヒント
まず第一に、トップレベルのコンテナ (JApplet、JFrame、JDialog) のペイント メソッドを決してオーバーライドしないでください。
次に、他の Swing コンポーネントでカスタム ペイントを行うには、paint() メソッドではなく、コンポーネントのPaintComponent() メソッドをオーバーライドします。Swing チュートリアルを読む カスタムペイント. 。したがって、まずそれらの問題を解決してください。
このスレッドの意味はわかりませんが、他の問題が解決するまでコードからスレッドを削除してください。アニメーションを実行しようとしている場合は、 スイングタイマー, 、スレッドではありません。
コンポーネントをドラッグするためのコードを確認したい場合は、以下を参照してください。 ウィンドウの移動 いくつかの汎用コードの場合。
これは実用的なソリューションです。これは、アプレットではありませんが、あなたは簡単にそれを変換することができます。それがお役に立てば幸います:
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();
}
}
}
簡単な答えは - あなたがのmousePressed()またはのmouseReleased()で何かをするためのコードを持っていません。
コード内の他の多くの問題がありますが...
私が思い付くことができ最も簡単な解決策 -
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);
}
}
}