Java Graphics2D绘图寻求 -组合/取消组合- 思路!

CNASP 2007-03-14 05:44:52
现在java做一个简单绘图软件,想实现 对多个Graphics2D对象的组合和取消组合功能,类似于在Word中绘图的组合和取消组合,没有思路如何做,有高手给个思路或者例程,高分相送。
具体可以描述为 在绘图程序同时选中 几个不同的 几何图像对象 要求实现 对他们进行组合和取消组合的操作。目的是对一个组合后的图形对象进行拖拽等操作。

比较急,高手出手相助了。。。
...全文
753 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
andnnl 2007-03-27
  • 打赏
  • 举报
回复
多看点文章 就行了。哈哈。
CNASP 2007-03-18
  • 打赏
  • 举报
回复
首先谢谢各位多支持,尤其是jk88811很热心,本人水平实在有限,所以才会产生很多问题麻烦各位。一点点分,大家笑纳了。
关于图形组合和取消组合,由于时间有期限而且很近,我就用了用Arraylist 存储组合,用Hashset存储各类图形, 大概就是这样。至于应用模式以后再仔细考虑。
CNASP 2007-03-15
  • 打赏
  • 举报
回复
很感谢jk88811的思路和代码,效率很高啊, 虽然问的是图形组合,可也学到了很多别的东西。有了方案我会贴出来。周一前再具体感谢大家。。。
jk88811 2007-03-15
  • 打赏
  • 举报
回复
/*
PaintPanel.java
*/
package com.jkzqw.painter;

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

public class PaintPanel extends JPanel {
private static final long serialVersionUID = 1L;

private ArrayList<Shape> allShapes;

private Shape drawingShape = null;

private Point2D startPoint = null;

public PaintPanel() {
allShapes = new ArrayList<Shape>();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

for (Shape shape : allShapes)
g2.draw(shape);
if (drawingShape != null)
g2.draw(drawingShape);
}

public void addShape(Shape shape) {
allShapes.add(shape);
this.repaint();
}

public void setDrawingShape(Shape shape) {
this.drawingShape = shape;
this.repaint();
}

public void removeDrawingShape() {
this.drawingShape = null;
this.repaint();
}

public void setStartPoint(Point2D startPoint) {
this.startPoint = startPoint;
}

public Point2D getStartPoint() {
return startPoint;
}
}

/*
ShapeUtil.java
*/
package com.jkzqw.painter;

import java.awt.geom.*;

public class ShapeUtil {
/**
* 由对角线上的两个点计算出这个矩形
* @param p1 顶点1
* @param p2 顶点2
* @return Rectangle2D
*/
public static Rectangle2D getRectangle2D(Point2D p1, Point2D p2) {
double x1 = p1.getX();
double y1 = p1.getY();
double x2 = p2.getX();
double y2 = p2.getY();

double upX = Math.min(x1, x2);
double upY = Math.min(y1, y2);
double width = Math.abs(x1 - x2);
double height = Math.abs(y1 - y2);
return new Rectangle2D.Double(upX, upY, width, height);
}
}
jk88811 2007-03-15
  • 打赏
  • 举报
回复
/*
DrawRectangleMouseHandler.java
*/
package com.jkzqw.painter;

import java.awt.event.*;
import java.awt.geom.*;

public class DrawRectangleMouseHandler extends MouseAdapter {
private PaintPanel paintPanel;

private Point2D start;
private Point2D end;

public DrawRectangleMouseHandler(PaintPanel paintPanel) {
this.paintPanel = paintPanel;
}

public void mousePressed(MouseEvent event) {
start = event.getPoint();
paintPanel.setStartPoint(start);
}

public void mouseReleased(MouseEvent event) {
end = event.getPoint();
Rectangle2D rect = ShapeUtil.getRectangle2D(start, end);
paintPanel.addShape(rect);

paintPanel.removeDrawingShape();
}
}

/*
DrawRectangleMouseMotionHandler.java
*/
package com.jkzqw.painter;

import java.awt.event.*;
import java.awt.geom.*;

public class DrawRectangleMouseMotionHandler extends MouseMotionAdapter {
private PaintPanel paintPanel;

public DrawRectangleMouseMotionHandler(PaintPanel paintPanel) {
this.paintPanel = paintPanel;
}

public void mouseDragged(MouseEvent event) {
Point2D start = paintPanel.getStartPoint();
Point2D end = event.getPoint();
Rectangle2D rect = ShapeUtil.getRectangle2D(start, end);
paintPanel.setDrawingShape(rect);
}
}

/*
ExitAction.java
*/
package com.jkzqw.painter;

import java.awt.event.*;

import javax.swing.*;

