swing中添加右键菜单

右键菜单是一直是一个非常实用的功能,在此,乘着现在还有一些印象做基础,存一个在swing中添加右键菜单功能的小例子,方便以后备用。

ps: 连Oracle官方都不推荐实用swing,而改用JavaFX了,基本上在官方的各种swing组件说明中都能看到一句

If you are interested in using JavaFX to create your GUI, see Working With Layouts in JavaFX.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import java.awt.Color;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;

public class Test02 {

@SuppressWarnings("serial")
class TextAreaMenu extends JTextArea{
// 菜单增加选项,复制,粘贴,剪切
JMenuItem copy = null, paste = null, cut = null;

public TextAreaMenu(){
// 给当前组件添加右键菜单组件
JPopupMenu menu = new JPopupMenu();
menu.add(copy = new JMenuItem("复制"));
menu.add(paste = new JMenuItem("粘贴"));
menu.add(cut = new JMenuItem("剪切"));

// 设置键盘操作
copy.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK));
paste.setAccelerator(KeyStroke.getKeyStroke('V', InputEvent.CTRL_MASK));
cut.setAccelerator(KeyStroke.getKeyStroke('X', InputEvent.CTRL_MASK));

// 设置边框增强显示效果
this.setBorder(BorderFactory.createLineBorder(Color.red));

this.addMouseListener(new MouseAdapter(){
// 当前组件的鼠标点击事件
@Override
public void mouseClicked(MouseEvent e) {
// MouseEvent.BUTTON1: 左键点击
// MouseEvent.BUTTON2: 中间点击(滑轮)
if(e.getButton() == MouseEvent.BUTTON3){
// 设置右键点击事件,打开邮件菜单
menu.show(TextAreaMenu.this,e.getX(),e.getY());

// 设置选项是否可用
boolean isCanCopy = isCanCopy();
copy.setEnabled(isCanCopy);
cut.setEnabled(isCanCopy);
// 剪贴板是否存在数据
paste.setEnabled(isClipboardString());
}
}
});

// 初始化选项事件
initEvent();
}

private void initEvent(){
copy.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("点击了复制按钮");
TextAreaMenu.this.copy();
}
});

paste.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("点击了粘贴按钮");
TextAreaMenu.this.paste();
}
});

cut.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("点击了剪切按钮");
TextAreaMenu.this.cut();
}
});
}

/**
* 当前文本组件是否可以复制
* true 具备
* false 不具备
* @return
*/
public boolean isCanCopy() {
// getSelectionStart() 返回选定文本的起始位置。如果是空文档,则返回 0;如果没有选定,则返回点值。
int start = this.getSelectionStart();
// getSelectionEnd() 返回选定文本的结束位置。如果文本为空,则返回 0;如果没有选择,则返回点值。
int end = this.getSelectionEnd();
return start != end;
}

/**
* 剪切板中是否有文本数据可供粘贴
* true 有文本数据
* false 无
* @return true为有文本数据
*/
public boolean isClipboardString() {
boolean b = false;
// 获取剪贴板对象
Clipboard clipboard = this.getToolkit().getSystemClipboard();
try {
// getContents(), 获取剪贴板对象中的数据对象,无则返回null
Transferable content = clipboard.getContents(this);
// getTransferData(), 获取数据对象中的值
if (content.getTransferData(DataFlavor.stringFlavor) instanceof String) {
b = true;
}
} catch (Exception e) {
return false;
}
return b;
}
}

public static void main(String[] args) {
JFrame jf = new JFrame("测试窗口");
jf.setSize(600, 600);
TextAreaMenu textAreaMenu = new Test02().new TextAreaMenu();
jf.setContentPane(textAreaMenu);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}

显示: