首页 > 代码库 > swing实现代码助手功能

swing实现代码助手功能

实现思路:

定义了个快捷键ctrl+/ ,当按此键时,会出现一个弹出窗口,采用JWINDOW来实现。

选择代码段便用了JList来实现。

下面直接上代码。


package org.swan.mybatis.ui.common;

import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;

@SuppressWarnings("serial")
public class MyCodeAssistant extends JDialog{
	/**
	 * 代码填充后,把光标直接定义到此位置
	 */
	public static final String CURSOR = "&CURSOR;";
	
	public static final String SELECT = "$0";
	
	JTextComponent component;
	JWindow tipWin = null;
	private JList<ReplacePair> list = new JList<>(new DefaultListModel<ReplacePair>());
	public void bind(final JTextComponent component,final Window window)
	{
		this.tipWin =new JWindow(window);
		list.setCellRenderer(new InnerListCellRenderer());
		list.setBackground(new Color(255,255,220));
		tipWin.getContentPane().add(new JScrollPane(list));
		tipWin.setSize(400, 200);
		tipWin.addFocusListener(new FocusListener() {
			@Override
			public void focusLost(FocusEvent e) {
				tipWin.setVisible(false);
			}
			@Override
			public void focusGained(FocusEvent e) {
			}
		});
		list.getInputMap().put(KeyStroke.getKeyStroke((char)KeyEvent.VK_ENTER), "keyenter");
		list.getInputMap().put(KeyStroke.getKeyStroke((char)KeyEvent.VK_ESCAPE), "esc");
		list.getActionMap().put("keyenter", new SelectTip(list));
		list.getActionMap().put("esc",new CloseTip());
		this.component = component;
		ActionMap map = component.getActionMap();
		InputMap im = component.getInputMap();
		im.put(KeyStroke.getKeyStroke(‘/‘,InputEvent.ALT_MASK), "tip");
		map.put("tip", new ShowTip());
		map.put("tipesc", new CloseTip());
		map.put("tipup", new TipUpper(list));
		map.put("tipdown", new TipDown(list));
		map.put("tipenter", new SelectTip(list));
	}
	
	public static ReplacePair newPair(String pattern,String value)
	{
		return new ReplacePair(pattern, value);
	}
	
	public void setStringList(List<String> list)
	{
		((DefaultListModel<ReplacePair>)this.list.getModel()).clear();
		for (String string : list) {
			((DefaultListModel<ReplacePair>)this.list.getModel()).addElement(new ReplacePair("^.*$", string));
		}
	}
	
	public void addString(String str)
	{
		((DefaultListModel<ReplacePair>)list.getModel()).addElement(new ReplacePair("^.*$",str));
	}
	
	public void setList(List<ReplacePair> list)
	{
		this.list.setListData(list.toArray(new ReplacePair[0]));
	}
	public void addList(ReplacePair pair)
	{
		((DefaultListModel<ReplacePair>)(list.getModel())).addElement(pair);
	}
	
	class CloseTip extends AbstractAction
	{
		@Override
		public void actionPerformed(ActionEvent e) {
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
			tipWin.setVisible(false);
		}
	}