public class ExitAction extends AbstractAction {
private static final long serialVersionUID = 1L;

private JFrame parent;

public ExitAction(JFrame parent) {
this.parent = parent;
this.putValue(Action.NAME, "Exit");
this.putValue(Action.SHORT_DESCRIPTION, "Exit the Painter");
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl X"));
}

public void actionPerformed(ActionEvent e) {
doExit();
}

public void doExit() {
int result = JOptionPane.showConfirmDialog(parent,
"Exit the Painting application?", "Exit",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION)
System.exit(0);
}

}

/*
MainWindow.java
*/
package com.jkzqw.painter;

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

public class MainWindow extends JFrame {
private static final long serialVersionUID = 1L;

private PaintPanel paintPanel = new PaintPanel();

public MainWindow() {
super("Painting");
this.setSize(600, 500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

createMenuBar();
createToolBar();

this.add(paintPanel, BorderLayout.CENTER);

final ExitAction exitAction = new ExitAction(this);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
exitAction.doExit();
}
});
}

private void createToolBar() {
JToolBar toolBar = new JToolBar("ToolBar");
toolBar.setFloatable(false);

toolBar.add(new DefaultAction("Normal", "Normal State", "ctrl N",
paintPanel, null, null));

DrawLineMouseHandler lineHandler = new DrawLineMouseHandler(paintPanel);
DrawLineMouseMotionHandler lineMotionHandler = new DrawLineMouseMotionHandler(
paintPanel);
toolBar.add(new DefaultAction("Line", "Draw Line", "ctrl L",
paintPanel, lineHandler, lineMotionHandler));

DrawRectangleMouseHandler rectHandler = new DrawRectangleMouseHandler(
paintPanel);
DrawRectangleMouseMotionHandler rectMotionHandler = new DrawRectangleMouseMotionHandler(
paintPanel);
toolBar.add(new DefaultAction("Rectangle", "Draw Rectangle", "ctrl R",
paintPanel, rectHandler, rectMotionHandler));

this.add(toolBar, BorderLayout.NORTH);
}

private void createMenuBar() {
JMenu editMenu = new JMenu("Edit");
editMenu.setMnemonic('E');
editMenu.add(new JMenuItem("Undo"));

JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic('H');
helpMenu.add(new ExitAction(this));

JMenuBar menuBar = new JMenuBar();
menuBar.add(editMenu);
menuBar.add(helpMenu);
this.setJMenuBar(menuBar);
}

public static void main(String[] args) {
JFrame frame = new MainWindow();
frame.setVisible(true);
}
}
jk88811 2007-03-15
  • 打赏
  • 举报
回复
今天想了一天,就写了下面这些代码,可是没有实现组合图形的功能,我尝试了好几种方法,
都不能很好的解决,还是请高手来吧。我想这种绘图程序也是有点难度的,至少只使用Java
Graphics2D库很难,有太多的地方需要考虑了。。。

不知道下面的代码对楼主有没有帮助,我随便写的:
/*
DefaultAction.java
*/
package com.jkzqw.painter;

import java.awt.Cursor;
import java.awt.event.*;

import javax.swing.*;

public class DefaultAction extends AbstractAction {
private static final long serialVersionUID = 1L;

private PaintPanel paintPanel;

private String name;

private MouseListener mouseListener;

private MouseMotionListener mouseMotionListener;

public DefaultAction(String name, String description, String key,
PaintPanel paintPanel, MouseListener ml, MouseMotionListener mml) {
this.paintPanel = paintPanel;
this.name = name;
this.mouseListener = ml;
this.mouseMotionListener = mml;
this.putValue(Action.NAME, name);
this.putValue(Action.SHORT_DESCRIPTION, description);
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(key));
}

public void actionPerformed(ActionEvent e) {
removeAllMouseListener();
setCursor();
addDrawShapeMouseListener();
}

