私が作成した「キャンバス」クラス (拡張された ) を使用して Java で問題が発生しJPanel
、アニメーションのリング チャートを描画しました。このグラフは を使用しMouseListener
てクリック イベントを取得しています。
問題は、マウスの位置が正確ではないように見えることです。つまり、「キャンバス」に対して相対的ではなく、ウィンドウに対して相対的であるように見えます (左上隅で、y 座標に約 30px を取得しました)。
これは私のコードです:
JPanel を拡張し、メンバーとして BufferedImage を持つクラスを作成しました。
public class Canvas extends JPanel {
public BufferedImage buf;
private RingChart _parent;
public Canvas(int width, int height, RingChart parent){
buf = new BufferedImage(width, height, 1);
...
ペイント コンポーネント メソッドでは、バッファリングされたイメージを描画するだけなので、公開されているバッファリングされたイメージにペイントすることで、「外側」からキャンバスにペイントできます。
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(buf, null, 0, 0);
}
「キャンバス」を含む RingChart クラスがあります。
public class RingChart extends JFrame{
public Canvas c;
...
そして、キャンバス クラスで bufferedImage から Graphics2D を作成します。この g2d はペイントに使用されます:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
setSize(1500, 1000);
setTitle("Hans");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g2d = (Graphics2D)c.buf.createGraphics();
...
私が今達成しようとしていたのは、キャンバス上で発生するマウス イベントをリッスンするマウス リスナーでした。したがって、ユーザーがキャンバスをクリックすると、イベント変数を介して、キャンバス上でクリックした位置を取得できます。
そこで、マウス リスナーを作成しました。
class MouseHandler implements MouseListener {
@Override
public void mouseClicked(MouseEvent e){
RingChart r = ((Canvas)e.getSource()).getParent();
r.mouseClick(e);
}
...
...そして、このマウス リスナーを RingChart クラスのキャンバスに追加しました (myChart は RingChart のインスタンスで、c は含まれるキャンバスです)。
...
MouseHandler mouse = new MouseHandler();
myChart.c.addMouseListener(mouse);
...
しかし、上で述べたように、クリック イベントが呼び出されたときに返されるマウスの位置は正確ではないようです。間違いは、私がその mouseListener を作成した方法、または間違った要素に割り当てた方法などにあるに違いないと思います。しかし、私はかなりのことを試しましたが、それは変わりませんでした。私が間違ったことを誰かが教えてくれますか?
アップデート:
RingChart のメンバーであり、マウス リスナーで呼び出される関数「mouseClick」のコード:
public void mouseClick(MouseEvent evt){
//evt = SwingUtilities.convertMouseEvent(this, evt, c);
if(evt.getButton() == MouseEvent.BUTTON1 && animation == null){
for(Element e : elements){
if(e.getShape() != null && e.getShape().contains(evt.getPoint())){
//do some stuff
}
}
}
}
繰り返しますが、私のクラスの階層: RingChart --contains a--> Canvas --got a--> MouseListener. この関数の形状は、キャンバス c に描かれた形状です。ユーザーがそれらのいずれかをクリックしたかどうかを確認したいと思います。私が思ったように、形状はキャンバス座標にある必要があり、イベントの位置はキャンバス座標にある必要があり、すべてが一致する必要があります。しかし、そうではありません。ここで、ユーザー MadProgrammer から、ConvertMouseEvent 関数を使用するように言われました。しかし、現在、これを賢明に使用する正確な方法はわかりません。
アップデート:
私は解決策を見つけました:私がしなければならなかったのは、キャンバスをに直接追加するJFrame
のではなくContentPane
、JFrame
代わりにのに追加することだけです:
代わりに:
public RingChart(){
c = new Canvas(1500,980,this);
add(c);
...
そうです:
public RingChart(){
c = new Canvas(1500,980,this);
getContentPane().add(c);
...
次に、 を に渡しMouseListener
ますContentPane
。
getContentPane().addMouseListener(new MouseHandler());
getContentPane().addMouseMotionListener(new MouseMoveHandler());
これがエレガントなソリューションかどうかはわかりませんが、機能します。