如何实现可拖放移动、并改变大小(200分)

北极猩猩 2002-03-12 02:02:37
请问如何使用Java2D API实现可用鼠标拖动位置,并通过控制点改变大小的方框、菱形、椭圆形等。本人有一简单程序,单在运行时不太正常。请指教:

import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

public class ShapeTest
{
public static void main(String[] args)
{
JFrame frame = new ShapeTestFrame();
frame.show();
}
}

class ShapeTestFrame extends JFrame
implements ActionListener
{
private ShapePanel panel;
private JComboBox comboBox;

public ShapeTestFrame()
{
setTitle("ShapeTest");
setSize(300, 300);
addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
Container contentPane = getContentPane();

panel = new ShapePanel();
comboBox = new JComboBox();
comboBox.addItem(new ArcMaker());
comboBox.addItem(new LineMaker());
comboBox.addItem(new RectangleMaker());
comboBox.addItem(new RoundRectangleMaker());
comboBox.addItem(new EllipseMaker());
comboBox.addItem(new PolygonMaker());
comboBox.addItem(new QuadCurveMaker());
comboBox.addItem(new CubicCurveMaker());
comboBox.addActionListener(this);
contentPane.add(comboBox, "North");
contentPane.add(panel, "Center");
}

public void actionPerformed(ActionEvent event)
{
ShapeMaker shapeMaker = (ShapeMaker)comboBox.getSelectedItem();
panel.setShapeMaker(shapeMaker);
}
}

class ShapePanel extends JPanel
implements MouseListener, MouseMotionListener
{
private Point2D[] points;
private static Random generator = new Random();
private static int SIZE = 6;
private int current;
private ShapeMaker shapeMaker;

public ShapePanel()
{
addMouseListener(this);
addMouseMotionListener(this);
current = -1;
}

public void setShapeMaker(ShapeMaker aShapeMaker)
{
shapeMaker = aShapeMaker;
int n = shapeMaker.getPointCount();
points = new Point2D[n];

for(int i=0; i<n; i++){
double x = generator.nextDouble() * getWidth();
double y = generator.nextDouble() * getHeight();
points[i] = new Point2D.Double(x, y);
}
repaint();
}

public void paintComponent(Graphics g)
{
super.paintComponents(g);
if(points == null){
return;
}
Graphics2D g2 = (Graphics2D) g;
for(int i=0; i<points.length; i++){
double x = points[i].getX() - SIZE/2;
double y = points[i].getY() - SIZE/2;
g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE));
}
g2.draw(shapeMaker.makeShape(points));
}

public void mousePressed(MouseEvent event)
{
Point p = event.getPoint();
for(int i=0; i<points.length; i++){
double x = points[i].getX() - SIZE/2;
double y = points[i].getY() - SIZE/2;
Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE);
if(r.contains(p)){
current = i;
return;
}
}
}

public void mouseReleased(MouseEvent event)
{
current = -1;
}

public void mouseEntered(MouseEvent event)
{
}

public void mouseExited(MouseEvent event)
{
}

public void mouseClicked(MouseEvent event)
{
}

public void mouseMoved(MouseEvent event)
{
}

public void mouseDragged(MouseEvent event)
{
if(current == -1){
return;
}
points[current] = event.getPoint();
repaint();
}
}

abstract class ShapeMaker
{
private int pointCount;

public ShapeMaker(int aPointCount)
{
pointCount = aPointCount;
}

public int getPointCount()
{
return pointCount;
}

public abstract Shape makeShape(Point2D[] p);

public String toString()
{
return getClass().getName();
}
}

class LineMaker extends ShapeMaker
{
public LineMaker()
{
super(2);
}

public Shape makeShape(Point2D[] p)
{
return new Line2D.Double(p[0], p[1]);
}
}

