Reputation: 20595
I've discovered that when running a Java program in Mac OS X, text field objects (e.g. JField) support cut, copy, and paste operations using the system clipboard if you use the key commands without you having to do an extra coding. For instance, I can create a JField, type in some text, select it, and then use "Command-C" to copy it, then paste it in another application. The same works for pasting text copied from other applications.
I really like that Java does this automatically, but I notice that the Edit menu doesn't appear automatically with the cut, copy, and paste menu items. Is there any way to automatically add these menu items for accessing the system clipboard when text is selected? If not, what's the best way to implement them so that it behaves like any other application. At this point, I'm only interested in copy and pasting text.
Also, I know that the system clipboard is platform specific. Does this automatic system clipboard functionality for text field objects occur on other platforms?
EDIT: I was actually wanting to know about adding this to the menu bar, but there wound up being such a great answer to the next question I would have had that I decided that I'd select it as the right answer and rename the question.
Upvotes: 2
Views: 1074
Reputation: 32153
This has worked for me:
public class MyTextField extends JTextField {
public static final MyPopupMenu POPUP_MENU = new MyPopupMenu();
public MyTextField() {
this.setComponentPopupMenu(POPUP_MENU);
}
}
Now, I just use MyTextField
everywhere I would otherwise use a JTextField
.
Upvotes: 0
Reputation: 28707
You will need to create a custom popup menu for this, which can be done utilizing MouseListener (or MouseAdapter) and a JPopupMenu. My approach would be to create a custom mouse listener which you can add to any text component.
public class ClipboardMenuHandler extends MouseAdapter {
private final JTextComponent textComponent;
public ClipboardMenuHandler(JTextComponent textComponent) {
this.textComponent = textComponent;
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.isPopupTrigger())
ClipboardMenu menu = new ClipboardMenu();
menu.show(textComponent, e.getX(), e.getY());
}
}
private class ClipboardMenu extends JPopupMenu {
public ClipboardMenu() {
// add copy/cut/paste actions; refer to Ted's answer for PasteAction
}
}
}
Then, you just add a ClipboardMenuHandler
as a listener to your text component.
JTextField field = new JTextField();
ClipboardMenuHandler menuHandler = new ClipboardMenuHandler(field);
field.addMouseListener(menuHandler);
Upvotes: 1
Reputation: 234857
Unfortunately, Swing does not support pop-up context menus. You have to roll your own. Fortunately, this isn't too hard. Perhaps the cleanest approach is to install your own event queue, as described here. That article suggests the following implementation:
// @author Santhosh Kumar T - [email protected]
public class MyEventQueue extends EventQueue{
protected void dispatchEvent(AWTEvent event){
super.dispatchEvent(event);
// interested only in mouseevents
if(!(event instanceof MouseEvent))
return;
MouseEvent me = (MouseEvent)event;
// interested only in popuptriggers
if(!me.isPopupTrigger())
return;
// me.getComponent(...) retunrs the heavy weight component on which event occured
Component comp = SwingUtilities.getDeepestComponentAt(me.getComponent(), me.getX(), me.getY());
// interested only in textcomponents
if(!(comp instanceof JTextComponent))
return;
// no popup shown by user code
if(MenuSelectionManager.defaultManager().getSelectedPath().length>0)
return;
// create popup menu and show
JTextComponent tc = (JTextComponent)comp;
JPopupMenu menu = new JPopupMenu();
menu.add(new CutAction(tc));
menu.add(new CopyAction(tc));
menu.add(new PasteAction(tc));
menu.add(new DeleteAction(tc));
menu.addSeparator();
menu.add(new SelectAllAction(tc));
Point pt = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(), tc);
menu.show(tc, pt.x, pt.y);
}
}
You then use this with:
public static void main(String[] args){
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new MyEventQueue());
.....
}
With that one line of code, you get a pop-up menu on every text component in your application.
The actions classes aren't too complicated. For instance, here's the implementation of the paste action, which shows interaction with the system clipboard:
// @author Santhosh Kumar T - [email protected]
class PasteAction extends AbstractAction{
JTextComponent comp;
public PasteAction(JTextComponent comp){
super("Paste");
this.comp = comp;
}
public void actionPerformed(ActionEvent e){
comp.paste();
}
public boolean isEnabled(){
if (comp.isEditable() && comp.isEnabled()){
Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);
return contents.isDataFlavorSupported(DataFlavor.stringFlavor);
}else
return false;
}
}
See the article for code for the other action implementations.
Upvotes: 2