用java 实现画圆、矩形和直线

| 0 Comments

用JAVA实现画圆、矩阵和直线的源程序:

//java 画圆  矩形  直线
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.Border;

public class DrawShapes extends JFrame{
private static final long serialVersionUID = 3685715844170953607L;
//作图面板
private CVS cvs;
//作图方式选择按钮
private JToggleButton cycle,line,rect;
private JLabel red,blue,green;
private ButtonGroup bgroup;
//按钮布局面板
private JPanel menuPanel;
//复位按钮
private JButton clean;

public DrawShapes(){
   super("Java  实训");
//   this.setResizable(false);
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   this.setSize(640,480);
   this.setLocationRelativeTo(null);
   this.getContentPane().add(cvs=new CVS());
   this.initComponents();
}
//初始化组件
private void initComponents() {
   this.menuPanel = new JPanel(null);
   this.menuPanel.setPreferredSize(new Dimension(400,28));
   this.menuPanel.setBorder(BorderFactory.createLineBorder(Color.gray));
   this.getContentPane().add(this.menuPanel,"South");
   this.bgroup = new ButtonGroup();
   this.cycle = new JToggleButton("圆形");
   this.cycle.setBounds(20,4,68,20);
   this.line = new JToggleButton("直线");
   this.line.setBounds(100,4,68,20);
   this.rect=new JToggleButton("矩形");
   this.rect.setBounds(180,4,68,20);
   red = new JLabel();
   red.setOpaque(true);
   red.setBackground(Color.red);
   red.setBounds(258,4,20,20);
   blue=new JLabel();
   blue.setOpaque(true);
   blue.setBackground(Color.blue);
   blue.setBounds(282,4,20,20);
   green=new JLabel();
   green.setBackground(Color.green);
   green.setOpaque(true);
   green.setBounds(306,4,20,20);
   this.menuPanel.add(red);
   this.menuPanel.add(blue);
   this.menuPanel.add(green);
   this.menuPanel.add(cycle);
   this.menuPanel.add(line);
   this.menuPanel.add(rect);
   this.bgroup.add(cycle);
   this.bgroup.add(line);
   this.bgroup.add(rect);
   this.clean = new JButton("清除");
   this.clean.setBounds(338,4,68,20);
   this.menuPanel.add(clean);
   //按钮动作侦听器实例
   ActionListener al = new ActionListener(){
    public void actionPerformed(ActionEvent e) {
     Object src = e.getSource();
     if(src.equals(cycle))
      cvs.setSX(S.CYCLE);//画圆
     else if(src.equals(line))
      cvs.setSX(S.LINE);//画直线
     else if(src.equals(rect))
      cvs.setSX(S.RECTANGLE);//画矩形
     else if(src.equals(clean))
      cvs.reset();//复位
    }
   };
   //给按钮注册侦听器
   this.cycle.addActionListener(al);
   this.line.addActionListener(al);
   this.rect.addActionListener(al);
   this.clean.addActionListener(al);
   MouseListener ml = new MouseAdapter(){
       public void mousePressed(MouseEvent e){
           Object s = e.getSource();
           Border b = BorderFactory.createLoweredBevelBorder();
           if(s.equals(red)){
               cvs.setFC(Color.red);
               red.setBorder(b);
               blue.setBorder(null);
               green.setBorder(null);
           }
           else if(s.equals(blue)){
               cvs.setFC(Color.blue);
               blue.setBorder(b);
               red.setBorder(null);
               green.setBorder(null);
           }
           else if(s.equals(green)){
               cvs.setFC(Color.green);
               green.setBorder(b);
               blue.setBorder(null);
               red.setBorder(null);
           }
       }
   };
   blue.addMouseListener(ml);
   red.addMouseListener(ml);
   green.addMouseListener(ml);
}
//程序入口
public static void main(String[] aregs) throws Exception{
   //调用系统视觉设置
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
   SwingUtilities.invokeLater(new Runnable(){
    public void run(){
     new DrawShapes().setVisible(true);
    }
   });
}
}

