疯狂JAVA讲义---第十一章(下):AWT编程-高级应用
2009-01-10 21:09
513 查看
这章我们主要来讨论下用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();
}
}
绘图主要是利用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();
}
}
相关文章推荐
- 疯狂JAVA讲义---第十一章(中):AWT编程-常用组件和事件处理
- 疯狂JAVA讲义---第十一章(上):AWT编程-布局管理器
- [疯狂Java讲义精粹] 第十一章|多线程
- [疯狂Java讲义精粹] 第十二章|网络编程
- 疯狂JAVA讲义---第十三章:JDBC编程(下)
- 疯狂JAVA讲义---第十二章:Swing编程(四)Applet和JApplet
- JAVA疯狂讲义第三版4.6.6数组的应用举例代码功能扩展
- java8--网络编程(java疯狂讲义3复习笔记)
- 疯狂JAVA讲义---第十二章:Swing编程(一)基本组件
- 疯狂JAVA讲义---第十二章:Swing编程(七)JTree树
- 疯狂JAVA讲义---第十二章:Swing编程(六)微调控制器和列表框
- 疯狂JAVA讲义---第十二章:Swing编程(七)JTree树
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
- 疯狂JAVA讲义---第十二章:Swing编程(八)JTable表格
- 【JAVA编程】泛型高级应用之泛型限定
- 疯狂JAVA讲义---第十二章:Swing编程(三)拖放功能
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
- 疯狂JAVA讲义---第十二章:Swing编程(二)特殊容器
- 疯狂JAVA讲义---第十三章:JDBC编程(上)
- java8--Mysql数据库与JDBC编程(java疯狂讲义3复习笔记)