swing 文本框简单右键菜单实现

用Java来做界面开发是难免而且带有些许尴尬的。而由于对C#的讨厌,我便常常处于这样的境地。
虽然Java不及C#或者MFC等通过拖曳组件来构造界面那般方便(据说Netbeans和eclipse的SWT亦支持拖曳组件来构造界面,但我已经习惯了eclipse和swing,因而没有尝试过),开发效率低,但是我仍然希望最后做出了的界面是体验良好的。
之前做了一个工具,需要用一个文本窗口来显示工具的运行日志,本可以直接通过Runtime来调用notepad完成此事,但由于日志文本数目巨大,因此需要在文本窗口载入文本内容后直接将滚动条移至最下,而notepad无法完成此事,于是带着追求完美和锻炼代码能力的心理自己写了个“notepad”。在以往所制作的java界面程序中,一直没有为文本框一类组件提供右键菜单支持,而这次搞自己的“notepad”,总不能仍然连个右键菜单都没有吧!所以趁此次机会,有了下面的结果...

简单的右键菜单实现:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;

/**
 * 简单文本操作右键菜单
 * @author Dancen
 *
 */
public class MyPopupMenu extends JPopupMenu implements MouseListener, ActionListener
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static MyPopupMenu instance = new MyPopupMenu();
	
    private JMenuItem cutItem;
    private JMenuItem copyItem;
    private JMenuItem pasteItem;
    private JMenuItem deleteItem;
    private JMenuItem selectAllItem;
    
    public static void main(String[] args)  
    {
    	System.out.println("Just for test ...");
    	
    	JFrame f = new JFrame();
    	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	
    	JTextField tf0 = new JTextField(10);
    	MyPopupMenu.installToTextComponent(tf0);
    	f.add(tf0, BorderLayout.CENTER);
    	
    	JTextField tf1 = new JTextField(10);
    	MyPopupMenu.installToTextComponent(tf1);
    	MyPopupMenu.installToTextComponent(tf1);
    	MyPopupMenu.uninstallFromTextComponent(tf1);
    	
    	f.add(tf1, BorderLayout.SOUTH);
    	
    	f.pack();
    	f.setLocationRelativeTo(null);
    	f.setVisible(true);
    }
    
    /**
     * 为文本组件添加右键菜单
     * @param textComponent
     * @return
     */
	public static boolean installToTextComponent(JTextComponent textComponent)
	{
		boolean isHasInstalled = false;
		MouseListener[] listeners = textComponent.getMouseListeners();
		
		if(null != listeners)
		{
			for(int i = 0; i < listeners.length; i++)
			{
				if(listeners[i] == MyPopupMenu.getInstance())
				{
					isHasInstalled = true;
				}
			}
		}
		
		if(!isHasInstalled)
		{
			textComponent.addMouseListener(MyPopupMenu.getInstance());
			
			return true;
		}
		
		return false;
	}
	
	/**
	 * 从文本组件移除右键菜单
	 * @param textComponent
	 */
	public static void uninstallFromTextComponent(JTextComponent textComponent)
	{
		textComponent.removeMouseListener(MyPopupMenu.getInstance());
	}

    private static MyPopupMenu getInstance()
    {
    	if(null == instance)
    	{
    		instance = new MyPopupMenu();
        }
    	
        return instance;
    }

    private MyPopupMenu()
    {
    	this.GUIInit();
    	this.dataInit();
    	this.listenerInit();
    }
    
    private void GUIInit()
    {
    	this.cutItem = new JMenuItem("剪切(T)");
    	this.copyItem = new JMenuItem("复制(C)");
    	this.pasteItem = new JMenuItem("粘贴(P)");
    	this.deleteItem = new JMenuItem("删除(D)");
    	this.selectAllItem = new JMenuItem("全选(A)");
    	
        this.cutItem.setMnemonic('T');
        this.copyItem.setMnemonic('C');
        this.pasteItem.setMnemonic('P');
        this.deleteItem.setMnemonic('D');
        this.selectAllItem.setMnemonic('A');
        
    	this.add(this.cutItem);
    	this.add(this.copyItem);
    	this.add(this.pasteItem);
    	this.add(this.deleteItem);
    	this.addSeparator();
    	this.add(this.selectAllItem);
    }
    
    private void dataInit()
    {
    	
    }
    
    private void listenerInit()
    {
    	this.cutItem.addActionListener(this);
    	this.copyItem.addActionListener(this);
    	this.pasteItem.addActionListener(this);
    	this.deleteItem.addActionListener(this);
    	this.selectAllItem.addActionListener(this);
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
    	if(e.isPopupTrigger() && e.getSource() instanceof JTextComponent)
    	{
    		JTextComponent textComponent = (JTextComponent) e.getSource();
    		
    		if(Boolean.TRUE.equals(textComponent.getClientProperty("DisablePopupMenu")))  
    		{
    			return;
    		}
            
    		textComponent.requestFocusInWindow();
    		this.show(textComponent, e.getX(), e.getY());
    	}
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {
    
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
    	
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
     
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
    
    }

    @Override
    public void show(Component invoker, int x, int y)
    {
        JTextComponent textComponent = (JTextComponent) invoker;
        String selectedText = textComponent.getSelectedText();

        boolean isTextAvailable = null != selectedText && !selectedText.equals("");
        boolean isEnabled = textComponent.isEnabled();
        boolean isEditable = textComponent.isEditable();
        boolean isPassword = textComponent instanceof JPasswordField;
        
        this.cutItem.setEnabled(isTextAvailable && isEnabled && isEditable && !isPassword);
        this.copyItem.setEnabled(isTextAvailable && isEnabled && !isPassword);
        this.deleteItem.setEnabled(isTextAvailable && isEnabled && isEditable);
        this.pasteItem.setEnabled(isEnabled && isEditable);
        this.selectAllItem.setEnabled(isEnabled);

        super.show(invoker, x, y);
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
    	JTextComponent textComponent = (JTextComponent) this.getInvoker();

    	if(e.getSource() == this.cutItem)
    	{
    		textComponent.cut();
    	}
    	else if(e.getSource() == this.copyItem)
    	{
    		textComponent.copy();
    	}
    	else if(e.getSource() == this.pasteItem) 
    	{
    		textComponent.paste();
    	}
    	else if(e.getSource() == this.selectAllItem) 
    	{
    		textComponent.selectAll();
    	}
    	else if(e.getSource() == this.deleteItem)
    	{
    		Document doc = textComponent.getDocument();
    		int start = textComponent.getSelectionStart();
    		int end = textComponent.getSelectionEnd();

    		try
    		{
    			Position p0 = doc.createPosition(start);
    			Position p1 = doc.createPosition(end);

    			if((null != p0) && (null != p1) && (p0.getOffset() != p1.getOffset()))
    			{
    				doc.remove(p0.getOffset(), p1.getOffset() - p0.getOffset());
    			}
    		}
    		catch(BadLocationException be)
    		{
    			be.printStackTrace();
    		}
    	}
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值