1 19 20 package org.netbeans.modules.autoupdate.catalog; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Cursor ; 24 import java.awt.Dialog ; 25 import java.awt.Dimension ; 26 import java.awt.Font ; 27 import java.awt.FontMetrics ; 28 import java.beans.PropertyChangeEvent ; 29 import java.beans.PropertyChangeListener ; 30 import java.beans.PropertyVetoException ; 31 import java.io.CharConversionException ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import javax.swing.ActionMap ; 35 import javax.swing.JScrollPane ; 36 import javax.swing.SwingUtilities ; 37 import javax.swing.UIManager ; 38 import javax.swing.border.Border ; 39 import javax.swing.event.ChangeEvent ; 40 import javax.swing.event.ChangeListener ; 41 import javax.swing.text.html.HTMLEditorKit ; 42 import javax.swing.text.html.StyleSheet ; 43 import org.netbeans.api.progress.ProgressHandle; 44 import org.netbeans.api.progress.ProgressHandleFactory; 45 import org.openide.DialogDescriptor; 46 import org.openide.DialogDisplayer; 47 import org.openide.awt.StatusDisplayer; 48 import org.openide.explorer.ExplorerManager; 49 import org.openide.explorer.ExplorerUtils; 50 import org.openide.explorer.view.TreeTableView; 51 import org.openide.nodes.Node; 52 import org.openide.nodes.PropertySupport; 53 import org.openide.util.AsyncGUIJob; 54 import org.openide.util.NbBundle; 55 import org.openide.util.Utilities; 56 import org.openide.windows.TopComponent; 57 import org.openide.xml.XMLUtil; 58 59 63 public class ModuleSelectionPanel extends javax.swing.JPanel 64 implements PropertyChangeListener { 65 66 private TreeTableView treeTableView; 67 private static final Logger err = Logger.getLogger("org.netbeans.modules.autoupdate.catalog.ModuleSelectionPanel"); 69 70 private static final int DEF_TREE_WIDTH = 420; 71 private static final int DEF_0_COL_WIDTH = 60; 72 private static final int DEF_1_COL_WIDTH = 150; 73 private static final int DEF_HEIGHT = 350; 74 75 private static ModuleDeleter deleter; 76 77 private Cursor cursor = null; 78 static private ModuleSelectionPanel panel = null; 79 80 static public ModuleSelectionPanel getGUI (boolean create) { 81 assert create || panel != null; 82 if (panel == null && create) { 83 panel = new ModuleSelectionPanel (); 84 } 85 return panel; 86 } 87 88 private ModuleSelectionPanel () { 89 initComponents(); 90 treeTableView = new TreeTableView (); 91 treeTableView.setRootVisible(false); 92 ExplorerPanel explorerPanel = new ExplorerPanel (); 93 explorerPanel.getAccessibleContext ().setAccessibleName ( 94 NbBundle.getBundle (ModuleSelectionPanel.class).getString ("ACN_ModuleSelectionPanel_ExplorerPanel")); explorerPanel.getAccessibleContext ().setAccessibleDescription ( 96 NbBundle.getBundle (ModuleSelectionPanel.class).getString ("ACD_ModuleSelectionPanel_ExplorerPanel")); explorerPanel.setLayout (new BorderLayout ()); 98 explorerPanel.add (treeTableView, BorderLayout.CENTER); 99 modulesPane.add (explorerPanel, BorderLayout.CENTER); 100 manager = explorerPanel.getExplorerManager(); 101 102 Font f = UIManager.getFont("controlFont"); Integer i = (Integer ) UIManager.get("nbDefaultFontSize"); if (i == null) { 106 i = new Integer (11); } 108 if (f == null) { 109 f = getFont(); 110 } 111 112 Node.Property [] properties = new Node.Property [] { 113 new PropertySupport.ReadWrite ( 114 "enabled", Boolean.TYPE, 116 org.openide.util.NbBundle.getMessage (ModuleNode.class, "PROP_modules_enabled"), 117 org.openide.util.NbBundle.getMessage (ModuleNode.class, "HINT_modules_enabled") 118 ) { 119 public Object getValue () { 120 return null; 121 } 122 123 public void setValue (Object o) { 124 } 125 }, 126 new PropertySupport.ReadOnly ( 127 "specificationVersion", String .class, 129 org.openide.util.NbBundle.getMessage (ModuleNode.class, "PROP_modules_specversion"), 130 org.openide.util.NbBundle.getMessage (ModuleNode.class, "HINT_modules_specversion") 131 ) { 132 public Object getValue () { 133 return null; 134 } 135 } 136 }; 137 138 treeTableView.setProperties (properties); 139 140 if (f.getSize() > i.intValue()) { sizeTTVCarefully(); 143 } else { 144 treeTableView.setPreferredSize( 146 new Dimension (DEF_1_COL_WIDTH + DEF_0_COL_WIDTH + DEF_TREE_WIDTH, 147 DEF_HEIGHT) 148 ); 149 treeTableView.setTreePreferredWidth(DEF_TREE_WIDTH); 150 treeTableView.setTableColumnPreferredWidth(0, DEF_0_COL_WIDTH); 151 treeTableView.setTableColumnPreferredWidth(1, DEF_1_COL_WIDTH); 152 } 153 treeTableView.setPopupAllowed(true); 154 treeTableView.setDefaultActionAllowed(false); 155 156 treeTableView.setBorder((Border )UIManager.get("Nb.ScrollPane.border")); treeTableView.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 159 160 initAccessibility(); 161 162 Utilities.attachInitJob (this, new WarmupJob ()); 163 setWaitingState (true, false); 164 } 165 166 private boolean isWaiting = false; 167 private Dialog d = null; 168 169 public void setWaitingState (boolean wait, final boolean showProgress) { 170 if (isWaiting == wait) { 171 return ; 172 } 173 isWaiting = wait; 174 SwingUtilities.invokeLater (new Runnable () { 175 public void run () { 176 doSetWaitingState (isWaiting, showProgress); 177 } 178 }); 179 } 180 181 private ChangeListener statusTextListener = null; 182 183 private void doSetWaitingState (boolean wait, boolean showProgress) { 184 assert SwingUtilities.isEventDispatchThread (); 185 if (! this.isVisible ()) return ; 186 err.log(Level.FINE, 187 "Set waiting state on ModuleSelectionPanel to (wait:" + wait + 188 ", showProgress: " + showProgress + ")"); 189 uninstallButton.setEnabled (! wait); 190 if (wait) { 191 if (cursor == null) cursor = getCursor(); 192 setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR)); 193 if (showProgress) { 194 if (d == null) { 195 final ProgressHandle handle = ProgressHandleFactory.createHandle ("modules-update"); 196 final ModuleUpdaterProgress progressPanel = new ModuleUpdaterProgress (handle); 197 DialogDescriptor dd = new DialogDescriptor (progressPanel, 198 NbBundle.getMessage (ModuleUpdaterProgress.class, "CTL_ModuleUpdaterProgress_Title"), true, new Object [0], 201 null, 202 DialogDescriptor.DEFAULT_ALIGN, 203 null, 204 null, 205 true); 206 statusTextListener = new ChangeListener () { 207 public void stateChanged (ChangeEvent e) { 208 handle.progress (StatusDisplayer.getDefault ().getStatusText ()); 209 } 210 }; 211 StatusDisplayer.getDefault ().addChangeListener (statusTextListener); 212 d = DialogDisplayer.getDefault ().createDialog (dd); 213 handle.start (); 214 d.setVisible (true); 215 } 216 } 217 } else { 218 if (cursor != null) { 219 setCursor (cursor); 220 cursor = null; 221 } else { 222 setCursor (Cursor.getDefaultCursor ()); 223 } 224 if (d != null && d.isVisible ()) { 225 d.setVisible (false); 226 d.dispose (); 227 d = null; 228 this.requestFocus (); 229 } 230 if (statusTextListener != null) { 231 StatusDisplayer.getDefault ().removeChangeListener (statusTextListener); 232 } 233 } 234 } 235 236 public boolean isWaitingState () { 237 return isWaiting; 238 } 239 240 private void prepareComponents () { 241 this.uninstallButton.setEnabled (false); 242 HTMLEditorKit htmlkit = new HTMLEditorKit (); 243 246 251 StyleSheet css = htmlkit.getStyleSheet (); 252 253 if (css.getStyleSheets() == null) { 254 StyleSheet css2 = new StyleSheet (); 255 Font f = treeTableView.getFont (); 256 int size = treeTableView.getFont ().getSize (); 257 css2.addRule(new StringBuffer ("body { font-size: ").append(size) .append("; font-family: ").append(f.getName()).append("; }").toString()); css2.addStyleSheet(css); 260 htmlkit.setStyleSheet(css2); 261 } 262 263 this.description.setEditorKit (htmlkit); 264 265 ModuleNode node = new ModuleNode(); 267 manager.setRootContext(node); 268 269 manager.addPropertyChangeListener (this); 270 271 Node[] kids = node.getChildren().getNodes(true); 272 if (kids.length > 0) { 273 try { 274 manager.setSelectedNodes(new Node[] {kids[0]}); 275 } catch (PropertyVetoException ex) { 276 assert false : ex; 277 } 278 } 279 } 280 281 286 private void sizeTTVCarefully () { 287 Font headerFont = (Font )UIManager.getDefaults().get("TableHeader.font"); Font tableFont = (Font )UIManager.getDefaults().get("Table.font"); FontMetrics headerFm = getFontMetrics(headerFont); 290 291 int enabledColWidth = Math.max(DEF_0_COL_WIDTH, headerFm.stringWidth( 292 NbBundle.getMessage (ModuleNode.class, "PROP_modules_enabled")) + 20 293 ); 294 int specColWidth = Math.max(DEF_1_COL_WIDTH, headerFm.stringWidth( 295 NbBundle.getMessage (ModuleNode.class, "PROP_modules_specversion")) + 20 296 ); 297 int defFontSize = UIManager.getDefaults().getInt("nbDefaultFontSize"); 298 int treeWidth = DEF_TREE_WIDTH + 10 * (tableFont.getSize() - defFontSize); 299 300 treeTableView.setPreferredSize( 301 new Dimension (treeWidth + enabledColWidth + specColWidth, 302 DEF_HEIGHT + 10 * (tableFont.getSize() - defFontSize)) 303 ); 304 treeTableView.setTreePreferredWidth(treeWidth); 305 treeTableView.setTableColumnPreferredWidth(0, enabledColWidth); 306 treeTableView.setTableColumnPreferredWidth(1, specColWidth); 307 } 308 309 314 private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; 316 317 modulesLabel = new javax.swing.JLabel (); 318 uninstallButton = new javax.swing.JButton (); 319 descriptionLabel = new javax.swing.JLabel (); 320 descriptionPane = new javax.swing.JScrollPane (); 321 description = new javax.swing.JEditorPane (); 322 modulesPane = new javax.swing.JPanel (); 323 324 setLayout(new java.awt.GridBagLayout ()); 325 326 setName(NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_ModuleSelectionPanel_Name")); 327 modulesLabel.setLabelFor(modulesPane); 328 org.openide.awt.Mnemonics.setLocalizedText(modulesLabel, org.openide.util.NbBundle.getBundle(ModuleSelectionPanel.class).getString("ModuleSelectionPanel_ModuleLabel_text")); 329 gridBagConstraints = new java.awt.GridBagConstraints (); 330 gridBagConstraints.gridx = 0; 331 gridBagConstraints.gridy = 0; 332 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 333 gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST; 334 gridBagConstraints.insets = new java.awt.Insets (7, 11, 0, 0); 335 add(modulesLabel, gridBagConstraints); 336 337 org.openide.awt.Mnemonics.setLocalizedText(uninstallButton, org.openide.util.NbBundle.getMessage(ModuleSelectionPanel.class, "BTN_ModuleSelectionPanel_Uninstall")); 338 uninstallButton.addActionListener(new java.awt.event.ActionListener () { 339 public void actionPerformed(java.awt.event.ActionEvent evt) { 340 uninstallButtonActionPerformed(evt); 341 } 342 }); 343 344 gridBagConstraints = new java.awt.GridBagConstraints (); 345 gridBagConstraints.gridx = 1; 346 gridBagConstraints.gridy = 1; 347 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 348 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 349 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 350 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH; 351 gridBagConstraints.weightx = 0.15; 352 gridBagConstraints.weighty = 1.0; 353 gridBagConstraints.insets = new java.awt.Insets (2, 8, 0, 12); 354 add(uninstallButton, gridBagConstraints); 355 356 descriptionLabel.setLabelFor(descriptionPane); 357 org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, org.openide.util.NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_ModuleSelectionPanel_descriptionLabel")); 358 gridBagConstraints = new java.awt.GridBagConstraints (); 359 gridBagConstraints.gridx = 0; 360 gridBagConstraints.gridy = 2; 361 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 362 gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST; 363 gridBagConstraints.insets = new java.awt.Insets (8, 11, 0, 0); 364 add(descriptionLabel, gridBagConstraints); 365 366 descriptionPane.setMinimumSize(new java.awt.Dimension (400, 70)); 367 descriptionPane.setPreferredSize(new java.awt.Dimension (400, 70)); 368 description.setEditable(false); 369 descriptionPane.setViewportView(description); 370 371 gridBagConstraints = new java.awt.GridBagConstraints (); 372 gridBagConstraints.gridx = 0; 373 gridBagConstraints.gridy = 3; 374 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 375 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 376 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH; 377 gridBagConstraints.weightx = 0.85; 378 gridBagConstraints.weighty = 0.2; 379 gridBagConstraints.insets = new java.awt.Insets (2, 11, 0, 0); 380 add(descriptionPane, gridBagConstraints); 381 382 modulesPane.setLayout(new java.awt.BorderLayout ()); 383 384 gridBagConstraints = new java.awt.GridBagConstraints (); 385 gridBagConstraints.gridx = 0; 386 gridBagConstraints.gridy = 1; 387 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 388 gridBagConstraints.weightx = 0.85; 389 gridBagConstraints.weighty = 0.8; 390 gridBagConstraints.insets = new java.awt.Insets (2, 11, 0, 0); 391 add(modulesPane, gridBagConstraints); 392 393 } 395 private void uninstallButtonActionPerformed (java.awt.event.ActionEvent evt) { ModuleNodeUtils.doUninstall (manager.getSelectedNodes ()); 397 } 399 private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) { } 403 private javax.swing.JEditorPane description; 405 private javax.swing.JLabel descriptionLabel; 406 private javax.swing.JScrollPane descriptionPane; 407 private javax.swing.JLabel modulesLabel; 408 private javax.swing.JPanel modulesPane; 409 private javax.swing.JButton uninstallButton; 410 412 private ExplorerManager manager; 413 414 private static class ExplorerPanel extends TopComponent implements ExplorerManager.Provider { 415 private ExplorerManager mgr; 416 public ExplorerPanel () { 417 this.mgr = new ExplorerManager (); 418 ActionMap map = this.getActionMap (); 419 map.put ("delete", ExplorerUtils.actionDelete(mgr, false)); 420 associateLookup (ExplorerUtils.createLookup (mgr, map)); 421 } 422 423 public ExplorerManager getExplorerManager () { 424 return mgr; 425 } 426 427 protected void componentActivated() { 428 ExplorerUtils.activateActions (mgr, true); 429 } 430 431 protected void componentDeactivated() { 432 ExplorerUtils.activateActions (mgr, false); 433 } 434 } 435 436 438 public void propertyChange(PropertyChangeEvent evt) { 439 if ((evt.getSource() == manager) 440 && (manager.PROP_SELECTED_NODES.equals(evt.getPropertyName()) || manager.PROP_NODE_CHANGE.equals (evt.getPropertyName ()))) { 441 442 final Node[] nodes = manager.getSelectedNodes(); 443 String text = ""; 445 if (nodes.length == 1) { 446 ModuleBean bean = (ModuleBean) nodes[0].getLookup().lookup(ModuleBean.class); 447 if (bean != null) { 448 try { 449 text = "<b>" + XMLUtil.toElementContent(bean.getModule().getDisplayName()) + "</b>"; String longDesc = bean.getLongDescription(); 451 if (longDesc != null) { 452 text += "<br>" + XMLUtil.toElementContent(longDesc); } 454 } catch (CharConversionException e) { 455 err.log(Level.WARNING, null, e); 456 } 457 } 458 } 459 460 description.setText(text); 461 description.setCaretPosition (0); 462 463 SwingUtilities.invokeLater (new Runnable () { 464 public void run () { 465 treeTableView.requestFocus (); 466 uninstallButton.setEnabled (! isWaitingState () && ModuleNodeUtils.canUninstall (nodes)); 468 } 469 }); 470 } 471 } 472 473 475 public void initAccessibility(){ 476 477 java.util.ResourceBundle b = NbBundle.getBundle(this.getClass()); 478 479 this.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_ModuleSelectionPanel")); } 481 482 private class WarmupJob implements AsyncGUIJob { 484 485 public void construct () { 486 prepareComponents (); 487 } 488 489 public void finished () { 490 setWaitingState (false, false); 491 treeTableView.requestFocus(); 492 } 493 494 } 495 496 } 497 | Popular Tags |