1 19 20 package org.netbeans.modules.editor.hints.borrowed; 21 22 23 import java.awt.Color ; 24 import java.awt.Dimension ; 25 import java.awt.event.KeyEvent ; 26 27 import javax.swing.*; 28 import javax.swing.BorderFactory ; 29 import javax.swing.event.ListSelectionListener ; 30 import javax.swing.plaf.TextUI ; 31 import javax.swing.text.JTextComponent ; 32 import javax.swing.text.Keymap ; 33 import javax.swing.text.EditorKit ; 34 35 import org.netbeans.editor.*; 36 import org.netbeans.editor.ext.ExtSettingsDefaults; 37 import org.netbeans.editor.ext.ExtSettingsNames; 38 import org.netbeans.spi.editor.hints.Fix; 39 import org.netbeans.spi.editor.hints.LazyFixList; 40 41 48 49 public class ScrollCompletionPane extends JScrollPane implements SettingsChangeListener { 50 51 private static final String COMPLETION_UP = "completion-up"; private static final String COMPLETION_DOWN = "completion-down"; private static final String COMPLETION_PGUP = "completion-pgup"; private static final String COMPLETION_PGDN = "completion-pgdn"; private static final String COMPLETION_BEGIN = "completion-begin"; private static final String COMPLETION_END = "completion-end"; 58 private static final int ACTION_COMPLETION_UP = 1; 59 private static final int ACTION_COMPLETION_DOWN = 2; 60 private static final int ACTION_COMPLETION_PGUP = 3; 61 private static final int ACTION_COMPLETION_PGDN = 4; 62 private static final int ACTION_COMPLETION_BEGIN = 5; 63 private static final int ACTION_COMPLETION_END = 6; 64 65 private JTextComponent component; 66 67 private ListCompletionView view; 68 private JLabel topLabel; 69 70 private Dimension minSize; 71 private Dimension maxSize; 72 private Dimension scrollBarSize; 73 74 public ScrollCompletionPane(JTextComponent component, LazyFixList fixes, String title, ListSelectionListener listener) { 75 this.component = component; 76 77 Dimension smallSize = super.getPreferredSize(); 79 setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER); 80 setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS); 81 scrollBarSize = super.getPreferredSize(); 82 scrollBarSize.width -= smallSize.width; 83 scrollBarSize.height -= smallSize.height; 84 setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED); 85 setBorder( 86 BorderFactory.createCompoundBorder( 87 BorderFactory.createLineBorder(java.awt.SystemColor.controlDkShadow), 88 BorderFactory.createEmptyBorder(4, 4, 4, 4))); 89 setViewportBorder( null ); 90 Settings.addSettingsChangeListener(this); 91 settingsChange(null); 93 view = new ListCompletionView(); 95 setBackground(view.getBackground()); 96 view.setResult(fixes); 98 resetViewSize(); 99 setViewportView(view); 100 101 setTitle(title); 102 installKeybindings(); 103 setFocusable (false); 104 view.setFocusable (false); 105 } 106 107 public ListCompletionView getView() { 108 return view; 109 } 110 111 public void reset(LazyFixList fixes, String title) { 112 view.setResult(fixes); 113 resetViewSize(); 114 setTitle(title); 115 } 116 117 public Fix getSelectedFix() { 118 Object ret = view.getSelectedValue(); 119 return ret instanceof Fix ? (Fix) ret : null; 120 } 121 122 public void settingsChange(SettingsChangeEvent evt) { 123 Class kitClass = Utilities.getKitClass(component); 124 if (kitClass != null) { 125 minSize = (Dimension )SettingsUtil.getValue(kitClass, 126 ExtSettingsNames.COMPLETION_PANE_MIN_SIZE, 127 ExtSettingsDefaults.defaultCompletionPaneMinSize); 128 setMinimumSize(minSize); 129 130 maxSize = (Dimension )SettingsUtil.getValue(kitClass, 131 ExtSettingsNames.COMPLETION_PANE_MAX_SIZE, 132 ExtSettingsDefaults.defaultCompletionPaneMaxSize); 133 setMaximumSize(maxSize); 134 } 135 } 136 137 public Dimension getPreferredSize() { 138 Dimension ps = super.getPreferredSize(); 139 140 142 int width = ps.width + scrollBarSize.width; 143 boolean displayHorizontalScrollbar = width > maxSize.width; 144 width = Math.max(Math.max(width, minSize.width), 145 getTitleComponentPreferredSize().width); 146 width = Math.min(width, maxSize.width); 147 148 int height = displayHorizontalScrollbar ? ps.height + scrollBarSize.height : ps.height; 149 height = Math.min(height, maxSize.height); 150 height = Math.max(height, minSize.height); 151 return new Dimension (width, height); 152 } 153 154 private void resetViewSize() { 155 Dimension viewSize = view.getPreferredSize(); 156 if (viewSize.width > maxSize.width - scrollBarSize.width) { 157 viewSize.width = maxSize.width - scrollBarSize.width; 158 view.setPreferredSize(viewSize); 159 } 160 } 161 162 private void setTitle(String title) { 163 if (title == null) { 164 if (topLabel != null) { 165 setColumnHeader(null); 166 topLabel = null; 167 } 168 } else { 169 if (topLabel != null) { 170 topLabel.setText(title); 171 } else { 172 topLabel = new JLabel(title); 173 topLabel.setForeground(Color.blue); 174 topLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); 175 setColumnHeaderView(topLabel); 176 } 177 } 178 } 179 180 private Dimension getTitleComponentPreferredSize() { 181 return topLabel != null ? topLabel.getPreferredSize() : new Dimension (); 182 } 183 184 185 private KeyStroke[] findEditorKeys(String editorActionName, KeyStroke defaultKey) { 186 KeyStroke[] ret = new KeyStroke[] { defaultKey }; 189 if (component != null) { 190 TextUI ui = component.getUI(); 191 Keymap km = component.getKeymap(); 192 if (ui != null && km != null) { 193 EditorKit kit = ui.getEditorKit(component); 194 if (kit instanceof BaseKit) { 195 Action a = ((BaseKit)kit).getActionByName(editorActionName); 196 if (a != null) { 197 KeyStroke[] keys = km.getKeyStrokesForAction(a); 198 if (keys != null && keys.length > 0) { 199 ret = keys; 200 } 201 } 202 } 203 } 204 } 205 return ret; 206 } 207 208 private void registerKeybinding(int action, String actionName, KeyStroke stroke, String editorActionName){ 209 KeyStroke[] keys = findEditorKeys(editorActionName, stroke); 210 for (int i = 0; i < keys.length; i++) { 211 getInputMap().put(keys[i], actionName); 212 } 213 getActionMap().put(actionName, new CompletionPaneAction(action)); 214 } 215 216 private void installKeybindings() { 217 registerKeybinding(ACTION_COMPLETION_UP, COMPLETION_UP, 219 KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), 220 BaseKit.upAction 221 ); 222 223 registerKeybinding(ACTION_COMPLETION_DOWN, COMPLETION_DOWN, 225 KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), 226 BaseKit.downAction 227 ); 228 229 registerKeybinding(ACTION_COMPLETION_PGDN, COMPLETION_PGDN, 231 KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), 232 BaseKit.pageDownAction 233 ); 234 235 registerKeybinding(ACTION_COMPLETION_PGUP, COMPLETION_PGUP, 237 KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), 238 BaseKit.pageUpAction 239 ); 240 241 registerKeybinding(ACTION_COMPLETION_BEGIN, COMPLETION_BEGIN, 243 KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), 244 BaseKit.beginLineAction 245 ); 246 247 registerKeybinding(ACTION_COMPLETION_END, COMPLETION_END, 249 KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), 250 BaseKit.endLineAction 251 ); 252 } 253 254 private class CompletionPaneAction extends AbstractAction { 255 private int action; 256 257 private CompletionPaneAction(int action) { 258 this.action = action; 259 } 260 261 public void actionPerformed(java.awt.event.ActionEvent actionEvent) { 262 switch (action) { 263 case ACTION_COMPLETION_UP: 264 view.up(); 265 break; 266 case ACTION_COMPLETION_DOWN: 267 view.down(); 268 break; 269 case ACTION_COMPLETION_PGUP: 270 view.pageUp(); 271 break; 272 case ACTION_COMPLETION_PGDN: 273 view.pageDown(); 274 break; 275 case ACTION_COMPLETION_BEGIN: 276 view.begin(); 277 break; 278 case ACTION_COMPLETION_END: 279 view.end(); 280 break; 281 } 282 } 283 } 284 } 285 | Popular Tags |