1 package org.antlr.works.idea; 2 3 import org.antlr.xjlib.appkit.frame.XJFrameInterface; 4 import org.antlr.works.components.grammar.CEditorGrammar; 5 import org.antlr.works.utils.IconManager; 6 import org.antlr.works.utils.OverlayObject; 7 8 import javax.swing.*; 9 import javax.swing.border.BevelBorder ; 10 import java.awt.*; 11 import java.awt.event.*; 12 import java.awt.font.TextLayout ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 45 46 public class IdeaOverlay extends OverlayObject { 47 48 protected static final int VISIBLE_IDEAS = 10; 49 50 protected CEditorGrammar editor; 51 protected DefaultListModel ideasModel; 52 protected JList ideasList; 53 protected JScrollPane ideasScrollPane; 54 protected JToggleButton ideaButton; 55 56 protected List <IdeaAction> ideas; 57 58 public IdeaOverlay(CEditorGrammar editor, XJFrameInterface parentFrame, JComponent parentComponent) { 59 super(parentFrame, parentComponent); 60 this.editor = editor; 61 } 62 63 public void setIdeas(List <IdeaAction> ideas) { 64 this.ideas = ideas; 65 } 66 67 public JComponent overlayCreateInterface() { 68 JPanel panel = new JPanel(new BorderLayout()); 69 panel.setOpaque(false); 70 71 ideaButton = new JToggleButton(); 72 ideaButton.setIcon(IconManager.shared().getIconIdea()); 73 74 ideaButton.setContentAreaFilled(false); 75 ideaButton.setBorder(null); 76 77 ideaButton.setFocusable(false); 78 ideaButton.addActionListener(new IdeaActionListener()); 79 ideaButton.setToolTipText("Click to display ideas"); 80 81 ideaButton.addMouseListener(new MouseAdapter() { 82 public void mouseEntered(MouseEvent e) { 83 ideaButton.setBorder(BorderFactory.createLineBorder(Color.darkGray)); 84 } 85 86 public void mouseExited(MouseEvent e) { 87 if(ideaButton.isSelected()) 88 return; 89 90 ideaButton.setBorder(null); 91 } 92 93 }); 94 95 panel.add(ideaButton, BorderLayout.CENTER); 96 97 ideasModel = new DefaultListModel(); 98 99 ideasList = new JList(ideasModel); 100 ideasList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 101 ideasList.setBackground(new Color(235, 244, 254)); 102 ideasList.setPrototypeCellValue("This is a rule name g"); 103 ideasList.addKeyListener(new ListKeyAdapter()); 104 ideasList.addMouseListener(new ListMouseAdapter()); 105 ideasList.addMouseMotionListener(new ListMouseMotionAdapter()); 106 107 ideasScrollPane = new JScrollPane(ideasList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 108 ideasScrollPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); 109 ideasScrollPane.setVisible(false); 110 parentFrame.getLayeredPane().add(ideasScrollPane, JLayeredPane.MODAL_LAYER); 111 112 return panel; 113 } 114 115 public int overlayDefaultWidth() { 116 return 20; 117 } 118 119 public int overlayDefaultHeight() { 120 return 20; 121 } 122 123 public int overlayDefaultAlignment() { 124 return ALIGN_CUSTOM; 125 } 126 127 public Point overlayCustomPosition() { 128 Point lp = editor.getTextEditor().getLineTextPositionsAtTextPosition(editor.getCaretPosition()); 129 130 int cx = 0; 131 int y = 0; 132 try { 133 y = editor.getTextPane().modelToView(lp.y).y; 134 cx = editor.getTextPane().modelToView(editor.getCaretPosition()).x; 135 } catch (Exception e) { 136 } 138 139 Point anchor = new Point(0, 0); 140 if(cx < 50) 141 anchor.x += 50; 142 143 Point p = SwingUtilities.convertPoint(parentComponent, anchor, parentFrame.getRootPane()); 144 return new Point(p.x + 5, p.y + y); 145 } 146 147 public void hide() { 148 super.hide(); 149 ideasScrollPane.setVisible(false); 150 } 151 152 public void resize() { 153 super.resize(); 154 resizeIdeas(); 155 } 156 157 public void resizeIdeas() { 158 Rectangle r = content.getBounds(); 159 int height = ideasList.getFixedCellHeight(); 160 int size = ideasModel.size(); 161 if(size > 0) { 162 int width = 0; 163 for(int i=0; i<ideasModel.size(); i++) { 164 IdeaAction action = (IdeaAction)ideasModel.getElementAt(i); 165 TextLayout layout = new TextLayout (action.name, ideasList.getFont(), ((Graphics2D)ideasList.getGraphics()).getFontRenderContext()); 166 width = Math.max(width, (int)layout.getBounds().getWidth()); 167 } 168 height = height*Math.min(VISIBLE_IDEAS, size)+5; 169 ideasScrollPane.setBounds(r.x, r.y+r.height, width+10, height); 170 } 171 } 172 173 public void updateIdeasList() { 174 ideasModel.clear(); 175 for(Iterator <IdeaAction> iter = ideas.iterator(); iter.hasNext();) { 176 ideasModel.addElement(iter.next()); 177 } 178 ideasList.setSelectedIndex(0); 179 } 180 181 public boolean overlayWillDisplay() { 182 updateIdeasList(); 183 ideaButton.setSelected(false); 184 ideaButton.setBorder(null); 185 return true; 186 } 187 188 public void applyIdea(int index) { 189 IdeaAction action = ideas.get(index); 190 action.run(); 191 } 192 193 public class IdeaActionListener implements ActionListener { 194 195 public void actionPerformed(ActionEvent e) { 196 ideasScrollPane.setVisible(ideaButton.isSelected()); 197 } 198 } 199 200 public class ListMouseMotionAdapter extends MouseMotionAdapter { 201 public void mouseMoved(MouseEvent e) { 202 ideasList.setSelectedIndex(ideasList.locationToIndex(e.getPoint())); 203 } 204 } 205 206 public class ListMouseAdapter extends MouseAdapter { 207 public void mousePressed(MouseEvent e) { 208 applyIdea(ideasList.getSelectedIndex()); 209 hide(); 210 } 211 } 212 213 public class ListKeyAdapter extends KeyAdapter { 214 215 public void selectNextListElement(int direction) { 216 int index = ideasList.getSelectedIndex(); 217 index += direction; 218 index = Math.min(Math.max(0, index), ideasModel.size()-1); 219 220 ideasList.setSelectedIndex(index); 221 ideasList.scrollRectToVisible(ideasList.getCellBounds(index, index)); 222 } 223 224 public void keyPressed(KeyEvent e) { 225 if(e.isConsumed()) 226 return; 227 228 if(!content.isVisible()) 229 return; 230 231 switch(e.getKeyCode()) { 232 case KeyEvent.VK_ESCAPE: 233 hide(); 234 e.consume(); 235 break; 236 237 case KeyEvent.VK_ENTER: 238 applyIdea(ideasList.getSelectedIndex()); 239 hide(); 240 e.consume(); 241 break; 242 243 case KeyEvent.VK_UP: 244 selectNextListElement(-1); 245 e.consume(); 246 break; 247 248 case KeyEvent.VK_DOWN: 249 selectNextListElement(1); 250 e.consume(); 251 break; 252 } 253 } 254 } 255 256 } 257 | Popular Tags |