//主作图面板类,可接收一般鼠标事件和鼠标拖动事件
class CVS extends Canvas implements MouseListener,MouseMotionListener{
private static final long serialVersionUID = 5585026114112579483L;

//指定图形的第一点,比如矩形的角点,圆形的圆心,直线的第一点
private int x,y;
//作图大小
private int w,h;
//作图类型控制
private S sx = S.NULL;
//双缓冲,背景缓冲区和临时缓冲区
private BufferedImage background,buff;
//图像更新标记
private boolean hasChanged;
//背景色,临时作图色,前景色
private Color bgc = Color.white;
private Color tmpc = Color.gray;
private Color fgc = Color.blue;

public CVS(){
   this.addMouseListener(this);
   this.addMouseMotionListener(this);
}
//作图控制方式设置
public void setSX(S s){
   sx = s;
}
//控制作图颜色:
public void setFC(Color c){
    fgc=c;
}
//绘制临时缓冲区
private void drawing(int X,int Y) {
   Graphics g = buff.getGraphics();
   g.setColor(bgc);
   g.clearRect(0,0,w,h);
   copyBuffer();
   g.setColor(tmpc);
   switch(sx){
   case CYCLE:
    Point p = new Point(x,y);
    Point2D p2 = new Point2D.Double(X,Y);
    int dist = (int)p.distance(p2);
    g.drawOval(x,y,0,0);
    g.drawOval(x-dist, y-dist,dist*2,dist*2);
    break;
   case LINE:
    g.drawLine(x,y,X,Y);
    break;
   case RECTANGLE:
    int dx = x-X;
    dx = Math.abs(dx);
    int dy = y-Y;
    dy = Math.abs(dy);
    g.drawRect(x<X?x:X,y<Y?y:Y,dx,dy);
    break;
   }
   g.dispose();
   drawBufferToCVS();
}
//绘制背景缓冲区
private void drawBuffer(int X,int Y){
   Graphics2D gd = background.createGraphics();
   gd.setColor(fgc);
   gd.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
   switch(sx){
   case CYCLE:
    Point p = new Point(x,y);
    Point2D p2 = new Point2D.Double(X,Y);
    int dist = (int)p.distance(p2);
    gd.drawOval(x,y,0,0);
    gd.drawOval(x-dist, y-dist,dist*2,dist*2);
    break;
   case LINE:
    gd.drawLine(x,y,X,Y);
    break;
   case RECTANGLE:
    int dx = x-X;
    dx = Math.abs(dx);
    int dy = y-Y;
    dy = Math.abs(dy);
    gd.drawRect(x<X?x:X,y<Y?y:Y,dx,dy);
    break;
   default:
    popupMsg();
   }
   gd.dispose();
   Graphics g = this.getGraphics();
   g.clearRect(0,0,w,h);
   g.drawImage(background,0,0,null);
   g.dispose();
}
private void popupMsg(){
   JOptionPane.showMessageDialog(this,"请选择一种作图方式开始作图.");
}
//复制背景缓冲区内容到临时缓冲区
private void copyBuffer(){
   Graphics g = buff.getGraphics();
   g.drawImage(background,0,0,null);
   g.dispose();
}
//印出临时缓冲区内容到窗口
private void drawBufferToCVS() {
   Graphics g = this.getGraphics();
   g.drawImage(buff,0,0,null);
   g.dispose();
}
//清除双缓冲区并清除窗口内容
public void reset(){
   clearContents(buff);
   clearContents(background);
   Graphics g = this.getGraphics();
   g.setColor(bgc);
   g.fillRect(0,0,w,h);
   g.dispose();
}
//清除指定缓冲区内容
private void clearContents(BufferedImage i){
   Graphics g = i.getGraphics();
   g.setColor(bgc);
   g.fillRect(0,0,w,h);
   g.dispose();
}
//初始化缓冲区
private void initImages() {
   background=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
   buff=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
   clearContents(background);
   clearContents(buff);
}
//重写此方法,以便在窗口重新显示时能正确显示最后的内容.
public void paint(Graphics g){
//   w = this.getWidth();
//   h = this.getHeight();
   if(background==null){
    w = this.getToolkit().getScreenSize().width;
    h = this.getToolkit().getScreenSize().height;
    initImages();
   }
   g.drawImage(background,0,0,null);
   g.dispose();
}
//双击作图区也能做清除动作,呵呵
public void mouseClicked(MouseEvent e) {
   if(e.getClickCount()==2)
    reset();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
//每当按下鼠标时就重新设置第一点的坐标
public void mousePressed(MouseEvent e) {
   this.x=e.getX();
   this.y=e.getY();
}
//每当释放鼠标时就决定是否需要将背景缓冲区印出到窗口
public void mouseReleased(MouseEvent e) {
   if(hasChanged){
    hasChanged=false;
    drawBuffer(e.getX(),e.getY());
   }
}
//每当鼠标拖动时开始作图
public void mouseDragged(MouseEvent e) {
   hasChanged=true;
   drawing(e.getX(),e.getY());
}
public void mouseMoved(MouseEvent e) {}
}
//作图类型的枚举
enum S{
CYCLE,RECTANGLE,LINE,NULL
}

相关日志

Advertisements

Leave a comment

Featured Post

 

Blogger博客支持实时统计

 

曙光博客稍稍修改