MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A);
MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, true);
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class SimpleMenu {
private Frame f = new Frame("test");
private MenuBar mb = new MenuBar();
Menu file = new Menu("文件");
Menu edit = new Menu("编辑");
MenuItem newItem = new MenuItem("新建");
MenuItem saveItem = new MenuItem("保存");
//创建exitItem菜单项,指定使用“Ctrl+X”快捷键
MenuItem exitItem = new MenuItem("退出",
new MenuShortcut(KeyEvent.VK_X));
CheckboxMenuItem autoWrap = new CheckboxMenuItem("自动换行");
MenuItem copyItem = new MenuItem("复制");
MenuItem pasteItem = new MenuItem("粘贴");
Menu format = new Menu("格式");
//创建commentItem菜单项,指定使用“Ctrl+Shift+/”快捷键
MenuItem commentItem = new MenuItem("注释",
new MenuShortcut(KeyEvent.VK_SLASH, true));
MenuItem cancelItem = new MenuItem("取消注释");
private TextArea ta = new TextArea(6, 40);
public void init()
{
//以lambda表达式创建菜单事件监听器
ActionListener menuListener = e ->
{
String cmd = e.getActionCommand();
ta.append("单击“"+cmd+"”菜单"+"\n");
if(cmd.equals("退出"))
System.exit(0);
};
//为commentItem菜单项添加事件监听器
commentItem.addActionListener(menuListener);
exitItem.addActionListener(menuListener);
//为file菜单添加菜单项
file.add(newItem);
file.add(saveItem);
file.add(exitItem);
//为edit菜单添加菜单项
edit.add(autoWrap);
//使用addSeparator方法来添加菜单分割线
edit.addSeparator();
edit.add(copyItem);
edit.add(pasteItem);
//为format菜单添加菜单项
format.add(commentItem);
format.add(cancelItem);
//使用添加new MenuItem("-")的方式添加菜单分割线
edit.add(new MenuItem("-"));
edit.add(format);
mb.add(file);
mb.add(edit);
//为f窗口设置菜单条
f.setMenuBar(mb);
//以匿名内部类的方式创建事件监听器对象
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(ta);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new SimpleMenu().init();
}
}
import java.awt.*;
import java.awt.event.*;
public class PopupMenuTest {
private TextArea ta = new TextArea(4, 30);
private Frame f = new Frame("测试");
PopupMenu pop = new PopupMenu();
CheckboxMenuItem autoWrap =
new CheckboxMenuItem("自动换行");
MenuItem copyItem = new MenuItem("复制");
MenuItem pasteItem = new MenuItem("粘贴");
Menu format = new Menu("格式");
MenuItem commentItem = new MenuItem("注释",
new MenuShortcut(KeyEvent.VK_SLASH, true));
MenuItem cancelItem = new MenuItem("取消注释");
public void init()
{
ActionListener menuListener = e ->
{
String cmd = e.getActionCommand();
ta.append("单击“"+cmd+"”菜单"+"\n");
if(cmd.equals("退出"))
{
System.exit(0);
}
};
commentItem.addActionListener(menuListener);
pop.add(autoWrap);
pop.addSeparator();
pop.add(copyItem);
pop.add(pasteItem);
format.add(commentItem);
format.add(cancelItem);
pop.add(new MenuItem("-"));
pop.add(format);
Panel p = new Panel();
p.setPreferredSize(new Dimension(300, 160));
p.add(pop);
p.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if(e.isPopupTrigger()) {
pop.show(p, e.getX(), e.getY());
}
}
});
f.add(p);
f.add(ta, BorderLayout.NORTH);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new PopupMenuTest().init();
}
}
paint(Graphics g):
绘制组件的外观update(Graphics g):
调用paint()方法,刷新组件外观repaint():
调用update()方法,刷新组件外观public void update(Graphics g) {
if (isShowing()) {
//以组件的背景色填充整个组件区域
if (! (peer instanceof LightweightPeer)) {
g.clearRect(0, 0, width, height);
}
paint(g);
}
}
public void update(Graphics g) {
paint(g);
}
drawLine():
绘制直线drawString():
绘制字符串drawRect():
绘制矩形drawRoundRect():
绘制圆角矩形drawOval():
椭圆drawPolygon():
多边形边框drawArc():
圆弧drawPolyline():
折线fillRect():
填充矩形fillRoundRect():
填充圆角矩形fillOval():
椭圆fillPolygon():
多边形fillArc():
填充圆弧和其两个端点到中心连线所包围的区域drawImage():
绘制位图AWT普通组件也可以通过Color()和Font()方法改变它的前景色和字体。且所有组件都有一个setBackground()方法用于设置组件的背景色。
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
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 = "";
class MyCanvas extends Canvas
{
//重写方法,实现绘画
public void paint(Graphics g)
{
Random rand = new Random();
if (shape.equals(RECT_SHAPE))
{
//设置画笔颜色
g.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
//随机地绘制一个矩形框
g.drawRect(rand.nextInt(200),
rand.nextInt(120), 40, 60);
}
if (shape.equals(OVAL_SHAPE))
{
//设置画笔颜色
g.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
g.fillOval(rand.nextInt(200),
rand.nextInt(120), 50, 40);
}
}
}
public void init()
{
Panel p = new Panel();
rect.addActionListener(e ->
{
shape = RECT_SHAPE;
drawArea.repaint();
});
oval.addActionListener(e ->
{
shape = OVAL_SHAPE;
drawArea.repaint();
});
p.add(rect);
p.add(oval);
drawArea.setPreferredSize(new Dimension(250, 180));
f.add(drawArea);
f.add(p, BorderLayout.SOUTH);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new SimpleDraw().init();
}
}
Timer(int delay, ActionListener listener):
每间隔delay毫秒,系统自动触发ActionListener监听器里的事件处理器(actionPerformed()方法)import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class PinBall {
//桌面的宽度
private final int TABLE_WIDTH = 300;
//桌面高度
private final int TABLE_HEIGHT = 400;
//球拍的垂直位置
private final int RACKET_Y = 340;
//定义球拍的宽度、高度
private final int RACKET_HEIGHT = 20;
private final int RACKET_WIDTH = 60;
//小球大小
private final int BALL_SIZE = 16;
private Frame f = new Frame("love you~");
Random rand = new Random();
//小球纵向运行速度
private int ySpeed = 10;
//返回一个-0.5~0.5的比率,用于控制小球的运行方向
private double xyRate = rand.nextDouble() - 0.5;
//小球横向运行速度
private int xSpeed = (int)(ySpeed*xyRate*2);
//ballX和ballY代表小球的坐标
private int ballX = rand.nextInt(200) + 20;
private int ballY = rand.nextInt(10) + 20;
//racketX代表球拍的水平位置
private int racketX = rand.nextInt(200);
private MyCanvas tableArea = new MyCanvas();
Timer timer;
private int score = 0;
//游戏是否结束的旗标
private boolean isLose = false;
public void init()
{
//设置桌面区域的最佳大小
tableArea.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));
f.add(tableArea);
//定义键盘监听器
KeyAdapter keyProcessor = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
{
if(racketX > 0)
racketX -= 10;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
{
if(racketX < TABLE_WIDTH-RACKET_WIDTH)
racketX += 10;
}
}
};
//增加“×”关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//为窗口和tableArea对象分别添加键盘监听器
f.addKeyListener(keyProcessor);
tableArea.addKeyListener(keyProcessor);
//定义每0.1秒执行一次的事件监听器
ActionListener taskPerformer = evt ->
{
//如果小球碰到左右边框
if(ballX <= 0 || ballX >= TABLE_WIDTH-BALL_SIZE)
xSpeed=-xSpeed;
//如果小球高度超出了球拍的位置,且横向不在球拍范围之内,则游戏结束
if (ballY >= RACKET_Y -BALL_SIZE &&(ballX<racketX || ballX>racketX + RACKET_WIDTH))
{
timer.stop();
isLose = true;
tableArea.repaint();
}
//如果小球位于球拍之内, 且到达球拍位置,小球反弹
else if (ballY <= 0 || (ballY >= RACKET_Y- BALL_SIZE && ballX> racketX&&ballX <=racketX +RACKET_WIDTH))
{
ySpeed=-ySpeed;
}
//小球坐标变化
ballY += ySpeed;
ballX += xSpeed;
tableArea.repaint();
score ++;
};
timer = new Timer(100, taskPerformer);
timer.start();
f.pack();
f.setVisible(true);
}
class MyCanvas extends Canvas
{
//重写paint方法
public void paint(Graphics g)
{
if (isLose) {
g.setColor(new Color(255,0,0));
g.setFont(new Font("Times", Font.BOLD, 25));
g.drawString("游戏结束!\n你的得分是"+score , 50, 200 );
}
else
{
g.setColor(new Color(222, 118, 222, 255));
g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE);
//设置颜色,并绘制球拍
g.setColor(new Color(80, 80, 200, 200));
g.fillRect(racketX, RACKET_Y, RACKET_WIDTH, RACKET_HEIGHT);
}
}
}
public static void main(String[] args) {
new PinBall().init();
}
}
BufferedImage(int width, int height, int imageType):
创建指定大小、指定图像类型的BufferedImage对象,其中imageType可以使BufferedImage.TYPE_INT_RGB、BufferedImage.TYPE_BYTE_GRAY等值。import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
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("red");
MenuItem greenItem = new MenuItem("green");
MenuItem blueItem = new MenuItem("blue");
//定义一个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 Color foreColor = new Color(255, 0, 0);
public void init()
{
ActionListener menuListener = e->
{
if(e.getActionCommand().equals("green"))
foreColor = new Color(0, 255, 0);
if(e.getActionCommand().equals("red"))
foreColor = new Color(255, 0, 0);
if(e.getActionCommand().equals("blue"))
foreColor = new Color(0, 0, 255);
};
//为三个菜单添加事件监听器
redItem.addActionListener(menuListener);
blueItem.addActionListener(menuListener);
greenItem.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() {
@Override
public void mouseDragged(MouseEvent e) {
if(preX > 0 && preY > 0)
{
g.setColor(foreColor);
g.drawLine(preX, preY, e.getX(), e.getY());
}
preX = e.getX();
preY = e.getY();
drawArea.repaint();
}
});
drawArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger())
{
pop.show(drawArea, e.getX(), e.getY());
}
preX = -1;
preY = -1;
}
});
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(drawArea);
f.pack();
f.setVisible(true);
}
class DrawCanvas extends Canvas
{
//重写paint
@Override
public void paint(Graphics g)
{
g.drawImage(image, 0, 0, null);
}
}
public static void main(String[] args) {
new HandDraw().init();
}
}
static String[] getReaderFileSuffixes():
返回一个String数组,该数组列出ImageIO所有能读的图形文件的文件后缀static String[] getReaderFormatNames():
返回一个String数组,该数组列出ImageIO所有能读的图形文件的非正式格式名称static String[] getWriterFileSuffixes():
返回一个String数组,该数组列出ImageIO所有能写的图形文件的文件后缀static String[] getWriterFormatNames():
返回一个String数组,该数组列出ImageIO所有能写的图形文件的非正式格式名称。import javax.imageio.ImageIO;
public class ImageIOTest {
public static void main(String[] args) {
String[] readFormat = ImageIO.getReaderFormatNames();
for (String tmp:readFormat) {
System.out.println(tmp);
}
System.out.println("--------");
String[] writeFormat = ImageIO.getWriterFormatNames();
for (String tmp:writeFormat) {
System.out.println(tmp);
}
}
}
lancibe@lancibe-PC:~/java/test/src/chapter11/src$ java ImageIOTest
JPG
jpg
tiff
bmp
BMP
gif
GIF
WBMP
png
PNG
JPEG
tif
TIF
TIFF
wbmp
jpeg
--------
JPG
jpg
tiff
bmp
BMP
gif
GIF
WBMP
png
PNG
JPEG
tif
TIF
TIFF
jpeg
wbmp
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class ZoomImage {
private final int WIDTH = 80;
private final int HEIGHT = 60;
//定义一个BufferedImage对象,用于保存缩小之后的位图
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"));
g.drawImage(srcImage, 0, 0, WIDTH, HEIGHT, null);
ImageIO.write(image, "jpeg", new File(System.currentTimeMillis() + ".jpg"));
}
public static void main(String[] args)
throws Exception
{
new ZoomImage().zoom();
}
}
传递文本是最简单的情形,因为AWT以及提供了一个StringSelection用于传输文本字符串。将一段文本内容(字符串对象)放进剪贴板的步骤如下:
创建一个Clipboard实例,创建系统剪贴板如下:
Clipboard clipboard = Toolkit.getDefaultToolkit.getSystemClipboard();
创建本地剪贴板如下:
Clipboard clipboard = new Clipboard();
将需要放入剪贴板中的字符串封装成StringSelection对象:
StringSelection st = new StringSelection(targetStr);
调用剪贴板对象的setContents()方法将StringSelection对象放入剪切板中,该方法需要两个参数,第一个时Transferable对象,第二个是ClipboardOwner对象,代表剪贴板数据的所有者,通常我们无须关心剪贴数据的所有者,设为null。
clipboard.setContents(st, null);
从剪贴板中取出数据则比较简单,调用Clipboard对象的getData(DataFlavor flavor)方法即可取出剪贴板中指定格式的内容,如果指定flavor的数据不存在,该方法将引发UnsupportedFlavorException异常。为避免出现异常,应先使用Clipboard对象的isDataFlavorAvailable(DataFlavor flavor)方法作为if的判据来判断指定的flavor的数据是否存在。
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))
String content = (String)clipboard.getData(DataFlavor.stringFlavor)
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
public class SimpleClipboard {
private Frame f = new Frame("test");
private Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
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(event ->
{
//将一个多行文本域里的字符串封装成StringSelection对象
StringSelection contents = new StringSelection(jtaCopyTo.getText());
//将该对象放入剪贴板
clipboard.setContents(contents, null);
});
btPaste.addActionListener(e ->
{
if(clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))
{
try
{
String content = (String)clipboard.getData(DataFlavor.stringFlavor);
jtaPaste.append(content);
}
catch (Exception ex)
{
ex.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.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new SimpleClipboard().init();
}
}
前面介绍过,Transferable接口代表可以放入剪贴板的传输对象,所以如果希望将图像反复剪贴板内,则必须提供一个Transferable接口的实现类。该实现类其实很简单,他封装了一个image对象,并且向外表现为imageFlavor内容。
JDK为Transferable接口仅提供了一个StringSelection实现类,用于封装字符串内容。但JDK在DataFlavor类中提供了一个imageFlavor常亮,用于代表图像格式的DataFlavor,并负责执行所有的复杂操作,以便进行Java图像和剪贴板图像的转换。
下面程序实现了一个ImageSelection类,该类实现了Transferable接口,并实现了该接口所包含的三个方法。
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
public class ImageSelection implements Transferable {
private Image image;
//构造器,负责持有一个Image对象
public ImageSelection(Image image)
{
this.image = image;
}
//返回该Transferable对象所持有的所有DataFlavor
@Override
public DataFlavor[] getTransferDataFlavors()
{
return new DataFlavor[]{DataFlavor.imageFlavor};
}
//取出该Transferable对象里实际的数据
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if(flavor.equals(DataFlavor.imageFlavor))
return image;
else
throw new UnsupportedFlavorException(flavor);
}
//返回该Transferable对象是否支持指定的DataFlavor
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.imageFlavor);
}
}
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class CopyImage {
//系统剪贴板
private Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
//使用ArrayList数据结构来保存所有粘贴进来的Image——就是当成图层处理
List<Image> imageList = new ArrayList<Image>();
//画图区的宽度
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("red");
MenuItem greenItem = new MenuItem("green");
MenuItem blueItem = new MenuItem("blue");
//定义一个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 Color foreColor = new Color(255, 0, 0);
public void init()
{
ActionListener menuListener = (e->
{
if(e.getActionCommand().equals("green"))
foreColor = new Color(0, 255, 0);
if(e.getActionCommand().equals("red"))
foreColor = new Color(255, 0, 0);
if(e.getActionCommand().equals("blue"))
foreColor = new Color(0, 0, 255);
});
//为三个菜单添加事件监听器
redItem.addActionListener(menuListener);
blueItem.addActionListener(menuListener);
greenItem.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() {
@Override
public void mouseDragged(MouseEvent e) {
if(preX > 0 && preY > 0)
{
g.setColor(foreColor);
g.drawLine(preX, preY, e.getX(), e.getY());
}
preX = e.getX();
preY = e.getY();
drawArea.repaint();
}
});
drawArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger())
{
pop.show(drawArea, e.getX(), e.getY());
}
preX = -1;
preY = -1;
}
});
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(drawArea);
Panel p = new Panel();
Button copy = new Button("复制");
Button paste = new Button("粘贴");
copy.addActionListener(e -> {
//将image对象封装成ImageSelection对象
ImageSelection contents = new ImageSelection(image);
//将ImageSelection对象放入剪贴板
clipboard.setContents(contents, null);
});
paste.addActionListener(e -> {
//如果剪贴板中包含imageFlavor内容
if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor))
{
try
{
//取出剪贴板中的imageFlavor内容,并将其添加到List集合中
imageList.add((Image)clipboard.getData(DataFlavor.imageFlavor));
drawArea.repaint();
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
});
p.add(copy);
p.add(paste);
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
class DrawCanvas extends Canvas
{
@Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, null);
for(Image img:imageList)
g.drawImage(img, 0, 0, null);
}
}
public static void main(String[] args) {
new CopyImage().init();
}
}
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.io.Serializable;
public class SerialSelection implements Transferable {
//持有一个可序列化对象
private Serializable obj;
//创建该类对象时,传入被持有的对象
public SerialSelection(Serializable obj)
{
this.obj = obj;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] flavors = new DataFlavor[2];
//获取被封装对象的类型
Class clazz = obj.getClass();
try
{
flavors[0] = new DataFlavor(DataFlavor.javaSerializedObjectMimeType + ";class="+clazz.getName());
flavors[1] = DataFlavor.stringFlavor;
return flavors;
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
return null;
}
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if(!isDataFlavorSupported((flavor)))
{
throw new UnsupportedFlavorException(flavor);
}
if(flavor.equals(DataFlavor.stringFlavor))
{
return obj.toString();
}
return obj;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.stringFlavor) || flavor.getPrimaryType().equals("application")
&& flavor.getSubType().equals("x-java-serialized-object")
&& flavor.getRepresentationClass().isAssignableFrom(obj.getClass());
}
}
"application/x-java-serialized-object;class="+clazz.getName()
,他表示封装可序列化的Java对象的数据格式import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.Serializable;
public class CopySerializable {
Frame f = new Frame("复制对象");
Button copy = new Button("复制");
Button paste = new Button("粘贴");
TextField name = new TextField(15);
TextField age = new TextField(15);
TextArea ta = new TextArea(3, 30);
//创建系统剪贴板
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
public void init()
{
Panel p = new Panel();
p.add(new Label("姓名"));
p.add(name);
p.add(new Label("年龄"));
p.add(age);
f.add(p, BorderLayout.NORTH);
f.add(ta);
Panel bp = new Panel();
copy.addActionListener(e -> copyDog());
paste.addActionListener(e ->
{
try
{
readDog();
}
catch (Exception ee)
{
ee.printStackTrace();
}
});
bp.add(copy);
bp.add(paste);
f.add(bp, BorderLayout.SOUTH);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.pack();
f.setVisible(true);
}
public void copyDog()
{
Dog d = new Dog(name.getText(), Integer.parseInt(age.getText()));
SerialSelection ls = new SerialSelection(d);
clipboard.setContents(ls, null);
}
public void readDog()
{
DataFlavor peronFlavor = new DataFlavor(DataFlavor.javaSerializedObjectMimeType + ";class=Dog");
if(clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))
{
Dog d = (Dog)clipboard.getData(peronFlavor);
ta.setText(d.toString());
}
}
public static void main(String[] args) {
new CopySerializable().init();
}
}
DropTarget(Component c, int ops, DropTargetListener dtl):
将c组件创建成一个拖放目标,该拖放目标默认可接受ops值所指定的拖放操作。其中DropTargetListener是拖放操作的关键,他负责对拖放操作作出相应的响应。ops可接受如下几个值
//将当前窗口创建成拖放目标
new DropTarget(jf, DnDconstants.ACTION_COPY, new ImageDropTargetListener());
dragEnter(DropTargetDragEvent dtde):
当光标进入拖放目标时触发DropTargetListener监听器的该方法dragExit(DropTargetEvent dtde):
当光标移出拖放目标时将触发DropTargetListener监听器的该方法dragOver(DropTargetEvent dtde):
当光标在拖放目标上移动时将触发DropTargetListener监听器的该方法drop(DropTargetDropEvent dtde):
当用户在拖放目标上松开鼠标键时,拖放结束时将触发DropTargetListener监听器的该方法dropActionChanged(DropTargetDragEvent dtde):
当用户在拖放目标上改变了拖放操作,例如按下或松开Ctrl等辅助键时将触发DropTargetListener监听器的该方法。import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class DropTargetTest {
final int DESKTOP_WIDTH = 480;
final int DESKTOP_HEIGHT = 360;
final int FRAME_DISTANCE = 30;
JFrame jf = new JFrame("测试拖放目标——把目标文件拖入该窗口");
//定义一个虚拟桌面
private JDesktopPane desktop = new JDesktopPane();
//保存下一个内部窗口的坐标点
private int nextFrameX;
private int nextFrameY;
//定义内部窗口为虚拟桌面的1/2大小
private int width = DESKTOP_WIDTH / 2;
private int height = DESKTOP_HEIGHT / 2;
public void init()
{
desktop.setPreferredSize(new Dimension(DESKTOP_WIDTH, DESKTOP_HEIGHT));
//将当前窗口创建成拖放目标
new DropTarget(jf, DnDConstants.ACTION_COPY, new ImageDropTargetListener());
jf.add(desktop);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
class ImageDropTargetListener extends DropTargetAdapter
{
@Override
public void drop(DropTargetDropEvent event) {
//接收复制操作
event.acceptDrop(DnDConstants.ACTION_COPY);
//获取拖放的内容
Transferable transferable = event.getTransferable();
DataFlavor[] flavors = transferable.getTransferDataFlavors();
//便利拖放内容里的所有数据格式
for(int i = 0 ; i < flavors.length ; i++)
{
DataFlavor d = flavors[i];
try
{
//如果拖放内容的数据格式是文件列表
if(d.equals(DataFlavor.javaFileListFlavor))
{
//取出拖放操作里的文件列表
List fileList = (List)transferable.getTransferData(d);
for(Object f : fileList)
{
//显示每一个文件
showImage((File)f, event);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
//强制拖放操作结束,停止阻塞拖放目标
event.dropComplete(true);
}
}
//显示每个文件的工具方法
private void showImage(File f, DropTargetDropEvent event)
throws IOException
{
Image image = ImageIO.read(f);
if(image == null)
{
//强制拖放操作结束,停止阻塞拖放目标
event.dropComplete(true);
JOptionPane.showInternalMessageDialog(desktop, "系统不支持该类型文件");
//方法返回,不会继续操作
return;
}
ImageIcon icon = new ImageIcon(image);
//创建内部窗口并显示图片
JInternalFrame iframe = new JInternalFrame(f.getName(), true, true, true, true);
JLabel imageLabel = new JLabel(icon);
iframe.add(new JScrollPane(imageLabel));
desktop.add(iframe);
//设置内部窗口的原始位置(内部窗口默认大小0*0,放在0,0位置)
iframe.reshape(nextFrameX, nextFrameY, width, height);
//使该窗口可见
iframe.show();
//计算下一个窗口内部位置
nextFrameX += FRAME_DISTANCE;
nextFrameY += FRAME_DISTANCE;
if(nextFrameX + width > desktop.getWidth())
nextFrameX = 0;
if(nextFrameY + height > desktop.getHeight())
nextFrameY = 0;
}
}
public static void main(String[] args) {
new DropTargetTest().init();
}
}