private void setCursor() {
if (name.equals("Normal")) {
paintPanel.setCursor(Cursor.getDefaultCursor());
} else {
paintPanel.setCursor(Cursor
.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
}

protected void removeAllMouseListener() {
MouseListener[] mls = paintPanel.getMouseListeners();
for (MouseListener ml : mls)
paintPanel.removeMouseListener(ml);
MouseMotionListener[] mmls = paintPanel.getMouseMotionListeners();
for (MouseMotionListener mml : mmls)
paintPanel.removeMouseMotionListener(mml);
}

protected void addDrawShapeMouseListener() {
paintPanel.addMouseListener(mouseListener);
paintPanel.addMouseMotionListener(mouseMotionListener);
}
}

/*
DrawLineMouseHandler.java
*/
package com.jkzqw.painter;

import java.awt.event.*;
import java.awt.geom.*;

public class DrawLineMouseHandler extends MouseAdapter {
private Point2D start;

private Point2D end;

private PaintPanel paintPanel;

public DrawLineMouseHandler(PaintPanel paintPanel) {
this.paintPanel = paintPanel;
}

public void mousePressed(MouseEvent event) {
start = event.getPoint();
paintPanel.setStartPoint(start);
}

public void mouseReleased(MouseEvent event) {
end = event.getPoint();
Line2D line = new Line2D.Double(start, end);
paintPanel.addShape(line);
paintPanel.removeDrawingShape();
}
}

/*
DrawLineMouseMotionHandler.java
*/
package com.jkzqw.painter;

import java.awt.event.*;
import java.awt.geom.*;

public class DrawLineMouseMotionHandler extends MouseMotionAdapter {
private PaintPanel paintPanel;

public DrawLineMouseMotionHandler(PaintPanel paintPanel) {
this.paintPanel = paintPanel;
}

public void mouseDragged(MouseEvent e) {
Point2D start = paintPanel.getStartPoint();
Point2D end = e.getPoint();
paintPanel.setDrawingShape(new Line2D.Double(start, end));
}
}
CNASP 2007-03-15
  • 打赏
  • 举报
回复
不好意思其实想了好久...
开始想用HashSet来存取和组合对象,后来感觉不通用,想用你建议的composite模式 需要改动其他代码,其实还是对composite模式不熟悉,看着文档挺明白,做起来下手难,继续学习. 有高手能给个详细点的伪代码我想对以后学习模式都有帮助.
大家多顶了,分很多的,周一给.
jk88811 2007-03-15
  • 打赏
  • 举报
回复
楼主这么早,想到好办法了没?

继续探讨吧。。。
nemo520hellen 2007-03-15
  • 打赏
  • 举报
回复
Rectangle2D r : squares怎么理解呢??jk88811贴的代码,我已经看过了!我基础差,好多没理解!郁闷!
CNASP 2007-03-15
  • 打赏
  • 举报
回复
good idea! 应用composite模式,抽象 图形 为component, 图形为composite, 各种分类图形为leaf. 可以对各种图形组合/取消组合。 期待一下具体代码. 继续学习中.
CNASP 2007-03-15
  • 打赏
  • 举报
回复
To andnnl():
实在是强, jk88811 说的问题也很现实,需要费点功夫去应用到我的问题中,我还没来及看代码,我理解一下,待会再过来。

To nemo520hellen() :
图像选中和移动可以参见jk88811贴的代码,实现方法虽不同,不过原理大同小异。
nemo520hellen 2007-03-15
  • 打赏
  • 举报
回复
我也是搞紧画图问题!楼主有没办法帮我解决花出图象的选中和移动呢??大家帮下忙吧!明天要交功课了!
jk88811 2007-03-15
  • 打赏
  • 举报
回复
楼上的代码很好的解释了如何使用Composite模式

但现在的问题是如何在Java Swing的界面程序中,应用这个模式,使用鼠标监听来进行图形的拖动,
还有图形组合的拖动。

不知楼主进展如何,这是项目还是作业题?
andnnl 2007-03-15
  • 打赏
  • 举报
回复
package com.andnnl.graphics;

public interface MyGraphics {
public void draw();
}


/*
* 创建日期 2007-2-2
*
* 更改所生成文件模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
package com.andnnl.graphics;

import java.awt.Graphics;


/**
* @author Administrator
*
* 更改所生成类型注释的模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public class Line implements MyGraphics {


public void draw() {
System.out.println("line");

}


}




/*
* 创建日期 2007-2-2
*
* 更改所生成文件模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
package com.andnnl.graphics;

import java.util.ArrayList;
import java.util.Iterator;


public class MultGrihics implements MyGraphics{

private ArrayList<MyGraphics> list=new ArrayList<MyGraphics>();

public void draw() {
for(Iterator it=list.iterator();it.hasNext();){
MyGraphics mg=(MyGraphics) it.next();
mg.draw();
}
}

public void addGraphics(MyGraphics mg){
list.add(mg);
}

public void removeGraphics(MyGraphics mg) {
list.remove(mg);
}
}




/*
* 创建日期 2007-2-2
*
* 更改所生成文件模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
package com.andnnl.graphics;

/**
* @author Administrator
*
* 更改所生成类型注释的模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public class Rect implements MyGraphics {

/* (非 Javadoc)
* @see com.andnnl.graphics.MyGraphics#draw()
*/
public void draw() {
System.out.println("rect");
}


}




/*
* 创建日期 2007-2-2
*
* 更改所生成文件模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
package com.andnnl.graphics;

/**
* @author Administrator
*
* 更改所生成类型注释的模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public class Test {

public static void main(String[] args) {
MyGraphics mg1=new Line();
MyGraphics mg2=new Rect();

MultGrihics mgs=new MultGrihics();
mgs.addGraphics(mg1);
mgs.addGraphics(mg2);
mgs.draw();
}
}

jk88811 2007-03-14
  • 打赏
  • 举报
回复
/**
@version 1.31 2004-05-04
@author Cay Horstmann
*/

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