	class ShowTip extends AbstractAction {
		@Override
		public void actionPerformed(ActionEvent e) {
			Point p1 = component.getLocationOnScreen();
			Point p2 = component.getCaret().getMagicCaretPosition();
			if(p2==null)
				p2 = new Point(0,0);
			p1.translate(p2.x, p2.y);
			p1.translate(0,component.getFont().getSize()+3);
			tipWin.setLocation(p1);
			list.setSelectedIndex(0);
			component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),"tipesc");
			component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0),"tipup");
			component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0),"tipdown");
			component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"tipenter");
			tipWin.setVisible(true);
			component.requestFocus();
		}
	}
	
	class SelectTip extends AbstractAction {
		private JList<ReplacePair> list;
		public SelectTip(JList<ReplacePair> list)
		{
			this.list = list;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			ReplacePair selectPair = list.getSelectedValue();
			String selectStr = "";
			if(selectPair == null)
			{
				if(list.getModel().getSize()>0)
					selectPair = list.getModel().getElementAt(0);
				else
					return;
			}
			
			selectStr = getPairString(selectPair);
			
			int offset = selectStr.length();
			if(selectStr.indexOf(CURSOR)!=-1)//处理光标问题
			{
				offset = selectStr.indexOf(CURSOR);
				selectStr = selectStr.replaceAll(CURSOR, "");
			}
			Caret caret = component.getCaret();
			StringBuilder sb = new StringBuilder(component.getText());
			int pos = caret.getDot();
			if(component.getSelectedText()!=null)
			{
				pos = component.getSelectionStart();
				sb.replace(component.getSelectionStart(), component.getSelectionEnd(), selectStr);
			}else
				sb.insert(pos, selectStr);
			component.setText(sb.toString());
			caret.setDot(pos + offset);
			tipWin.setVisible(false);
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0));
			component.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
		}
	}
	
	class TipUpper extends AbstractAction {
		private JList<ReplacePair> list;
		public TipUpper(JList<ReplacePair> list)
		{
			this.list = list;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			int pos = list.getSelectedIndex();
			if (list.getModel().getSize() > 0) {
				if (pos > 0)
					list.setSelectedIndex(pos - 1);
				else {
					list.setSelectedIndex(list.getModel().getSize() - 1);
				}
			}
		}
	}
	class TipDown extends AbstractAction {
		private JList<ReplacePair> list;
		public TipDown(JList<ReplacePair> list)
		{
			this.list = list;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			int pos = list.getSelectedIndex();
			if (list.getModel().getSize() > 0) {
				if (pos < list.getModel().getSize() - 1)
					list.setSelectedIndex(pos + 1);
				else
					list.setSelectedIndex(0);
			}
		}
	}
	
	private String getPairString(ReplacePair v) {
		String disLabel = "";
		if(v.getTarget()!=null)
		{
			String tmpStr = component.getSelectedText();
			if(tmpStr == null) tmpStr = "";
			disLabel = tmpStr.replaceAll(v.getPattern(), v.getTarget());
		}
		return disLabel;
	}
	
	class InnerListCellRenderer extends DefaultListCellRenderer
	{
		@Override
		public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			ReplacePair v = (ReplacePair)value;
			String disLabel= "";
			disLabel = getPairString(v);
			disLabel = disLabel.replaceAll(CURSOR, "");
			if(disLabel.equals(""))
				disLabel = " ";
			Component component =  super.getListCellRendererComponent(list, disLabel, index, isSelected, cellHasFocus);
			if(component instanceof JLabel)
				((JLabel)component).setToolTipText(disLabel);
			return component;
		}
	}
	
	static class ReplacePair
	{
		private String pattern;
		private String target;
		protected ReplacePair(String pattern, String target) {
			this.pattern = pattern;
			this.target = target;
		}
		public String getPattern() {
			return pattern;
		}
		public void setPattern(String pattern) {
			this.pattern = pattern;
		}
		public String getTarget() {
			return target;
		}
		public void setTarget(String target) {
			this.target = target;
		}
	}
	
	public static void main(String[] args) {
		JFrame jf = new JFrame();
		jf.setSize(400,400);
		JTextArea ta = new JTextArea();
		jf.add(ta);
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		MyCodeAssistant myAssistant= new MyCodeAssistant();
		myAssistant.bind(ta,jf);
		List<String> list = new ArrayList<String>();
		list.add("333333333");
		list.add("11"+MyCodeAssistant.CURSOR+"11");
		list.add("222"+MyCodeAssistant.SELECT+"2222"+MyCodeAssistant.CURSOR+"22");
		list.add("12"+MyCodeAssistant.SELECT+"3456"+MyCodeAssistant.CURSOR+"789");
		ReplacePair pair = new MyCodeAssistant.ReplacePair("(.*)\\s(.*)", "$2    $1");
		
		myAssistant.setStringList(list);
		myAssistant.addList(pair);
	}
}