这章我们主要来讨论下用awt包画图,位图处理,使用剪贴板等,由于这些东西比较有套路,我主要以代码形式讲解。
绘图主要是利用Component的三个方法,
paint(Graphics g):绘制组件的外观
update(Graphic g):调用paint方法刷新外观
repaint():调用update
- public class SimpleDraw
- {
- private final String RECT_SHAPE = "rect";
- private final String OVAL_SHAPE = "oval";
- private Frame f = new Frame("简单绘图");
- private Button rect = new Button("绘制矩形");
- private Button oval = new Button("绘制圆形");
- private MyCanvas drawArea = new MyCanvas();
- //用于保存需要绘制什么图形的字符串属性
- private String shape = "";
- public void init()
- {
- Panel p = new Panel();
- rect.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- //设置shape属性为RECT_SHAPE
- shape = RECT_SHAPE;
- //重画MyCanvas对象,即调用它的update方法
- drawArea.repaint();
- }
- });
- oval.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- //设置shape属性为OVAL_SHAPE
- shape = OVAL_SHAPE;
- //重画MyCanvas对象,即调用它的update方法
- drawArea.repaint();
- }
- });
- p.add(rect);
- p.add(oval);
- drawArea.setPreferredSize(new Dimension(250 , 180));
- f.add(drawArea);
- f.add(p , BorderLayout.SOUTH);
- f.pack();
- f.setVisible(true);
- }
- public static void main(String[] args)
- {
- new SimpleDraw().init();
- }
- class MyCanvas extends Canvas
- {
- //重写Canvas的paint方法,实现绘画
- public void paint(Graphics g)
- {
- Random rand = new Random();
- if (shape.equals(RECT_SHAPE))
- {
- //设置画笔颜色
- g.setColor(new Color(220, 100, 80));
- //随机地绘制一个矩形框
- g.drawRect( rand.nextInt(200) , rand.nextInt(120) , 40 , 60);
- }
- if (shape.equals(OVAL_SHAPE))
- {
- //设置画笔颜色
- g.setColor(new Color(80, 100, 200));
- //随机地绘制一个矩形框
- g.fillOval( rand.nextInt(200) , rand.nextInt(120) , 50 , 40);
- }
- }
- }
- }
下面讲个利用BufferedImage实现图形缓冲的例子,eg
- public class HandDraw
- {
- //画图区的宽度
- private final int AREA_WIDTH = 500;
- //画图区的高度
- private final int AREA_HEIGHT = 400;
- //下面的preX、preY保存了上一次鼠标拖动事件的鼠标座标
- private int preX = -1;
- private int preY = -1;
- //定义一个右键菜单用于设置画笔颜色
- PopupMenu pop = new PopupMenu();
- MenuItem redItem = new MenuItem("红色");
- MenuItem greenItem = new MenuItem("绿色");
- MenuItem blueItem = new MenuItem("蓝色");
- //定义一个BufferedImage对象
- BufferedImage image = new BufferedImage(AREA_WIDTH , AREA_HEIGHT ,
- BufferedImage.TYPE_INT_RGB);
- //获取image对象的Graphics
- Graphics g = image.getGraphics();
- private Frame f = new Frame("简单手绘程序");
- private DrawCanvas drawArea = new DrawCanvas();
- //用于保存需要绘制什么图形的字符串属性
- private String shape = "";
- //用于保存画笔颜色
- private Color foreColor = new Color(255, 0 ,0);
- public void init()
- {
- //定义右键菜单的事件监听器。
- ActionListener menuListener = new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- if (e.getActionCommand().equals("绿色"))
- {
- foreColor = new Color(0 , 255 , 0);
- }
- if (e.getActionCommand().equals("红色"))
- {
- foreColor = new Color(255 , 0 , 0);
- }
- if (e.getActionCommand().equals("蓝色"))
- {
- foreColor = new Color(0 , 0 , 255);
- }
- }
- };
- //为三个菜单添加事件监听器
- redItem.addActionListener(menuListener);
- greenItem.addActionListener(menuListener);
- blueItem.addActionListener(menuListener);
- //将菜单项组合成右键菜单
- pop.add(redItem);
- pop.add(greenItem);
- pop.add(blueItem);
- //将右键菜单添加到drawArea对象中
- drawArea.add(pop);
- //将image对象的背景色填充成白色
- g.fillRect(0 , 0 ,AREA_WIDTH , AREA_HEIGHT);
- drawArea.setPreferredSize(new Dimension(AREA_WIDTH , AREA_HEIGHT));
- //监听鼠标移动动作
- drawArea.addMouseMotionListener(new MouseMotionAdapter()
- {
- //实现按下鼠标键并拖动的事件处理器
- public void mouseDragged(MouseEvent e)
- {
- //如果preX和preY大于0
- if (preX > 0 && preY > 0)
- {
- //设置当前颜色
- g.setColor(foreColor);
- //绘制从上一次鼠标拖动事件点到本次鼠标拖动事件点的线段
- g.drawLine(preX , preY , e.getX() , e.getY());
- }
- //将当前鼠标事件点的X、Y座标保存起来
- preX = e.getX();
- preY = e.getY();
- //重绘drawArea对象
- drawArea.repaint();
- }
- });
- //监听鼠标事件
- drawArea.addMouseListener(new MouseAdapter()
- {
- //实现鼠标松开的事件处理器
- public void mouseReleased(MouseEvent e)
- {
- //弹出右键菜单
- if (e.isPopupTrigger())
- {
- pop.show(drawArea , e.getX() , e.getY());
- }
- //松开鼠标键时,把上一次鼠标拖动事件的X、Y座标设为-1。
- preX = -1;
- preY = -1;
- }
- });
- f.add(drawArea);
- f.pack();
- f.setVisible(true);
- }
- public static void main(String[] args)
- {
- new HandDraw().init();
- }
- class DrawCanvas extends Canvas
- {
- //重写Canvas的paint方法,实现绘画
- public void paint(Graphics g)
- {
- //将image绘制到该组件上
- g.drawImage(image , 0 , 0 , null);
- }
- }
- }
由于以上每次画都刷全图,闪烁还是不能避免,其实只要刷画笔的周围就可以实现基本不闪的效果,利用Swing的JPanel组件等都已经实现了双缓冲了
下面再讲下利用ImageIO来对图片进行读写,在windows现在支持这几种图片格式
BMP
jpeg
bmp
wbmp
gif
JPG
png
jpg
JPEG
WBMP
常用的基本都支持了,举个使用实例eg
- public class ZoomImage
- {
- //下面两个常量设置缩小后图片的大小
- private final int WIDTH = 80;
- private final int HEIGHT = 60;
- //定义个BuffedImage对象,用于保存缩小后的位图
- BufferedImage image = new BufferedImage(WIDTH , HEIGHT ,
- BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- public void zoom()throws Exception
- {
- //读取原始位图
- Image srcImage = ImageIO.read(new File("image/board.jpg"));
- //将原始位图缩小后绘制到image图象中
- g.drawImage(srcImage , 0 , 0 , WIDTH , HEIGHT , null);
- //将image图象文件输出到磁盘文件中。
- ImageIO.write(image , "jpeg" ,
- new File(System.currentTimeMillis() + ".jpg"));
- }
- public static void main(String[] args)throws Exception
- {
- new ZoomImage().zoom();
- }
- }
最后简单讲下剪贴板的使用,主要区别下系统剪贴板和本地剪贴板的区别,本地的复制只能在jvm里使用。eg
- public class SimpleClipboard
- {
- private Frame f = new Frame("简单的剪贴板程序");
- //获取系统剪贴板
- private Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- //下面是创建本地剪贴板的代码
- //Clipboard clipboard = new Clipboard("cb");
- //用于复制文本的文本框
- private TextArea jtaCopyTo = new TextArea(5,20);
- //用于粘贴文本的文本框
- private TextArea jtaPaste = new TextArea(5,20);
- private Button btCopy = new Button("复制"); //拷贝按钮
- private Button btPaste = new Button("粘贴"); //粘贴按钮
- public void init()
- {
- Panel p = new Panel();
- p.add(btCopy);
- p.add(btPaste);
- btCopy.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- //将一个多行文本域里的字符串封装成StringSelection对象
- StringSelection contents=new StringSelection(jtaCopyTo.getText());
- //将StringSelection对象放入剪贴板
- clipboard.setContents(contents, null);
- }
- });
- btPaste.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- //如果剪贴板中包含stringFlavor内容
- if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))
- {
- try
- {
- //取出剪贴板中stringFlavor内容
- String content = (String)clipboard.getData(DataFlavor.stringFlavor);
- jtaPaste.append(content);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
- });
- //创建一个水平排列的Box容器
- Box box = new Box(BoxLayout.X_AXIS);
- //将两个多行文本域放在Box容器中
- box.add(jtaCopyTo);
- box.add(jtaPaste);
- //将按钮所在Panel、Box容器添加到Frame窗口中
- f.add(p,BorderLayout.SOUTH);
- f.add(box,BorderLayout.CENTER);
- f.pack();
- f.setVisible(true);
- }
- public static void main(String[] args)
- {
- new SimpleClipboard().init();
- }
- }