public class MouseTest
{
public static void main(String[] args)
{
MouseFrame frame = new MouseFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

/**
A frame containing a panel for testing mouse operations
*/
class MouseFrame extends JFrame
{
public MouseFrame()
{
setTitle("MouseTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

// add panel to frame

MousePanel panel = new MousePanel();
add(panel);
}

public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
}

/**
A panel with mouse operations for adding and removing squares.
*/
class MousePanel extends JPanel
{
public MousePanel()
{
squares = new ArrayList<Rectangle2D>();
current = null;

addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

// draw all squares
for (Rectangle2D r : squares)
g2.draw(r);
}

/**
Finds the first square containing a point.
@param p a point
@return the first square that contains p
*/
public Rectangle2D find(Point2D p)
{
for (Rectangle2D r : squares)
{
if (r.contains(p)) return r;
}
return null;
}

/**
Adds a square to the collection.
@param p the center of the square
*/
public void add(Point2D p)
{
double x = p.getX();
double y = p.getY();

current = new Rectangle2D.Double(
x - SIDELENGTH / 2,
y - SIDELENGTH / 2,
SIDELENGTH,
SIDELENGTH);
squares.add(current);
repaint();
}

/**
Removes a square from the collection.
@param s the square to remove
*/
public void remove(Rectangle2D s)
{
if (s == null) return;
if (s == current) current = null;
squares.remove(s);
repaint();
}


private static final int SIDELENGTH = 10;
private ArrayList<Rectangle2D> squares;
private Rectangle2D current;
// the square containing the mouse cursor

private class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
// add a new square if the cursor isn't inside a square
current = find(event.getPoint());
if (current == null)
add(event.getPoint());
}

public void mouseClicked(MouseEvent event)
{
// remove the current square if double clicked
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2)
remove(current);
}
}

private class MouseMotionHandler
implements MouseMotionListener
{
public void mouseMoved(MouseEvent event)
{
// set the mouse cursor to cross hairs if it is inside
// a rectangle

if (find(event.getPoint()) == null)
setCursor(Cursor.getDefaultCursor());
else
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}

public void mouseDragged(MouseEvent event)
{
if (current != null)
{
int x = event.getX();
int y = event.getY();

// drag the current rectangle to center it at (x, y)
current.setFrame(
x - SIDELENGTH / 2,
y - SIDELENGTH / 2,
SIDELENGTH,
SIDELENGTH);
repaint();
}
}
}
}

这是Core Java 卷I 第8章 第4节关于鼠标事件的例子, 虽然没有关于如何组合/取消, 但演示了如何对绘制矩形, 删除矩形和拖动矩形. 不知是否对你有所帮助...

我想了一下, 这里应该可以应用Composite模式. 让好几个图形的组合作为一个整体, 也实现Shape接口, 而这个Composite组合本身包含一个ArrayList<Shape>, 里面存放的是所有其它的图形. 实现了Shape你就可以对它进行绘制, 判断一个点是否在这个图形组合间等.

现在我们宿舍要停电了, 晚上给你好好想想, 明天再来看看有没有好的解决方案...
CNASP 2007-03-14
  • 打赏
  • 举报
回复
example: 三角形A 和 圆形B 为分组G_1 / 四边形C 和 圆形D 为分组G_2
如何才能做到对于任意分组的图形的识别(点击分组中任意图形,即可对整组进行操作),如果是任意分组呢?
CNASP 2007-03-14
  • 打赏
  • 举报
回复
To moon_cool(月影剑):
Demo的那个例程我看了,是关于panel组合,我想要的是对图形 取消分组的组合和取消组合功能。多谢你的回复,其实想要更详细点的了。。。

To redduke1202:
如果用HashSet来存取 已经被选择的Graphics2D图形对象,如何才可以把分组/取消分组操作实现,或者说用ArrayList怎样具体应用到分组/取消分组.还疑惑,多谢解答。
CNASP 2007-03-14
  • 打赏
  • 举报
回复
多谢,我研究一下,有更详细的继续感谢.
Moon 2007-03-14
  • 打赏
  • 举报
回复
组合和取消组合的操作
在JDK自带的demo里面有个例子的
拖动的话可以参考楼上的
要记录鼠标点
使用MouseEvent
getX()和getY()方法可以取得当前鼠标点的位置
「已注销」 2007-03-14
  • 打赏
  • 举报
回复
public class ItemGroup
{
ArrayList<Item> arrayList=new ArrayList<Item>();
add(Item item)
remove(Item item)
}
class Item
{
ItemGroup group;

move()
{
if(group==null)
//只移动自身
else
//group内的所有Item都移动
}
}

62,614

社区成员

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

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