以下示例绘制 2 个矩形。
在paintComponent()方法中,第一个矩形被正常绘制,第二个矩形被旋转。
旋转基于鼠标移动。如果鼠标点击矩形然后移动 以圆形方式,第二个矩形按预期旋转,但当鼠标旋转时,矩形的旋转并不总是与鼠标同步。
我怀疑这都与角度计算有关。关于如何使矩形的旋转与鼠标移动同步有什么建议吗?
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class SimpleTest extends JComponent
{
static int x = 200,y = 200 , width = 100 , height = 30;
static Vector objectsToDraw = new Vector();
static int mouseClickX, mouseClickY, mouseX, mouseY = 0;
static double angle;
public static void main(String[] args)
{
//Create Frame
JFrame window = new JFrame();
//Attach Mouse Listeners.
window.addMouseMotionListener(new MouseMotionListener()
{
@Override
public void mouseMoved(MouseEvent e) { }
@Override
public void mouseDragged(MouseEvent e)
{
// System.out.println("Dragged");
System.out.println("Dragged at X :" + e.getX() + " Y : " + e.getY());
calculateAngle(e.getX(), e.getY());
mouseX = e.getX();
mouseY = e.getY();
window.repaint();
}
});
window.addMouseListener(new MouseListener()
{
@Override
public void mouseClicked(MouseEvent arg0) { }
@Override
public void mouseEntered(MouseEvent arg0) { }
@Override
public void mouseExited(MouseEvent arg0) { }
@Override
public void mousePressed(MouseEvent e)
{
System.out.println("Pressed at X :" + e.getX() + " Y : " + e.getY());
mouseClickX = e.getX();
mouseClickY = e.getY();
}
@Override
public void mouseReleased(MouseEvent arg0)
{
System.out.println("Released");
mouseClickX = 0;
mouseClickY = 0;
window.repaint();
}
});
//show Window
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 800, 800);
window.getContentPane().add(new SimpleTest());
window.setVisible(true);
}
public static void calculateAngle (int x, int y)
{
int deltaX = x - 250;//Rectangle Center X
int deltaY = y - 200;//Rectangle Center Y
angle = Math.toDegrees(Math.atan2(deltaY, deltaX));
System.out.println("Angle = " + angle);
}
@Override //Works
public void paintComponent(Graphics g)
{
System.out.println("paintComponent() - using angle : " + angle);
Graphics2D g2d = (Graphics2D)g;
AffineTransform old = g2d.getTransform();
g.drawRect(x, y, width, height);
g2d.rotate(Math.toRadians(angle), 250, 215);
Rectangle rect2 = new Rectangle(200, 200, 100, 30);
g.drawRect(x, y, width, height);
g2d.setTransform(old);
}
}
最佳答案
首先,您将 MouseListener 添加到了错误组件。不要将其添加到窗口,而是添加到执行绘图的 JComponent。否则,无论菜单栏有多大,或者任何其他改变绘图组件(使用鼠标位置的组件)相对于 JFrame(您的当前获取鼠标位置的组件)。
例如,
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleTest2 extends JPanel {
// avoiding "magic" numbers
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
public static final int RECT_X = 200;
public static final int RECT_Y = RECT_X;
public static final int RECT_WIDTH = 100;
public static final int RECT_HEIGHT = 30;
private double angle;
private static void createAndShowGui() {
SimpleTest2 mainPanel = new SimpleTest2();
JFrame frame = new JFrame("Simple Test 2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack(); // let the GUI size itself
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public SimpleTest2() {
// using an adapter is a nice clean way of avoiding empty method bodies
MouseAdapter myMouse = new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
calculateAngle(e.getX(), e.getY());
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
calculateAngle(e.getX(), e.getY());
repaint();
}
};
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
public void calculateAngle(int x, int y) {
// get rid of "magic" numbers
int deltaX = x - (RECT_X + RECT_WIDTH / 2);// Rectangle Center X
int deltaY = y - (RECT_Y + RECT_HEIGHT / 2);// Rectangle Center Y
angle = Math.toDegrees(Math.atan2(deltaY, deltaX));
}
@Override
public Dimension getPreferredSize() {
// better way to size the drawing component
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // ***don't forget this guy***
Graphics2D g2d = (Graphics2D) g;
// for smoother rendering
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform old = g2d.getTransform();
g.drawRect(RECT_X, RECT_Y, RECT_WIDTH, RECT_HEIGHT);
g2d.rotate(Math.toRadians(angle), 250, 215);
// Rectangle rect2 = new Rectangle(200, 200, 100, 30);
g.drawRect(RECT_X, RECT_Y, RECT_WIDTH, RECT_HEIGHT);
g2d.setTransform(old);
}
}
关于java - 用鼠标旋转矩形不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59007807/