1 19 20 package org.netbeans.modules.apisupport.project.ui.customizer; 21 22 import java.awt.Color ; 23 import java.awt.EventQueue ; 24 import java.awt.event.ActionEvent ; 25 import java.net.URL ; 26 import java.util.Iterator ; 27 import java.util.Locale ; 28 import java.util.Set ; 29 import javax.swing.AbstractAction ; 30 import javax.swing.Action ; 31 import javax.swing.ActionMap ; 32 import javax.swing.InputMap ; 33 import javax.swing.JComponent ; 34 import javax.swing.JPanel ; 35 import javax.swing.KeyStroke ; 36 import javax.swing.event.DocumentEvent ; 37 import javax.swing.event.ListSelectionEvent ; 38 import javax.swing.event.ListSelectionListener ; 39 import javax.swing.text.BadLocationException ; 40 import javax.swing.text.Style ; 41 import javax.swing.text.StyleConstants ; 42 import javax.swing.text.StyledDocument ; 43 import org.netbeans.modules.apisupport.project.Util; 44 import org.netbeans.modules.apisupport.project.ui.UIUtil; 45 import org.netbeans.modules.apisupport.project.universe.NbPlatform; 46 import org.openide.ErrorManager; 47 import org.openide.awt.HtmlBrowser; 48 import org.openide.util.Mutex; 49 import org.openide.util.NbBundle; 50 import org.openide.util.RequestProcessor; 51 52 59 public final class AddModulePanel extends JPanel { 60 61 private static final String FILTER_DESCRIPTION = getMessage("LBL_FilterDescription"); 62 63 private CustomizerComponentFactory.DependencyListModel universeModules; 64 private RequestProcessor.Task filterTask; 65 private AddModuleFilter filterer; 66 private URL currectJavadoc; 67 68 private final SingleModuleProperties props; 69 70 public AddModulePanel(final SingleModuleProperties props) { 71 this.props = props; 72 initComponents(); 73 initAccessibility(); 74 filterValue.setText(FILTER_DESCRIPTION); 75 fillUpUniverseModules(); 76 moduleList.setCellRenderer(CustomizerComponentFactory.getDependencyCellRenderer(false)); 77 moduleList.addListSelectionListener(new ListSelectionListener () { 78 public void valueChanged(ListSelectionEvent e) { 79 showDescription(); 80 currectJavadoc = null; 81 ModuleDependency[] deps = getSelectedDependencies(); 82 if (deps.length == 1) { 83 NbPlatform platform = props.getActivePlatform(); 84 if (platform == null) { currectJavadoc = Util.findJavadocForNetBeansOrgModules(deps[0]); 86 } else { 87 currectJavadoc = Util.findJavadoc(deps[0], platform); 88 } 89 } 90 showJavadocButton.setEnabled(currectJavadoc != null); 91 } 92 }); 93 filterValue.getDocument().addDocumentListener(new UIUtil.DocumentAdapter() { 94 public void insertUpdate(DocumentEvent e) { 95 if (!FILTER_DESCRIPTION.equals(filterValue.getText())) { 96 search(); 97 } 98 } 99 }); 100 String [][] listNavCommands = { 102 { "selectPreviousRow", "selectPreviousRow" }, { "selectNextRow", "selectNextRow" }, { "selectFirstRow", "selectFirstRow" }, { "selectLastRow", "selectLastRow" }, { "scrollUp", "scrollUp" }, { "scrollDown", "scrollDown" }, }; 109 String [][] areaNavCommands = { 110 { "selection-page-up", "page-up" }, { "selection-page-down", "page-down" }, { "selection-up", "caret-up" }, { "selection-down", "caret-down" }, }; 115 exchangeCommands(listNavCommands, moduleList, filterValue); 116 exchangeCommands(areaNavCommands, descValue, filterValue); 117 } 118 119 private static void exchangeCommands(String [][] commandsToExchange, 120 final JComponent target, final JComponent source) { 121 InputMap targetBindings = target.getInputMap(); 122 KeyStroke [] targetBindingKeys = targetBindings.allKeys(); 123 ActionMap targetActions = target.getActionMap(); 124 InputMap sourceBindings = source.getInputMap(); 125 ActionMap sourceActions = source.getActionMap(); 126 for (int i = 0; i < commandsToExchange.length; i++) { 127 String commandFrom = commandsToExchange[i][0]; 128 String commandTo = commandsToExchange[i][1]; 129 final Action orig = targetActions.get(commandTo); 130 if (orig == null) { 131 continue; 132 } 133 sourceActions.put(commandTo, new AbstractAction () { 134 public void actionPerformed(ActionEvent e) { 135 orig.actionPerformed(new ActionEvent (target, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers())); 136 } 137 }); 138 for (int j = 0; j < targetBindingKeys.length; j++) { 139 if (targetBindings.get(targetBindingKeys[j]).equals(commandFrom)) { 140 sourceBindings.put(targetBindingKeys[j], commandTo); 141 } 142 } 143 } 144 } 145 146 private void fillUpUniverseModules() { 147 filterValue.setEnabled(false); 148 moduleList.setEnabled(false); 149 showNonAPIModules.setEnabled(false); 150 final String lastFilter = filterValue.getText(); 151 filterValue.setText(CustomizerComponentFactory.WAIT_VALUE); 152 moduleList.setModel(CustomizerComponentFactory.createListWaitModel()); 153 final boolean nonApiDeps = showNonAPIModules.isSelected(); 154 ModuleProperties.RP.post(new Runnable () { 155 public void run() { 156 final Set universeDeps = props.getUniverseDependencies(true, !nonApiDeps); 157 EventQueue.invokeLater(new Runnable () { 158 public void run() { 159 universeModules = CustomizerComponentFactory.createSortedDependencyListModel(universeDeps); 160 filterer = null; 161 moduleList.setModel(universeModules); 162 moduleList.setEnabled(true); 163 filterValue.setEnabled(true); 164 showNonAPIModules.setEnabled(true); 165 filterValue.setText(lastFilter); 166 if (!FILTER_DESCRIPTION.equals(lastFilter)) { 167 search(); 168 } else { 169 filterValue.selectAll(); 170 } 171 filterValue.requestFocusInWindow(); 172 } 173 }); 174 } 175 }); 176 } 177 178 private void showDescription() { 179 StyledDocument doc = descValue.getStyledDocument(); 180 try { 181 doc.remove(0, doc.getLength()); 182 ModuleDependency[] deps = getSelectedDependencies(); 183 if (deps.length != 1) { 184 return; 185 } 186 String longDesc = deps[0].getModuleEntry().getLongDescription(); 187 if (longDesc != null) { 188 doc.insertString(0, longDesc, null); 189 } 190 String filterText = filterValue.getText().trim(); 191 if (filterText.length() != 0 && !FILTER_DESCRIPTION.equals(filterText)) { 192 doc.insertString(doc.getLength(), "\n\n", null); Style bold = doc.addStyle(null, null); 194 bold.addAttribute(StyleConstants.Bold, Boolean.TRUE); 195 doc.insertString(doc.getLength(), getMessage("TEXT_matching_filter_contents"), bold); 196 doc.insertString(doc.getLength(), "\n", null); if (filterText.length() > 0) { 198 String filterTextLC = filterText.toLowerCase(Locale.US); 199 Style match = doc.addStyle(null, null); 200 match.addAttribute(StyleConstants.Background, new Color (246, 248, 139)); 201 Set <String > matches = filterer.getMatchesFor(filterText, deps[0]); 202 Iterator it = matches.iterator(); 203 boolean isEven = false; 204 Style even = doc.addStyle(null, null); 205 even.addAttribute(StyleConstants.Background, new Color (235, 235, 235)); 206 while (it.hasNext()) { 207 String hit = (String ) it.next(); 208 int loc = doc.getLength(); 209 doc.insertString(loc, hit, (isEven ? even : null)); 210 int start = hit.toLowerCase(Locale.US).indexOf(filterTextLC); 211 while (start != -1) { 212 doc.setCharacterAttributes(loc + start, filterTextLC.length(), match, true); 213 start = hit.toLowerCase(Locale.US).indexOf(filterTextLC, start + 1); 214 } 215 doc.insertString(doc.getLength(), "\n", (isEven ? even : null)); isEven ^= true; 217 } 218 } else { 219 Style italics = doc.addStyle(null, null); 220 italics.addAttribute(StyleConstants.Italic, Boolean.TRUE); 221 doc.insertString(doc.getLength(), getMessage("TEXT_no_filter_specified"), italics); 222 } 223 } 224 descValue.setCaretPosition(0); 225 } catch (BadLocationException e) { 226 Util.err.notify(ErrorManager.INFORMATIONAL, e); 227 } 228 } 229 230 public ModuleDependency[] getSelectedDependencies() { 231 ModuleDependency[] deps; 232 if (CustomizerComponentFactory.isWaitModel(moduleList.getModel())) { 233 deps = new ModuleDependency[0]; 234 } else { 235 Object [] objects = moduleList.getSelectedValues(); 236 deps = new ModuleDependency[objects.length]; 237 System.arraycopy(objects, 0, deps, 0, objects.length); 238 } 239 return deps; 240 } 241 242 private void search() { 243 if (filterTask != null) { 244 filterTask.cancel(); 245 filterTask = null; 246 } 247 final String text = filterValue.getText(); 248 if (text.length() == 0) { 249 moduleList.setModel(universeModules); 250 moduleList.setSelectedIndex(0); 251 moduleList.ensureIndexIsVisible(0); 252 } else { 253 final Runnable compute = new Runnable () { 254 public void run() { 255 final Set <ModuleDependency> matches = filterer.getMatches(text); 256 filterTask = null; 257 Mutex.EVENT.readAccess(new Runnable () { 258 public void run() { 259 if (!text.equals(filterValue.getText())) { 261 return; } 263 moduleList.setModel(CustomizerComponentFactory.createDependencyListModel(matches)); 264 int index = matches.isEmpty() ? -1 : 0; 265 moduleList.setSelectedIndex(index); 266 moduleList.ensureIndexIsVisible(index); 267 } 268 }); 269 } 270 }; 271 if (filterer == null) { 272 moduleList.setModel(CustomizerComponentFactory.createListWaitModel()); 274 filterTask = RequestProcessor.getDefault().post(new Runnable () { 275 public void run() { 276 if (filterer == null) { 277 filterer = new AddModuleFilter(universeModules.getDependencies(), props.getCodeNameBase()); 278 compute.run(); 279 } 280 } 281 }); 282 } else { 283 compute.run(); 285 } 286 } 287 } 288 289 private void initAccessibility() { 290 this.getAccessibleContext().setAccessibleDescription(getMessage("ACS_AddModuleDependency")); 291 filterValue.getAccessibleContext().setAccessibleDescription(getMessage("ACS_LBL_Filter")); 292 moduleList.getAccessibleContext().setAccessibleDescription(getMessage("ACS_CTL_ModuleList")); 293 moduleSP.getVerticalScrollBar().getAccessibleContext().setAccessibleName(getMessage("ACS_CTL_ModuleListVerticalScroll")); 294 moduleSP.getVerticalScrollBar().getAccessibleContext().setAccessibleDescription(getMessage("ACSD_CTL_ModuleListVerticalScroll")); 295 moduleSP.getHorizontalScrollBar().getAccessibleContext().setAccessibleName(getMessage("ACS_CTL_ModuleListHorizontalScroll")); 296 moduleSP.getHorizontalScrollBar().getAccessibleContext().setAccessibleDescription(getMessage("ACSD_CTL_ModuleListHorizontalScroll")); 297 showNonAPIModules.getAccessibleContext().setAccessibleDescription(getMessage("ACSD_ShowNonApiModules")); 298 } 299 300 private static String getMessage(String key) { 301 return NbBundle.getMessage(AddModulePanel.class, key); 302 } 303 304 309 private void initComponents() { 311 java.awt.GridBagConstraints gridBagConstraints; 312 313 moduleLabel = new javax.swing.JLabel (); 314 moduleSP = new javax.swing.JScrollPane (); 315 moduleList = new javax.swing.JList (); 316 descLabel = new javax.swing.JLabel (); 317 filter = new javax.swing.JLabel (); 318 filterValue = new javax.swing.JTextField (); 319 descValueSP = new javax.swing.JScrollPane (); 320 descValue = new javax.swing.JTextPane (); 321 showJavadocButton = new javax.swing.JButton (); 322 showNonAPIModules = new javax.swing.JCheckBox (); 323 324 setLayout(new java.awt.GridBagLayout ()); 325 326 setBorder(javax.swing.BorderFactory.createEmptyBorder(6, 6, 6, 6)); 327 setPreferredSize(new java.awt.Dimension (400, 400)); 328 moduleLabel.setLabelFor(moduleList); 329 org.openide.awt.Mnemonics.setLocalizedText(moduleLabel, org.openide.util.NbBundle.getMessage(AddModulePanel.class, "LBL_Module")); 330 gridBagConstraints = new java.awt.GridBagConstraints (); 331 gridBagConstraints.gridx = 0; 332 gridBagConstraints.gridy = 2; 333 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 334 gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST; 335 gridBagConstraints.insets = new java.awt.Insets (24, 0, 0, 0); 336 add(moduleLabel, gridBagConstraints); 337 338 moduleSP.setViewportView(moduleList); 339 340 gridBagConstraints = new java.awt.GridBagConstraints (); 341 gridBagConstraints.gridx = 0; 342 gridBagConstraints.gridy = 3; 343 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 344 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 345 gridBagConstraints.weighty = 1.0; 346 add(moduleSP, gridBagConstraints); 347 348 descLabel.setLabelFor(descValue); 349 org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(AddModulePanel.class, "LBL_Description")); 350 gridBagConstraints = new java.awt.GridBagConstraints (); 351 gridBagConstraints.gridx = 0; 352 gridBagConstraints.gridy = 4; 353 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 354 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 355 gridBagConstraints.insets = new java.awt.Insets (24, 0, 0, 0); 356 add(descLabel, gridBagConstraints); 357 358 filter.setLabelFor(filterValue); 359 org.openide.awt.Mnemonics.setLocalizedText(filter, org.openide.util.NbBundle.getMessage(AddModulePanel.class, "LBL_Filter")); 360 gridBagConstraints = new java.awt.GridBagConstraints (); 361 gridBagConstraints.gridx = 0; 362 gridBagConstraints.gridy = 0; 363 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 364 gridBagConstraints.insets = new java.awt.Insets (0, 0, 0, 12); 365 add(filter, gridBagConstraints); 366 367 gridBagConstraints = new java.awt.GridBagConstraints (); 368 gridBagConstraints.gridx = 1; 369 gridBagConstraints.gridy = 0; 370 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 371 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 372 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 373 gridBagConstraints.weightx = 1.0; 374 add(filterValue, gridBagConstraints); 375 376 descValue.setEditable(false); 377 descValue.setPreferredSize(new java.awt.Dimension (6, 100)); 378 descValueSP.setViewportView(descValue); 379 380 gridBagConstraints = new java.awt.GridBagConstraints (); 381 gridBagConstraints.gridx = 0; 382 gridBagConstraints.gridy = 5; 383 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 384 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 385 gridBagConstraints.weighty = 1.0; 386 add(descValueSP, gridBagConstraints); 387 388 org.openide.awt.Mnemonics.setLocalizedText(showJavadocButton, java.util.ResourceBundle.getBundle("org/netbeans/modules/apisupport/project/ui/customizer/Bundle").getString("CTL_ShowJavadoc")); 389 showJavadocButton.setEnabled(false); 390 showJavadocButton.addActionListener(new java.awt.event.ActionListener () { 391 public void actionPerformed(java.awt.event.ActionEvent evt) { 392 showJavadoc(evt); 393 } 394 }); 395 396 gridBagConstraints = new java.awt.GridBagConstraints (); 397 gridBagConstraints.gridx = 0; 398 gridBagConstraints.gridy = 6; 399 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 400 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 401 gridBagConstraints.insets = new java.awt.Insets (24, 0, 0, 0); 402 add(showJavadocButton, gridBagConstraints); 403 404 org.openide.awt.Mnemonics.setLocalizedText(showNonAPIModules, org.openide.util.NbBundle.getMessage(AddModulePanel.class, "CTL_ShowNonAPIModules")); 405 showNonAPIModules.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); 406 showNonAPIModules.setMargin(new java.awt.Insets (0, 0, 0, 0)); 407 showNonAPIModules.addActionListener(new java.awt.event.ActionListener () { 408 public void actionPerformed(java.awt.event.ActionEvent evt) { 409 showNonAPIModulesActionPerformed(evt); 410 } 411 }); 412 413 gridBagConstraints = new java.awt.GridBagConstraints (); 414 gridBagConstraints.gridx = 0; 415 gridBagConstraints.gridy = 1; 416 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 417 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 418 gridBagConstraints.insets = new java.awt.Insets (12, 0, 0, 0); 419 add(showNonAPIModules, gridBagConstraints); 420 421 } 423 private void showNonAPIModulesActionPerformed(java.awt.event.ActionEvent evt) { fillUpUniverseModules(); 425 } 427 private void showJavadoc(java.awt.event.ActionEvent evt) { HtmlBrowser.URLDisplayer.getDefault().showURL(currectJavadoc); 429 } 431 432 private javax.swing.JLabel descLabel; 434 private javax.swing.JTextPane descValue; 435 private javax.swing.JScrollPane descValueSP; 436 private javax.swing.JLabel filter; 437 javax.swing.JTextField filterValue; 438 private javax.swing.JLabel moduleLabel; 439 javax.swing.JList moduleList; 440 private javax.swing.JScrollPane moduleSP; 441 private javax.swing.JButton showJavadocButton; 442 private javax.swing.JCheckBox showNonAPIModules; 443 445 } 446 | Popular Tags |