//已经做好了,实测貌似没问题哦~~
//DrawFrame.java (主程式,含程序入口);
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
public class DrawFrame extends JFrame{
private static final long serialVersionUID = -6016640305196475801L;
private MyCanvas canvas;
private JPanel menuPanel;
private JButton enableDrawButton,resetButton,colorSelectButton;
private JColorChooser colorChooser;
private JDialog colorChooserDialog;
//构造函数,对组件进行初始化
public DrawFrame(){
super("Draw shape demo");
this.getContentPane().setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas= new MyCanvas();
enableDrawButton = new JButton("new");
resetButton = new JButton("reset");
colorSelectButton = new JButton("color");
enableDrawButton.setBounds(10,4,68,20);
colorSelectButton.setBounds(88,4,68,20);
resetButton.setBounds(166,4,68,20);
menuPanel =new JPanel(null);
menuPanel.setPreferredSize(new Dimension(500,30));
menuPanel.add(enableDrawButton);
menuPanel.add(colorSelectButton);
menuPanel.add(resetButton);
colorChooser = new JColorChooser();
colorChooserDialog = new JDialog(this,"Color Selector");
colorChooserDialog.setSize(400,300);
colorChooserDialog.getContentPane().add(colorChooser);
initListeners();
this.add(canvas);//将画布放入中央位置
this.add(menuPanel,"South");//菜单放在底部
this.setSize(500,500);//窗口大小
this.setLocationRelativeTo(null);//初始位置在屏幕正中间
colorChooserDialog.setLocationRelativeTo(DrawFrame.this);//初始的颜色选择器在窗口正中央
this.setVisible(true);
}
//给组件加入事件侦听器
private void initListeners() {
ActionListener l = new ActionListener(){
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if(o.equals(enableDrawButton))
canvas.enableDrawSomething();
else if(o.equals(colorSelectButton)){
colorChooserDialog.setVisible(true);
}
else if(o.equals(resetButton))
canvas.reset();
}
};
enableDrawButton.addActionListener(l);
colorSelectButton.addActionListener(l);
resetButton.addActionListener(l);
colorChooser.getSelectionModel().addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent arg0) {
Color color = colorChooser.getColor();
canvas.fillShape(color);
}
});
}
public static void main(String[] args) {
new DrawFrame();
}
}
/*用户要求:
1.500*500窗口,鼠标进去背景是白色,出来背景是灰色.
2.下面3个按钮,new color reset
3.点new 然后再点空白地方,可以 创造黑色的圆,最多造三个,第四个点下去不会发生任何事情.
4.点color会出来一个颜色的菜单,这个拿什么做都无所谓,有效果就行,选颜色,然后点已经有点圆 ,圆会渐变成那个颜色.
5.reset 一切归零.
* */
/**
* 目前只能画正圆,在画好的圆上拖动鼠标能对它进行移动操作,在任意的圆上点击都将选中这个圆.
* 能对选中的圆进行填充颜色操作,目前没有实现去色操作(其实很简单),
* 鼠标移动到画布就会更改画布的背景色,进去是白色,出来是亮灰色(可自定 bgColor),
* 有图形数量限制,最多3个(可自定 total)
* 在LINUX下使用不会有兼容问题,但中文注释可能无法正常显示!(我可懒得去LINUX下写这个,呵呵)
* */
class MyCanvas extends Canvas implements MouseListener,MouseMotionListener{
private static final long serialVersionUID = 14567890L;
private Color lineColor,bgColor;//边框色,背景色
private int total = 3;//最多可画3个图形
private boolean enableDraw;//允许作图
private ArrayList<SC> list;//图形包装类容器
private SC selectedSC;//被点选中的图形
private int x,y,w,h;//作图用的坐标,屏幕大小
private BufferedImage finalBuffer,tmpBuffer;//缓冲区图像
//构造函数
MyCanvas(){
this.w=getToolkit().getScreenSize().width;
this.h=getToolkit().getScreenSize().height;
finalBuffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
tmpBuffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
list = new ArrayList<SC>();
lineColor = Color.black;
bgColor=Color.LIGHT_GRAY;
this.setBackground(bgColor);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
//重写此方法,使画布在被破坏后能显示缓冲的内容
public void paint(Graphics g){
drawToFace();
}
public void mouseClicked(MouseEvent e) {}
//按指定颜色填充被选中的图形
public void fillShape(Color color) {
for(SC sc:list){
if(sc.isSelected){
sc.color=color;
sc.isFilled=true;
break;
}
}
drawArray();
drawToFace();
}
//复位画布
public void reset() {
enableDraw=false;
list.clear();
bgColor=Color.LIGHT_GRAY;
this.setBackground(bgColor);
drawArray();
drawToFace();
}
//作图形关
public void enableDrawSomething() {
enableDraw=true;
}
//将全部内容画到画布上
private void drawBuff(int X,int Y){
createSC(X,Y);
drawArray();
drawToFace();
}
//创建SC对象实例,新建的SC对象默认是被选中的
private void createSC(int X,int Y) {
SC sc = new SC();
Point p = new Point(x,y);
Point2D p2 = new Point2D.Double(X,Y);
int dist = (int)p.distance(p2);
sc.x=x-dist;sc.y=y-dist;
sc.w=sc.h=dist*2;
sc.shape=new Ellipse2D.Double(sc.x,sc.y,sc.w,sc.h);
list.add(sc);
}
//临时作画(拖动时的作画过程)
private void drawTmp(int X,int Y){
//画图形到缓冲区
Graphics g = tmpBuffer.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,w,h);
// drawArray();
g.drawImage(finalBuffer,0,0,null);//先画上以前已画过的图形
g.setColor(lineColor);
g.drawOval(x,y,0,0);
Point p = new Point(x,y);
Point2D p2 = new Point2D.Double(X,Y);
int dist = (int)p.distance(p2);
g.drawOval(x-dist,y-dist,dist*2,dist*2);
g.dispose();
//画图形到画布
g = this.getGraphics();
g.drawImage(tmpBuffer,0,0,null);
g.dispose();
}
//将图形包装类容器中的内容画到缓冲区
private void drawArray() {
Collections.sort(list);//根据Z轴向值排序容器内容
Collections.reverse(list);//反向使Z轴值大的先画,这样就能使Z轴值小的更靠近用户
Graphics2D g = finalBuffer.createGraphics();//建立缓冲区图形
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//反锯齿设置
g.setColor(bgColor);
g.fillRect(0,0,w,h);//填充背景
for(SC s:list){//开始画图
g.setColor(lineColor);
g.draw(s.shape);//绘制图形外轮廓
if(s.isFilled){//填充图形
g.setColor(s.color);
g.fill(s.shape);
}
}
g.dispose();
}
//根据鼠标的出入来更改背景色(用户需要)
private void changeBgc(Color bgc){
this.bgColor=bgc;
drawArray();
drawToFace();
}
//将最终缓冲的内容印到画布
private void drawToFace(){
Graphics g = this.getGraphics();
g.drawImage(finalBuffer,0,0,null);
g.dispose();
}
//移动图形的操作方法
private void moveSc(int X,int Y){
selectedSC.x=X+selectedSC.sx;
selectedSC.y=Y+selectedSC.sy;
Ellipse2D e2d = (Ellipse2D)selectedSC.shape;
e2d.setFrame(selectedSC.x,selectedSC.y,selectedSC.w,selectedSC.h);
drawArray();
drawToFace();
}
public void mouseEntered(MouseEvent e) {changeBgc(Color.white);}
public void mouseExited(MouseEvent e) {changeBgc(Color.LIGHT_GRAY);}
//鼠标点击事件处理方法
public void mousePressed(MouseEvent e) {
if(!enableDraw)return;
this.x=e.getX();
this.y=e.getY();
selectedSC=null;
ArrayList<SC> tmp = new ArrayList<SC>();
for(SC s:list){
s.isSelected=false;
if(s.shape.contains(e.getPoint())){
tmp.add(s);
}
}
Collections.sort(tmp);
for(SC s:tmp){
selectedSC = s;
s.sx=s.x-e.getX();
s.sy=s.y-e.getY();
s.zIndex=-1;
s.isSelected=true;
break;
}
for(SC s:list){
s.zIndex++;
}
}
//鼠标释放事件处理方法
public void mouseReleased(MouseEvent e) {
if(!enableDraw)return;
if(selectedSC!=null){
drawArray();
drawToFace();
}
else if(list.size()<total)
drawBuff(e.getX(),e.getY());
}
//鼠标拖动事件处理方法
public void mouseDragged(MouseEvent arg0) {
if(!enableDraw){
JOptionPane.showMessageDialog(this,"请先点击 \"new\" 按钮开始作画!","警告",JOptionPane.WARNING_MESSAGE);
return;
}
if(selectedSC!=null){
moveSc(arg0.getX(),arg0.getY());
}
else if(list.size()<total)
drawTmp(arg0.getX(),arg0.getY());
else JOptionPane.showMessageDialog(this,"当前画布图像已达到了预设的数量,不能继续作画!","警告",JOptionPane.WARNING_MESSAGE);
}
public void mouseMoved(MouseEvent arg0) {}
}
//图形的包装类,保存图形的相关信息
class SC implements Comparable<SC>{
int x,y,w,h;//坐标和大小值
int sx,sy;//鼠标移动时产生的临时数据
Color color;//图形填充色
Shape shape;//图形
int zIndex;//Z轴的值,值越小越靠前
boolean isSelected=true;//选中状态指示值//默认是被选中的
boolean isFilled;//填充状态指示值
public int compareTo(SC sc) {//为排序比较用的方法
return zIndex-sc.zIndex;
}
}
温馨提示:内容为网友见解,仅供参考