在很多軟件中每個文本組件都有自定義的菜單,這個blogjava的編輯器就有這樣的菜單如:Cut , Copy,Paste,Delete,Select All,在Swing中若也想在JTextField,JTextArea,JEditorPane,JTextPane等等這些組件中都提供如此自定義菜單的功能,每個都寫繼承類?或者加鼠標監聽事件?但不管怎樣弄都會實現效果,只不過這樣動靜很大,不好維護,今天在網上看到一個很是方便的方法。
大家都知道,Swing中所有的事件都是進入java.awt.EventQueue這個隊列中等待,然后通過dispatchEvent方法進行派發,那么我們在這里就寫個繼承EventQueue這個類,攔截所有的事件并對其進行處理,我們的文本組件都是繼承與JTextComponent的,那么到這里我們就能為所有的文本組件定制一致的菜單了。效果如:
見代碼:
package org.kissjava.swingx.core;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.JPopupMenu;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;


public class KJEventQueue extends EventQueue
{
@Override

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);
}

class CutAction extends AbstractAction
{
JTextComponent comp;

public CutAction(JTextComponent comp)
{
super("Cut");
this.comp = comp;
}

public void actionPerformed(ActionEvent e)
{
comp.cut();
}

public boolean isEnabled()
{
return comp.isEditable()
&& comp.isEnabled()
&& comp.getSelectedText()!=null;
}
}
// @author Santhosh Kumar T - santhosh@in.fiorano.com

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;
}
}
// @author Santhosh Kumar T - santhosh@in.fiorano.com

class DeleteAction extends AbstractAction
{
JTextComponent comp;

public DeleteAction(JTextComponent comp)
{
super("Delete");
this.comp = comp;
}

public void actionPerformed(ActionEvent e)
{
comp.replaceSelection(null);
}

public boolean isEnabled()
{
return comp.isEditable()
&& comp.isEnabled()
&& comp.getSelectedText()!=null;
}
}
// @author Santhosh Kumar T - santhosh@in.fiorano.com

class CopyAction extends AbstractAction
{
JTextComponent comp;

public CopyAction(JTextComponent comp)
{
super("Copy");
this.comp = comp;
}

public void actionPerformed(ActionEvent e)
{
comp.copy();
}

public boolean isEnabled()
{
return comp.isEnabled()
&& comp.getSelectedText()!=null;
}
}
// @author Santhosh Kumar T - santhosh@in.fiorano.com

class SelectAllAction extends AbstractAction
{
JTextComponent comp;

public SelectAllAction(JTextComponent comp)
{
super("Select All");
this.comp = comp;
}

public void actionPerformed(ActionEvent e)
{
comp.selectAll();
}

public boolean isEnabled()
{
return comp.isEnabled()
&& comp.getText().length()>0;
}
}
}

到這里我們如何使用這個類呢?也很簡單,只要在主程序的入口處加上下面這句就行了:
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new KJEventQueue());
也就是在main方法中調用,如:

public static void main(String[] args)
{
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new KJEventQueue());
// TODO Auto-generated method stub

SwingUtilities.invokeLater(new Runnable()
{

public void run()
{
new KJEventQuequeDemo();
}
});
}
資料來源:http://www.jroller.com/santhosh/entry/context_menu_for_textcomponents