class RectangleMaker extends ShapeMaker
{
public RectangleMaker()
{
super(2);
}

public Shape makeShape(Point2D[] p)
{
Rectangle2D s = new Rectangle2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}

class RoundRectangleMaker extends ShapeMaker
{
public RoundRectangleMaker()
{
super(2);
}

public Shape makeShape(Point2D[] p)
{
RoundRectangle2D s = new RoundRectangle2D.Double(0, 0, 0, 0, 20, 20);
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}

class EllipseMaker extends ShapeMaker
{
public EllipseMaker()
{
super(2);
}

public Shape makeShape(Point2D[] p)
{
Ellipse2D s = new Ellipse2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}

class ArcMaker extends ShapeMaker
{
public ArcMaker()
{
super(4);
}

public Shape makeShape(Point2D[] p)
{
double centerX = (p[0].getX() + p[1].getX()) / 2;
double centerY = (p[0].getY() + p[1].getY()) / 2;
double width = Math.abs(p[1].getX() - p[0].getX());
double height = Math.abs(p[1].getY() - p[0].getY());

double distortedStartAngle = Math.toDegrees(Math.atan2(-(p[2].getY() - centerY)
* width, (p[2].getX() - centerX) * height));
double distortedEndAngle = Math.toDegrees(Math.atan2(-(p[3].getY() - centerY)
* width, (p[3].getX() - centerX) * height));
double distortAngleDifference = distortedEndAngle - distortedStartAngle;

if(distortedStartAngle<0){
distortedStartAngle +=360;
}
if(distortAngleDifference<0){
distortAngleDifference +=360;
}

Arc2D s = new Arc2D.Double(0, 0, 0, 0, distortedStartAngle, distortAngleDifference, Arc2D.OPEN);
s.setFrameFromDiagonal(p[0], p[1]);

GeneralPath g = new GeneralPath();
g.append(s, false);
Rectangle2D r = new Rectangle2D.Double();
r.setFrameFromDiagonal(p[0], p[1]);
g.append(r, false);
Point2D center = new Point2D.Double(centerX, centerY);
g.append(new Line2D.Double(center, p[2]), false);
g.append(new Line2D.Double(center, p[3]), false);
return s;
}
}

class PolygonMaker extends ShapeMaker
{
public PolygonMaker()
{
super(6);
}

public Shape makeShape(Point2D[] p)
{
GeneralPath s = new GeneralPath();
s.moveTo((float)p[0].getX(), (float)p[0].getY());
for(int i=1; i<p.length; i++){
s.lineTo((float)p[i].getX(), (float)p[i].getY());
}
s.closePath();
return s;
}
}

class QuadCurveMaker extends ShapeMaker
{
public QuadCurveMaker()
{
super(3);
}

public Shape makeShape(Point2D[] p)
{
return new QuadCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY());
}
}

class CubicCurveMaker extends ShapeMaker
{
public CubicCurveMaker()
{
super(4);
}

public Shape makeShape(Point2D[] p)
{
return new CubicCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY(),
p[3].getX(), p[3].getY());
}
}

主要是在改变大小时不能清楚原来的内容。
...全文
66 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
北极猩猩 2002-03-13
  • 打赏
  • 举报
回复
多谢 feiyasu(飞海) ,你可真是救星。
能给我个email吗,以后可能还会有时请教
feiyasu 2002-03-13
  • 打赏
  • 举报
回复
feiyasu@sina.com.cn
feiyasu 2002-03-12
  • 打赏
  • 举报
回复
Graphics2D g2 = (Graphics2D) g;
for(int i=0; i<points.length; i++){
double x = points[i].getX() - SIZE/2;
double y = points[i].getY() - SIZE/2;
Color background = this.getBackground();
g2.setPaint(background);
g2.fillRect(0,0,this.getWidth(),this.getHeight());

g2.setPaint(Color.black);
g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE));
}
g2.draw(shapeMaker.makeShape(points));

我编译过了,可以了
feiyasu 2002-03-12
  • 打赏
  • 举报
回复
g2.setPaint(background);
g2.fillrect(0,0,width,height);

g2.setPaint(your color);
g2.fill(rect);
feiyasu 2002-03-12
  • 打赏
  • 举报
回复
先消除原来的图像就可以了
GJA106 2002-03-12
  • 打赏
  • 举报
回复
在拖动过程中程序中没有消掉原来的图形,从旧位置到新位置到都进行画图操作,而没有清除旧图形。
当鼠标在控制点的时候,判断当前位置与旧点是不是一致,如果不是重新画图。
北极猩猩 2002-03-12
  • 打赏
  • 举报
回复
简单的说,就是想word中添加的矩形一样用鼠标拖动改变位置和大小
feiyasu 2002-03-12
  • 打赏
  • 举报
回复
说得再明白一点
pukerno3 2002-03-12
  • 打赏
  • 举报
回复
晕~!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