如何解决如何在Java中的缩放面板中操作形状?
我在互联网上找到了一些代码,可以使用Java控制可滚动面板的缩放和平移,但是我希望能够处理此区域内的形状,并且无法将x和y坐标转换回原始尺寸(未缩放)..
我想对这些形状做一些事情,但是首先,当鼠标在两个实体矩形中移动时,如何将其涂成红色?
这是我到目前为止的代码:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class CanvasPane extends JPanel {
private static Canvas canvas;
public CanvasPane(boolean isDoubleBuffered) {
super(isDoubleBuffered);
setLayout(new BorderLayout());
canvas = new Canvas(1.0);
JScrollPane pane = new JScrollPane(canvas);
pane.getViewport().setBackground(Color.DARK_GRAY);
add(pane,BorderLayout.CENTER);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Test Graphics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new CanvasPane(true),BorderLayout.CENTER);
frame.pack();
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//Initial scrolling of the canvas to its center
Rectangle canvasRectangle = canvas.getBounds();
Rectangle visibleRectangle = canvas.getVisibleRect();
double tx = (canvasRectangle.getWidth() - visibleRectangle.getWidth())/2;
double ty = (canvasRectangle.getHeight() - visibleRectangle.getHeight())/2;
visibleRectangle.setBounds((int)tx,(int)ty,visibleRectangle.width,visibleRectangle.height);
canvas.scrollRectToVisible(visibleRectangle);
}
}
class Canvas extends JComponent implements MouseWheelListener,MouseMotionListener,MouseListener {
private static final long serialVersionUID = 1L;
private double zoom = 1.0;
public static final double SCALE_STEP = 0.1d;
private Dimension initialSize;
private Point origin;
private double previousZoom = zoom;
private double scrollX = 0d;
private double scrollY = 0d;
private Rectangle2D workspace = new Rectangle2D.Double(0,1024,768);
private Rectangle entity1 = new Rectangle(10,10,100,100);
private Rectangle entity2 = new Rectangle(300,300,100);
public Canvas(double zoom) {
this.zoom = zoom;
addMouseWheelListener(this);
addMouseMotionListener(this);
addMouseListener(this);
setAutoscrolls(true);
setPreferredSize(new Dimension((int)workspace.getWidth(),(int)workspace.getHeight()));
}
@Override public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//Zoom graphics
g2d.scale(zoom,zoom);
//translate graphics to be always in center of the canvas
Rectangle size = getBounds();
double tx = ((size.getWidth() - workspace.getWidth() * zoom) / 2) / zoom;
double ty = ((size.getHeight() - workspace.getHeight() * zoom) / 2) / zoom;
g2d.translate(tx,ty);
//Draw
g2d.setColor(Color.LIGHT_GRAY);
g2d.fill(workspace);
g2d.setColor(Color.DARK_GRAY);
g2d.setStroke(new BasicStroke(5.0f));
g2d.draw(workspace);
g2d.draw(entity1);
g2d.draw(entity2);
}
@Override public void setSize(Dimension size) {
super.setSize(size);
if (initialSize == null) {
this.initialSize = size;
}
}
@Override public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
if (initialSize == null) {
this.initialSize = preferredSize;
}
}
public void mouseWheelMoved(MouseWheelEvent e) {
double zoomFactor = -SCALE_STEP * e.getPreciseWheelRotation() * zoom;
zoom = Math.abs(zoom + zoomFactor);
//Here we calculate new size of canvas relative to zoom.
Dimension d = new Dimension(
(int)(initialSize.width * zoom),(int)(initialSize.height * zoom));
setPreferredSize(d);
setSize(d);
validate();
followMouseOrCenter(e.getPoint());
previousZoom = zoom;
}
public void followMouseOrCenter(Point2D point) {
Rectangle size = getBounds();
Rectangle visibleRect = getVisibleRect();
scrollX = size.getCenterX();
scrollY = size.getCenterY();
if (point != null) {
scrollX = point.getX() / previousZoom * zoom - (point.getX() - visibleRect.getX());
scrollY = point.getY() / previousZoom * zoom - (point.getY() - visibleRect.getY());
}
visibleRect.setRect(scrollX,scrollY,visibleRect.getWidth(),visibleRect.getHeight());
scrollRectToVisible(visibleRect);
}
public void mouseDragged(MouseEvent e) {
if (origin != null) {
int deltaX = origin.x - e.getX();
int deltaY = origin.y - e.getY();
Rectangle view = getVisibleRect();
view.x += deltaX;
view.y += deltaY;
scrollRectToVisible(view);
}
}
public void mousePressed(MouseEvent e) {
origin = new Point(e.getPoint());
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
我尝试使用以下代码进行计算,但这不太正确
public void mouseMoved(MouseEvent e) {
double x = e.getX() / zoom;
double y = e.getY() / zoom;
double x2 = getWidth() - workspace.getWidth() * zoom;
double y2 = getHeight() - workspace.getHeight() * zoom;
if(x2 > 0) x -= x2;
if(y2 > 0) y -= y2;
Point p = new Point((int)x,(int)y);
if(entity1.contains(p)) {
intersects = true;
}
else {
intersects = false;
}
repaint();
}
解决方法
这似乎效果更好,但是我不确定它是否是最干净的解决方案...
public void mouseMoved(MouseEvent e) {
double x = e.getX() / zoom;
double y = e.getY() / zoom;
// double x2 = getWidth() - workspace.getWidth() * zoom;
// double y2 = getHeight() - workspace.getHeight() * zoom;
double x2 = ((getWidth() - workspace.getWidth() * zoom) / 2) / zoom;
double y2 = ((getHeight() - workspace.getHeight() * zoom) / 2) / zoom;
if(x2 > 0) x -= x2;
if(y2 > 0) y -= y2;
Point p = new Point((int)x,(int)y);
if(entity1.contains(p)) {
intersects = true;
}
else {
intersects = false;
}
repaint();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。