Проблема с указателем мыши в Java Swing

Я создал следующую простую программу Java Swing, которая выводит квадрат 3 * 3 в окне каждый раз, когда пользователь щелкает мышью. Квадраты остаются в окне, даже если пользователь щелкает более одного раза. Программа компилируется и работает нормально, однако, когда кто-то щелкает в окне, квадрат рисуется намного ниже того места, где находится указатель мыши. Я некоторое время ломал голову над этим - что я могу здесь изменить, чтобы квадрат появлялся точно с указателем при каждом щелчке? Большое спасибо за любую помощь!

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;


public class ClickCloud extends JComponent {

    final ArrayList<Point2D> points = new ArrayList<Point2D>();

    public void addPoint(Point2D a) {
        points.add(a);
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        for (int i = 0; i < points.size(); i++) {
            Point2D aPoint = points.get(i);
            g2.draw(new Rectangle2D.Double(aPoint.getX(), aPoint.getY(), 3, 3));
        }
    }

    public static void main(String[] args) {
        final ClickCloud cloud = new ClickCloud();
        JFrame aFrame = new JFrame();

        class ClickListen implements MouseListener {

            @Override
            public void mouseClicked(MouseEvent arg0) {
            }

            @Override
            public void mouseEntered(MouseEvent arg0) {
            }

            @Override
            public void mouseExited(MouseEvent arg0) {
            }

            public void mousePressed(MouseEvent arg0) {

                cloud.addPoint(arg0.getPoint());
                cloud.repaint();

            }

            @Override
            public void mouseReleased(MouseEvent arg0) {

            }
        }

        aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aFrame.setSize(500, 500);
        aFrame.add(cloud);
        aFrame.addMouseListener(new ClickListen());
        aFrame.setVisible(true);
    }
}

person astroDude1    schedule 02.03.2011    source источник


Ответы (1)


Вы добавляете MouseListener в JFrame, но отображаете результаты в JComponent и относительно JComponent. Таким образом, местоположение нажатой точки будет относиться к координатам JFrame, но затем отображаться относительно координат JComponent, что сместит вещи вниз на расстояние строки заголовка. Вместо этого просто добавьте MouseListener к тому же компоненту, который отвечает за отображение результатов, чтобы координаты отображения и щелчка совпадали:

  aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  aFrame.setSize(500, 500);
  aFrame.add(cloud);
  //!! aFrame.addMouseListener(new ClickListen());  // !! Removed
  cloud.addMouseListener(new ClickListen());  // !! added
  aFrame.setVisible(true);

Кстати: спасибо за создание и публикацию приличного SSCCE, так как это значительно упрощает анализ и решение вашей проблемы.

person Hovercraft Full Of Eels    schedule 02.03.2011
comment
Не благодарите меня, это я задаю вопрос! lol Вы очень помогли, большое СПАСИБО! Быстрое и отличное решение. - person astroDude1; 02.03.2011