在平常我們常常使用 Windows 的 Ctrl+C (複製) , Ctrl+P (貼上) etc, 那我們有沒有辦法在 Java UI 上添加類似的快捷鍵呢? 答案是使用 KeyAdapter 類別. 底下我們透過一個簡單範例說明如何為 UI 添加快捷鍵與剪貼簿的使用.
CalcUI 範例:
考慮我們有個只有加法的 Calculator 如下, 在按下 "=" 按鈕後會將計算結果顯示於最右邊的 TextField:
而如果我們要將計算結果取出, 則需要到最右邊的 TextField 選取所有內容後, 再按下 Ctrl+C 的複製快捷鍵. 但我們希望一旦按下 "=" 鍵, 接著直接按下 Ctrl+C 的快捷鍵便可以將計算結果置於剪貼簿中. 因此下面將說明如何完成這個需求.
Step1. 第一步就是要先讓 UI 可以監聽到鍵盤的 Event, 此因我們新增另一個類別來處理 Key event 並監聽 Ctrl+C 的事件:
- class MyKeyListener extends KeyAdapter{
- public void keyPressed(KeyEvent e){
- if ((e.getKeyCode() == KeyEvent.VK_C) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
- // Copy calculation result to clipboard
- }
- }
- }
- public class CalcUI extends JFrame implements ClipboardOwner{
- ...
- public CalcUI() {
- super();
- initGUI();
- clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- addKeyListener(new MyKeyListener());
- setFocusable(true); // 確保自己能得到 focus 已收到監聽事件
- frame = this; // 方便後續 reference 到自己.
- }
- ...
- }
- jButtonEq.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent evt) {
- int sum = Integer.valueOf(jTextFieldA.getText()) + Integer.valueOf(jTextFieldB.getText());
- jTextFieldSum.setText(String.valueOf(sum));
- frame.requestFocus(); // 讓外面的 JFrame 獲得 focus 以繼續監聽事件
- }
- });
- class MyKeyListener extends KeyAdapter{
- public void keyPressed(KeyEvent e){
- if ((e.getKeyCode() == KeyEvent.VK_C) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
- StringSelection contents = new StringSelection(jTextFieldSum.getText());
- clipboard.setContents(contents, frame);
- }
- }
- }
- package swing.demo;
- import java.awt.Toolkit;
- import java.awt.datatransfer.Clipboard;
- import java.awt.datatransfer.ClipboardOwner;
- import java.awt.datatransfer.StringSelection;
- import java.awt.datatransfer.Transferable;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyAdapter;
- import java.awt.event.KeyEvent;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JTextField;
- import javax.swing.SwingConstants;
- import javax.swing.SwingUtilities;
- import javax.swing.WindowConstants;
- public class CalcUI extends JFrame implements ClipboardOwner{
- private JTextField jTextFieldA;
- private JTextField jTextFieldSum;
- private JButton jButtonEq;
- private JTextField jTextFieldB;
- private JLabel jLabelPlus;
- public CalcUI frame;
- private Clipboard clipboard;
- /**
- * Auto-generated main method to display this JFrame
- */
- public static void main(String[] args) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- CalcUI inst = new CalcUI();
- inst.setLocationRelativeTo(null);
- inst.setVisible(true);
- }
- });
- }
- public CalcUI() {
- super();
- initGUI();
- clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- addKeyListener(new MyKeyListener());
- setFocusable(true);
- frame = this;
- }
- private void initGUI() {
- try {
- setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- getContentPane().setLayout(null);
- {
- jTextFieldA = new JTextField();
- getContentPane().add(jTextFieldA);
- jTextFieldA.setText("10");
- jTextFieldA.setBounds(12, 12, 83, 24);
- jTextFieldA.setHorizontalAlignment(SwingConstants.CENTER);
- }
- {
- jLabelPlus = new JLabel();
- getContentPane().add(jLabelPlus);
- jLabelPlus.setText("+");
- jLabelPlus.setBounds(101, 15, 17, 17);
- jLabelPlus.setFont(new java.awt.Font("Arial",1,12));
- jLabelPlus.setHorizontalAlignment(SwingConstants.CENTER);
- }
- {
- jTextFieldB = new JTextField();
- getContentPane().add(jTextFieldB);
- jTextFieldB.setText("10");
- jTextFieldB.setBounds(125, 12, 20, 24);
- jTextFieldB.setSize(83, 24);
- jTextFieldB.setHorizontalAlignment(SwingConstants.CENTER);
- }
- {
- jButtonEq = new JButton();
- getContentPane().add(jButtonEq);
- jButtonEq.setText("=");
- jButtonEq.setFocusable(false);
- jButtonEq.setBounds(214, 12, 42, 24);
- jButtonEq.setFont(new java.awt.Font("Arial",1,12));
- jButtonEq.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent evt) {
- int sum = Integer.valueOf(jTextFieldA.getText()) + Integer.valueOf(jTextFieldB.getText());
- jTextFieldSum.setText(String.valueOf(sum));
- frame.requestFocus(); // 讓外面的 JFrame 獲得 focus 以繼續監聽事件
- }
- });
- }
- {
- jTextFieldSum = new JTextField();
- getContentPane().add(jTextFieldSum);
- jTextFieldSum.setText("?");
- jTextFieldSum.setBounds(267, 12, 105, 24);
- jTextFieldSum.setHorizontalAlignment(SwingConstants.CENTER);
- }
- pack();
- this.setSize(400, 86);
- } catch (Exception e) {
- //add your error handling code here
- e.printStackTrace();
- }
- }
- class MyKeyListener extends KeyAdapter{
- public void keyPressed(KeyEvent e){
- if ((e.getKeyCode() == KeyEvent.VK_C) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
- StringSelection contents = new StringSelection(jTextFieldSum.getText());
- clipboard.setContents(contents, frame);
- }
- }
- }
- @Override
- public void lostOwnership(Clipboard arg0, Transferable arg1) {}
- }
* [blog] java Gui 键盘监听事件
* [ Java 代碼範本 ] 用 java 設定、取用剪貼簿內容
* stackoverflow: Java detect CTRL+X key
* Java Tutorial : How to write key listener
沒有留言:
張貼留言