HƯỚNG DẪN Copy, Cut and Paste Listener for JTextField and JTextArea

Joe

Thành viên VIP
21/1/13
2,958
1,323
113
Hi

I know that some SWING developers are sometimes very frustrated when they want to "copy" a long string from a source A into a JTextField or JTextArea. But unlike JavaFX TextField and TextArea where the text can be easily copied, cut and pasted SWING JTextArea and JTextField lack of these useful functions. I show you how to "steal" the JFX functions and to "glue" them to the mentioned SWING JTextField and JTextArea. How? The mouse is the most universal tool for a GUI application. So we use the mouse. A text can be marked by a mouse right pad and with the left pad the marked text can be copied or cut or pasted at the cursor position as JFX does with TextArea and TextField. So, what we have to do is to take over this functions by implementing the SWING MouseListener Interface and name it as the CopyCutPaste Listener for JComponent. Why JComponent? Because it is the base of JTextArea and JTextField.

The CopyCutPaste.java API
Java:
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.*;
// Joe Nartca (c)
/**
CopyAndPaste for J Components such as JTextField, JTextArea, etc.
*/
public class CopyCutPaste implements MouseListener {
  /**
   Constructor A pop-up menu "Copy/Cut/Paste" with the click of the right mouse-pad
   @param jcomp any Jcomponent. Example JTextArea, JtextField, JTextPane, etc.
  */
  public CopyCutPaste(JTextComponent jcomp) {
    this.jcomp = jcomp;
  }
  /**
  self-explained
  @param e MouseEvent
  */
  public void mousePressed(MouseEvent e){
    if (e.isPopupTrigger()) popup(e);
  }
  /**
  self-explained
  @param e MouseEvent
  */
  public void mouseReleased(MouseEvent e){
    if (e.isPopupTrigger())popup(e);
  }
  //
  private void popup(MouseEvent e){
    JPopupMenu menu = new JPopupMenu();
    JMenuItem copy = new JMenuItem(jcomp.getActionMap().get(DefaultEditorKit.copyAction));
    copy.setAccelerator(KeyStroke.getKeyStroke((int)'C', InputEvent.CTRL_DOWN_MASK));
    copy.setText("Copy");
    menu.add(copy);

    JMenuItem cut = new JMenuItem(jcomp.getActionMap().get(DefaultEditorKit.cutAction));
    cut.setAccelerator(KeyStroke.getKeyStroke((int)'X', InputEvent.CTRL_DOWN_MASK));
    cut.setText("Cut");
    menu.add(cut);

    JMenuItem paste = new JMenuItem(jcomp.getActionMap().get(DefaultEditorKit.pasteAction));
    paste.setAccelerator(KeyStroke.getKeyStroke((int)'V', InputEvent.CTRL_DOWN_MASK));
    paste.setText("Paste");
    menu.add(paste);
    menu.show(e.getComponent(), e.getX(), e.getY());
  }
  // Implementation of MouseListener
  public void mouseClicked(MouseEvent me) {
    Highlighter hl = jcomp.getHighlighter();
    Highlighter.Highlight[] hls = hl.getHighlights();
    try { // remove the highlight at this click
      int caretPos = jcomp.getCaretPosition();
      int beg = Utilities.getWordStart((JTextComponent)jcomp, caretPos);
      int end = Utilities.getWordEnd((JTextComponent)jcomp, caretPos);
      String word = null;
      try {
        word = jcomp.getDocument().getText(beg, end - beg);
      } catch (Exception ex) { }
      if (word == null) return;
      for (int i = 0, b, e; i < hls.length; ++i) {
        b = hls[i].getStartOffset();
        e = hls[i].getEndOffset();
        if (beg <= b && e >= end ) {
          hl.removeHighlight(hls[i]);
          return;
        }
      }
    } catch (Exception ex) { }
  } 
  public void mouseEntered(MouseEvent me) { } 
  public void mouseExited(MouseEvent me) { } 
  private JTextComponent jcomp;
}
The following little app shows you how CopyCutPaste works:
Java:
import javax.swing.*;
import java.awt.Font;
// Joe Nartca (C)
public class Test {
  public static void main(String... a) throws Exception {
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    new Test( );
  }
  public Test( ) throws Exception {
    JFrame jf = new JFrame("CopyCutTest");
    JTextField jtf = new JTextField(32);
    jtf.addMouseListener(new CopyCutPaste(jtf)); // <----CopyCutPaste for JTextField
    JTextArea jta = new JTextArea(100,5);
    jta.addMouseListener(new CopyCutPaste(jta)); // <----CopyCutPaste for JTextArea
    jta.setFont(new Font("Monospaced", Font.PLAIN, 12));
    JScrollPane jsp = new JScrollPane (jta,
                                       JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                       JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //
    jf.add("North", jtf);
    jf.add("Center", jsp);
    jf.setSize(400, 400);
    jf.setVisible(true);
  }
}
CopyCutPaste.png
Copy
CopyCutPaste_1.png
paste
CopyCutPaste_2.png
and the pasted text in JTextArea
Enjoy
Joe