简体   繁体   English

如何在JPanel中点击移动形状?

[英]How to make a shape move to click in JPanel?

I am trying to make to make a shape move to wherever I click my mouse. 我试图使形状移动到我单击鼠标的位置。 I got the shape to move, and it moves towards the general direction of where I clicked, but it never moves exactly to where I clicked, it misses by a good distance. 我得到了移动的形状,它朝着我单击的位置的大致方向移动,但是它永远不会精确地移动到我单击的位置,因此错过了一段很长的距离。 Since it doesn't move exactly to where I clicked, the shape continues to move and doesn't stop. 由于它不会完全移动到我单击的位置,因此形状会继续移动并且不会停止。

Here is the code: 这是代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

public class GraphicsTester extends JFrame implements MouseListener {
    private int startX;
    private int startY;
    private int endX;
    private int endY;
    private int stepX;
    private int stepY;
    private Timer sliderTimer = new Timer(40, new SlideListener());

    public GraphicsTester() throws IOException {
        setTitle("Graphics Tester 1");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JPanel basePanel = new JPanel(new BorderLayout()) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(Color.red);
                g2d.fillOval(215 + stepX, 215 + stepY, 30, 30);
                startX = stepX;
                startY = stepY;
                if (215 + stepX == endX && 215 + stepY == endY) {
                    sliderTimer.stop();
                }
            }
        };
        basePanel.setPreferredSize(new Dimension(500, 500));
        basePanel.addMouseListener(this);

        getContentPane().add(basePanel);
        pack();
        setVisible(true);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    new GraphicsTester();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        endX = e.getX();
        endY = e.getY();
        System.out.println("endX: " + endX + ", endY: " + endY);
        sliderTimer.start();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    private class SlideListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            stepX += (endX - startX) / 5; // the 5's are just arbitrary values, I chose 5 because it makes the shape slide at the speed I want
            stepY += (endY - startY) / 5;
            System.out.println("stepX: " + (215 + stepX) + ", stepY: " + (215 + stepY));
            repaint();
        }
    }
}

How can I make the shape move to exactly where I clicked? 如何使形状精确移动到单击的位置? The problem lies with stepX += (endX - startX) / 5; 问题在于stepX += (endX - startX) / 5; and stepY += (endY - startY) / 5; stepY += (endY - startY) / 5; . Those two lines are causing the shape not to move exactly to where I clicked, since they don't increment stepX and stepY precisely to the click and instead "round" at each increment. 这两行导致形状不能精确移动到我单击的位置,因为它们没有将stepXstepY精确地增加到单击位置,而是每次增加一个“舍入”。 I don't know how to fix these two lines so that they increment stepX and stepY exactly to where I clicked and therefore stop moving the shape once it reaches endX and endY . 我不知道如何固定这两行,以便它们将stepXstepY精确地增加到我单击的位置,因此一旦到达endXendY ,就停止移动形状。

Your main problem is that you add 215 to stepX and stepY in your paintComponent() method, which is why it appears to be 'way off'. 您的主要问题是您在paintComponent()方法中的stepXstepY中添加了215 ,这就是为什么它看起来“ stepY ”的原因。 This is because it draws at stepX + 215 and stepY + 215 , when you really want it drawn at exactly stepX and stepY (which are based on the mouse pointer at the time of clicking). 这是因为当您确实要在stepXstepY (它们都是基于单击时的鼠标指针)上绘制时,它在stepX + 215stepY + 215绘制。 Presumably the + 215 is just an offset for the initial location? 大概+ 215只是初始位置的偏移量?

Simple fix is to change your paintComponent() method to: 简单的解决方法是将您的paintComponent()方法更改为:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.RED);
    g2d.fillOval(stepX, stepY, 30, 30);
    startX = stepX;
    startY = stepY;
    if (stepX == endX && stepY == endY) {
        sliderTimer.stop();
    }
}

or just be consistent with the offset of all the coordinates. 或仅与所有坐标的偏移量一致。

Secondly, your slideTimer.stop() is highly unlikely to ever be called. 其次,您的slideTimer.stop()极不可能被调用。 You should set stepX = endX and stepY = endY if the following is true: end - step < 5 , ie 如果满足以下条件,则应设置stepX = endXstepY = endYend - step < 5 ,即

stepX = endX - startX < 5 ? endX : stepX + (endX - startX) / 5;
stepY = endY - startY < 5 ? endY : stepY + (endY - startY) / 5;

This may not bring it to the nicest possible finish, so feel free to experiment. 这可能无法达到最佳效果,所以请随时尝试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM