实现思路:
定义了个快捷键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); } }
原文地址:http://blog.csdn.net/fswan/article/details/24701453