Java,鼠标拖动仿射变换
我正在研究JavaSwing 我需要一个应用程序,使用户可以缩放图形 绘图是在自定义的方法中完成的 比如说,绘图是一个方法调用 在应用程序中,缩放图形有两种方式(我称之为“模式”):Java,鼠标拖动仿射变换,java,swing,affinetransform,custom-painting,Java,Swing,Affinetransform,Custom Painting,我正在研究JavaSwing 我需要一个应用程序,使用户可以缩放图形 绘图是在自定义的方法中完成的 比如说,绘图是一个方法调用 在应用程序中,缩放图形有两种方式(我称之为“模式”): 调用图形的方法时,只需增加图形的宽度和高度。例如: graphics.drawRect(x, y, width + addX, height + addY); graphics.transform(at); graphics.drawRect(x, y, width, height); 其中,addX和addY
graphics.drawRect(x, y, width + addX, height + addY);
graphics.transform(at);
graphics.drawRect(x, y, width, height);
其中,addX
和addY
是用户鼠标拖动手势的偏移量graphics.drawRect(x, y, width + addX, height + addY);
graphics.transform(at);
graphics.drawRect(x, y, width, height);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
//The panel which handles drawing:
private static class PaintPanel extends JPanel {
private final double drawX, drawY;
private final AffineTransform at;
private double drawWidth, drawHeight;
public PaintPanel(final double drawX,
final double drawY,
final double drawWidth,
final double drawHeight) {
at = new AffineTransform();
this.drawX = drawX;
this.drawY = drawY;
this.drawWidth = drawWidth;
this.drawHeight = drawHeight;
}
public AffineTransform getAffineTransform() {
return at;
}
public double getDrawX() {
return drawX;
}
public double getDrawY() {
return drawY;
}
public double getDrawWidth() {
return drawWidth;
}
public double getDrawHeight() {
return drawHeight;
}
public double getTotalWidth() {
return getDrawWidth() * getAffineTransform().getScaleX();
}
public double getTotalHeight() {
return getDrawHeight() * getAffineTransform().getScaleY();
}
@Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
final Graphics2D g2d = (Graphics2D) g.create();
//Red rectangle for clarity.
g.setColor(Color.RED);
g.drawRect((int)getDrawX(), (int)getDrawY(), (int)getTotalWidth()-1, (int)getTotalHeight()-1);
//The drawing!
g2d.transform(getAffineTransform());
g2d.drawRect((int)getDrawX(), (int)getDrawY(), (int)getDrawWidth()-1, (int)getDrawHeight()-1);
g2d.drawOval((int)getDrawX(), (int)getDrawY(), (int)getDrawWidth()-1, (int)getDrawHeight()-1);
g2d.dispose();
}
//The scale(...) method scales the drawing.
//The scale(...) method needs changes.
public void scale(final boolean drawScale,
final double addX,
final double addY) {
if (drawScale) {
drawWidth += (addX / getAffineTransform().getScaleX());
drawHeight += (addY / getAffineTransform().getScaleY());
}
else {
final double tmpAddX = addX / getAffineTransform().getScaleX(),
tmpAddY = addY / getAffineTransform().getScaleY();
final double sx = (getDrawWidth() + tmpAddX) / getDrawWidth(),
sy = (getDrawHeight() + tmpAddY) / getDrawHeight();
getAffineTransform().scale(sx, sy);
final double tmpAddX2 = addX / getAffineTransform().getScaleX(),
tmpAddY2 = addY / getAffineTransform().getScaleY();
final double sx2 = (getDrawWidth() + tmpAddX2) / getDrawWidth(),
sy2 = (getDrawHeight() + tmpAddY2) / getDrawHeight();
getAffineTransform().translate(getDrawX() - getDrawX()*sx2,
getDrawY() - getDrawY()*sy2);
}
repaint();
}
}
private static boolean drawScale;
public static void main(final String[] args) {
final Dimension dim = new Dimension(300, 300);
final int drawOff = 100;
final PaintPanel paintPanel = new PaintPanel(drawOff/2, drawOff/2, dim.width - 2*drawOff, dim.height - 2*drawOff);
paintPanel.setPreferredSize(dim);
final MouseAdapter ma = new MouseAdapter() {
private Point dragLocation;
private boolean dragX, dragY;
//Tells if the width is dragged:
private boolean isDragX(final Point loc) {
return (loc.getX() > paintPanel.getTotalWidth()-10+paintPanel.getDrawX()
&& loc.getX() < paintPanel.getTotalWidth()+10+paintPanel.getDrawX()
&& loc.getY() < paintPanel.getTotalHeight()+paintPanel.getDrawY()+10
&& loc.getY() > paintPanel.getDrawY());
}
//Tells if the height is dragged:
private boolean isDragY(final Point loc) {
return (loc.getY() > paintPanel.getTotalHeight()-10+paintPanel.getDrawY()
&& loc.getY() < paintPanel.getTotalHeight()+10+paintPanel.getDrawY()
&& loc.getX() < paintPanel.getTotalWidth()+paintPanel.getDrawX()+10
&& loc.getX() > paintPanel.getDrawX());
}
//Only used to set the cursor:
@Override
public void mouseMoved(final MouseEvent mevt) {
final Point loc = mevt.getPoint();
if (isDragX(loc) && isDragY(loc))
paintPanel.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
else if (isDragX(loc))
paintPanel.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
else if (isDragY(loc))
paintPanel.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
else if (paintPanel.getCursor() != Cursor.getDefaultCursor())
paintPanel.setCursor(Cursor.getDefaultCursor());
}
//Determines (on mouse click) which sides are dragged:
@Override
public void mousePressed(final MouseEvent mevt) {
final Point loc = mevt.getPoint();
dragX = isDragX(loc);
dragY = isDragY(loc);
dragLocation = loc;
}
//Scales while dragging:
@Override
public void mouseDragged(final MouseEvent mevt) {
final Point loc = mevt.getPoint();
if (dragX && dragY)
paintPanel.scale(drawScale, loc.getX()-dragLocation.getX(), loc.getY()-dragLocation.getY());
else if (dragX)
paintPanel.scale(drawScale, loc.getX()-dragLocation.getX(), 0);
else if (dragY)
paintPanel.scale(drawScale, 0, loc.getY()-dragLocation.getY());
dragLocation = loc;
}
};
paintPanel.addMouseListener(ma);
paintPanel.addMouseMotionListener(ma);
final JButton drawScaleButton = new JButton("Draw scale"),
affineTransformScaleButton = new JButton("AffineTransform scale");
drawScaleButton.addActionListener(e -> {
drawScale = true;
drawScaleButton.setEnabled(false);
affineTransformScaleButton.setEnabled(true);
});
affineTransformScaleButton.addActionListener(e -> {
drawScale = false;
drawScaleButton.setEnabled(true);
affineTransformScaleButton.setEnabled(false);
});
drawScale = false;
drawScaleButton.setEnabled(true);
affineTransformScaleButton.setEnabled(false);
final JPanel buttons = new JPanel(/*FlowLayout*/);
buttons.add(affineTransformScaleButton);
buttons.add(drawScaleButton);
final JPanel contents = new JPanel(new BorderLayout());
contents.add(buttons, BorderLayout.PAGE_START);
contents.add(paintPanel, BorderLayout.CENTER);
final JFrame frame = new JFrame("Scaling shape test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Cursor;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.AffineTransform;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共班机{
//处理图形的面板:
私有静态类PaintPanel扩展了JPanel{
私人最终双抽绳,抽绳;
私人最终仿射翻译在;
私人双抽宽,抽高;
公共漆面(最终双抽,
最后的双抽,
最终双拉伸宽度,
最终双抽高度){
at=新仿射变换();
this.drawX=drawX;
this.drawY=drawY;
this.drawWidth=drawWidth;
this.drawHeight=drawHeight;
}
公共AffineTransform getAffineTransform(){
返回;
}
公共双getDrawX(){
回采;
}
公共双盲法(){
回程慢;
}
公共双getDrawWidth(){
返回宽度;
}
公共双高{
回程高度;
}
公共双getTotalWidth(){
返回getDrawWidth()*getAffineTransform().getScaleX();
}
公共双getTotalHeight(){
返回getDrawHeight()*getAffineTransform().getScaleY();
}
@凌驾
公共组件(最终图形g){
超级组件(g);
最终图形2d g2d=(图形2d)g.创建();
//为清晰起见,红色矩形。
g、 setColor(Color.RED);
g、 drawRect((int)getDrawX(),(int)getDrawY(),(int)getTotalWidth()-1,(int)getTotalHeight()-1);
//这幅画!
变换(getAffineTransform());
g2d.drawRect((int)getDrawX(),(int)getDrawY(),(int)getDrawWidth()-1,(int)getDrawHeight()-1);
g2d.drawOval((int)getDrawX(),(int)getDrawY(),(int)getDrawWidth()-1,(int)getDrawHeight()-1);
g2d.dispose();
}
//缩放(…)方法缩放图形。
//scale(…)方法需要更改。
公共空隙比例(最终布尔拉伸比例,
最终双地址,
最终双地址){
if(提取比例){
drawWidth+=(addX/getAffineTransform().getScaleX());
drawHeight+=(addY/getAffineTransform().getScaleY());
}
否则{
final double tmpAddX=addX/getAffineTransform().getScaleX(),
tmpAddY=addY/getAffineTransform().getScaleY();
最终双精度sx=(getDrawWidth()+tmpAddX)/getDrawWidth(),
sy=(getDrawHeight()+tmpAddY)/getDrawHeight();
getAffineTransform().scale(sx,sy);
final double tmpAddX2=addX/getAffineTransform().getScaleX(),
tmpAddY2=addY/getAffineTransform().getScaleY();
最终双精度sx2=(getDrawWidth()+tmpAddX2)/getDrawWidth(),
sy2=(getDrawHeight()+tmpAddY2)/getDrawHeight();
getAffineTransform().translate(getDrawX()-getDrawX()*sx2,
getDrawY()-getDrawY()*sy2);
}
重新油漆();
}
}
私有静态布尔尺度;
公共静态void main(最终字符串[]args){
最终尺寸尺寸=新尺寸(300300);
最终整数支取=100;
最终油漆面板油漆面板=新油漆面板(拉深/2,拉深/2,尺寸宽度-2*拉深,尺寸高度-2*拉深);
油漆面板。设置首选尺寸(尺寸);
最终MouseAdapter ma=新MouseAdapter(){
私用点定位;
私有布尔dragX,dragY;
//指示是否拖动宽度:
专用布尔isDragX(终点位置){
返回(loc.getX()>paintPanel.getTotalWidth()-10+paintPanel.getDrawX()
&&loc.getX()paintPanel.getDrawY());
}
//指示是否拖动高度:
专用布尔isDragY(终点位置){
return(loc.getY()>paintPanel.getTotalHeight()-10+paintPanel.getDrawY()
&&loc.getY()