1 19 20 21 package org.netbeans.modules.palette.ui; 22 import java.awt.Component ; 23 import java.awt.Container ; 24 import java.awt.Cursor ; 25 import java.awt.Dimension ; 26 import java.awt.LayoutManager ; 27 import java.awt.Point ; 28 import java.awt.Rectangle ; 29 import java.util.ArrayList ; 30 import javax.swing.BorderFactory ; 31 import org.netbeans.modules.palette.Category; 32 import org.netbeans.modules.palette.Item; 33 import org.netbeans.modules.palette.Model; 34 import org.netbeans.modules.palette.ModelListener; 35 import org.netbeans.modules.palette.Settings; 36 import org.netbeans.modules.palette.Utils; 37 import org.netbeans.spi.palette.PaletteController; 38 import org.openide.util.Utilities; 39 40 import java.awt.event.MouseAdapter ; 41 import java.awt.event.MouseListener ; 42 import java.awt.event.MouseEvent ; 43 import java.beans.PropertyChangeEvent ; 44 import java.beans.PropertyChangeListener ; 45 import javax.swing.JComponent ; 46 import javax.swing.JPanel ; 47 import javax.swing.JPopupMenu ; 48 import javax.swing.JScrollPane ; 49 import javax.swing.Scrollable ; 50 import javax.swing.SwingUtilities ; 51 import javax.swing.UIManager ; 52 import org.openide.nodes.Node; 53 import org.openide.util.HelpCtx; 54 55 56 57 62 public class PalettePanel extends JPanel implements Scrollable { 63 64 private static PalettePanel theInstance; 65 66 private PaletteController controller; 67 private Model model; 68 private Settings settings; 69 70 private ModelListener modelListener; 71 private PropertyChangeListener settingsListener; 72 73 private CategoryDescriptor[] descriptors = new CategoryDescriptor[0]; 74 private Category selectedCategory; 75 76 private Object lock = new Object (); 77 private MouseListener mouseListener; 78 79 private JScrollPane scrollPane; 80 81 private DnDSupport dndSupport; 82 83 private PalettePanel () { 84 setLayout( new PaletteLayoutManager() ); 85 addMouseListener( mouseListener() ); 86 87 dndSupport = new DnDSupport( this ); 88 89 setBackground( UIManager.getColor ("Panel.background") ); 90 } 91 92 public static synchronized PalettePanel getDefault() { 93 if( null == theInstance ) { 94 theInstance = new PalettePanel(); 95 } 96 return theInstance; 97 } 98 99 public JScrollPane getScrollPane() { 100 if( null == scrollPane ) { 101 scrollPane = new JScrollPane ( this ); 102 scrollPane.setBorder( BorderFactory.createEmptyBorder() ); 103 scrollPane.addMouseListener( mouseListener() ); 104 scrollPane.getViewport().setBackground( UIManager.getColor ("Panel.background") ); 105 scrollPane.setViewportBorder(null); 107 } 108 return scrollPane; 109 } 110 111 private CategoryDescriptor getCategoryDescriptor( Category category ) { 112 for( int i=0; i<descriptors.length; i++ ) { 113 CategoryDescriptor descriptor = descriptors[i]; 114 if( descriptor.getCategory () == category ) 115 return descriptor; 116 } 117 return null; 118 } 119 120 private CategoryDescriptor[] computeDescriptors( Category[] categories ) { 121 if( null == categories ) { 122 return new CategoryDescriptor[0]; 123 } 124 categories = getVisibleCategories( categories ); 125 CategoryDescriptor[] descriptors = new CategoryDescriptor[categories.length]; 126 for( int i=0; i<categories.length; i++) { 127 Category category = categories[i]; 128 CategoryDescriptor descriptor = getCategoryDescriptor( category ); 129 if( descriptor == null ) { 130 descriptor = new CategoryDescriptor( this, category ); 131 descriptor.setShowNames( getSettings().getShowItemNames() ); 132 descriptor.setIconSize( getSettings().getIconSize() ); 133 } else { 134 descriptor.refresh(); 135 } 136 descriptor.setWidth( getWidth() ); 137 descriptors[i] = descriptor; 138 } 139 return descriptors; 140 } 141 142 private Category[] getVisibleCategories( Category[] cats ) { 143 ArrayList <Category> tmp = new ArrayList <Category>( cats.length ); 144 for( int i=0; i<cats.length; i++ ) { 145 if( settings.isVisible( cats[i] ) ) { 146 tmp.add( cats[i] ); 147 } 148 } 149 return tmp.toArray( new Category[tmp.size()] ); 150 } 151 152 void computeHeights( Category openedCategory ) { 153 computeHeights( descriptors, openedCategory ); 154 } 155 156 private void computeHeights( CategoryDescriptor[] paletteCategoryDescriptors, 157 Category openedCategory) { 158 if( paletteCategoryDescriptors == null || paletteCategoryDescriptors.length <= 0 ) { 159 return; 160 } 161 revalidate(); 162 } 163 164 private static boolean arrayContains( Object [] objects, Object object ) { 165 if( objects == null || object == null ) 166 return false; 167 for( int i=0; i<objects.length; i++ ) { 168 if( objects[i] == object ) 169 return true; 170 } 171 return false; 172 } 173 174 private void setDescriptors( CategoryDescriptor[] paletteCategoryDescriptors ) { 175 for( int i=0; i<descriptors.length; i++ ) { 176 CategoryDescriptor descriptor = descriptors[i]; 177 if( !arrayContains( paletteCategoryDescriptors, descriptor ) ) { 178 remove( descriptor.getComponent() ); 179 dndSupport.remove( descriptor ); 180 } 181 } 182 for( int i=0; i<paletteCategoryDescriptors.length; i++ ) { 183 CategoryDescriptor paletteCategoryDescriptor = paletteCategoryDescriptors[i]; 184 if( !arrayContains( descriptors, paletteCategoryDescriptor ) ) { 185 add( paletteCategoryDescriptor.getComponent() ); 186 dndSupport.add( paletteCategoryDescriptor ); 187 } 188 } 189 if( descriptors.length == 0 && paletteCategoryDescriptors.length > 0 ) { 190 boolean isAnyCategoryOpened = false; 191 for( int i=0; i<paletteCategoryDescriptors.length; i++ ) { 192 if( paletteCategoryDescriptors[i].isOpened() ) { 193 isAnyCategoryOpened = true; 194 break; 195 } 196 } 197 if( !isAnyCategoryOpened ) { 198 paletteCategoryDescriptors[0].setOpened( true ); 199 } 200 } 201 descriptors = paletteCategoryDescriptors; 202 revalidate(); 203 } 204 205 public void doRefresh() { 206 if( null != controller ) 207 controller.refresh(); 208 } 209 210 public void refresh () { 211 Runnable runnable = new Runnable () { 212 public void run() { 213 synchronized( lock ) { 214 setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) ); 215 CategoryDescriptor[] paletteCategoryDescriptors = computeDescriptors( null != model ? model.getCategories() : null ); 216 setDescriptors (paletteCategoryDescriptors); 217 if( null != settings ) { 218 setIconSize( settings.getIconSize() ); 219 setShowItemNames( settings.getShowItemNames() ); 220 setItemWidth( settings.getShowItemNames() ? settings.getItemWidth() : -1 ); 221 } 222 if( null != model ) { 223 Item item = model.getSelectedItem(); 224 Category category = model.getSelectedCategory(); 225 setSelectedItemFromModel( category, item ); 226 } 227 setCursor( Cursor.getDefaultCursor() ); 228 } 229 } 230 }; 231 if( SwingUtilities.isEventDispatchThread() ) { 232 runnable.run(); 233 } else { 234 SwingUtilities.invokeLater( runnable ); 235 } 236 } 237 238 public void propertyChange( PropertyChangeEvent evt ) { 239 refresh (); 240 } 241 242 void select( Category category, Item item ) { 243 if( category != selectedCategory ) { 244 CategoryDescriptor selectedDescriptor = findDescriptorFor( selectedCategory ); 245 if( selectedDescriptor != null ) { 246 selectedDescriptor.setSelectedItem( null ); 247 } 248 } 249 selectedCategory = category; 250 if( null != model ) { 251 if( null == category || null == item ) 252 model.clearSelection(); 253 else 254 model.setSelectedItem( category.getLookup(), item.getLookup() ); 255 } 256 } 257 258 private void setSelectedItemFromModel( Category category, Item item ) { 259 if( null != selectedCategory && !selectedCategory.equals( category ) ) { 260 CategoryDescriptor selectedDescriptor = findDescriptorFor( selectedCategory ); 261 if( selectedDescriptor != null ) { 262 selectedDescriptor.setSelectedItem( null ); 263 } 264 } 265 CategoryDescriptor descriptor = findDescriptorFor( category ); 266 if( descriptor == null ) { 267 return; 268 } 269 if( item != null ) { 270 selectedCategory = category; 271 } 272 descriptor.setSelectedItem( item ); 273 } 274 275 private CategoryDescriptor findDescriptorFor( Category category ) { 276 if( null != descriptors ) { 277 for( int i= 0; i<descriptors.length; i++ ) { 278 CategoryDescriptor descriptor = descriptors[i]; 279 if( descriptor.getCategory().equals( category ) ) 280 return descriptor; 281 } 282 } 283 return null; 284 } 285 286 private void scrollToCategory( final Category category ) { 287 Runnable runnable = new Runnable () { 288 public void run() { 289 synchronized( lock ) { 290 CategoryDescriptor descriptor = findDescriptorFor( category ); 291 if( null != descriptor ) { 292 scrollPane.validate(); 293 Point loc = descriptor.getComponent().getLocation(); 294 scrollPane.getViewport().setViewPosition( loc ); 295 } 296 } 297 } 298 }; 299 if( SwingUtilities.isEventDispatchThread() ) { 300 runnable.run(); 301 } else { 302 SwingUtilities.invokeLater( runnable ); 303 } 304 } 305 306 309 public void setContent( PaletteController newController, Model newModel, Settings newSettings ) { 310 synchronized (lock ) { 311 if( newModel == model && newSettings == settings ) { 312 return; 313 } 314 315 Model old = model; 316 if( model != null && null != modelListener ) { 317 model.removeModelListener( modelListener ); 318 } 319 if( settings != null && null != settingsListener ) { 320 settings.removePropertyChangeListener( settingsListener ); 321 } 322 323 model = newModel; 324 settings = newSettings; 325 controller = newController; 326 if( model != null ) { 327 model.addModelListener( getModelListener() ); 328 } 329 if( null != settings ) { 330 settings.addPropertyChangeListener( getSettingsListener() ); 331 } 332 refresh(); 333 } 334 } 335 336 private MouseListener mouseListener() { 337 if( null == mouseListener ) { 338 mouseListener = new MouseAdapter () { 339 public void mouseClicked(MouseEvent event) { 340 if( SwingUtilities.isRightMouseButton( event ) && null != model ) { 341 JPopupMenu popup = Utilities.actionsToPopup( model.getActions(), PalettePanel.this ); 342 Utils.addCustomizationMenuItems( popup, getController(), getSettings() ); 343 popup.show( (Component )event.getSource(), event.getX(), event.getY() ); 344 } 345 } 346 }; 347 } 348 return mouseListener; 349 } 350 351 private void setShowItemNames( boolean showNames ) { 352 for( int i=0; i<descriptors.length; i++ ) { 353 descriptors[i].setShowNames( showNames ); 354 } 355 repaint(); 356 } 357 358 private void setIconSize(int iconSize) { 359 for( int i=0; i<descriptors.length; i++ ) { 360 descriptors[i].setIconSize( iconSize ); 361 } 362 repaint(); 363 } 364 365 private void setItemWidth(int itemWidth) { 366 for( int i=0; i<descriptors.length; i++ ) { 367 descriptors[i].setItemWidth( itemWidth ); 368 } 369 repaint(); 370 } 371 372 public boolean getScrollableTracksViewportHeight () { 373 return false; 374 } 375 376 public boolean getScrollableTracksViewportWidth () { 377 return true; 378 } 379 380 public Dimension getPreferredScrollableViewportSize () { 381 return getPreferredSize (); 382 } 383 384 public int getScrollableBlockIncrement (Rectangle visibleRect, int orientation, int direction) { 385 return 100; 386 } 387 388 public int getScrollableUnitIncrement (Rectangle visibleRect, int orientation, int direction) { 389 return 20; 390 } 391 392 public HelpCtx getHelpCtx() { 393 HelpCtx ctx = null; 394 if( null != getModel() ) { 395 Item selItem = getModel().getSelectedItem(); 396 if( null != selItem ) { 397 Node selNode = (Node) selItem.getLookup().lookup( Node.class ); 398 if( null != selNode ) 399 ctx = selNode.getHelpCtx(); 400 } 401 if( null == ctx || HelpCtx.DEFAULT_HELP.equals( ctx ) ) { 402 CategoryDescriptor selCategory = null; 404 for( int i=0; i<descriptors.length; i++ ) { 405 if( descriptors[i].isSelected() ) { 406 selCategory = descriptors[i]; 407 break; 408 } 409 } 410 if( null != selCategory ) { 411 Node selNode = (Node) selCategory.getCategory().getLookup().lookup( Node.class ); 412 if( null != selNode ) 413 ctx = selNode.getHelpCtx(); 414 } 415 } 416 if( null == ctx || HelpCtx.DEFAULT_HELP.equals( ctx ) ) { 417 Node selNode = (Node) getModel().getRoot().lookup( Node.class ); 418 if( null != selNode ) 419 ctx = selNode.getHelpCtx(); 420 } 421 } 422 if( null == ctx || HelpCtx.DEFAULT_HELP.equals( ctx ) ) { 423 ctx = new HelpCtx("CommonPalette"); } 425 return ctx; 426 } 427 428 private ModelListener getModelListener() { 429 if( null == modelListener ) { 430 modelListener = new ModelListener() { 431 public void categoriesAdded( Category[] addedCategories ) { 432 PalettePanel.this.refresh(); 433 if( null != addedCategories && addedCategories.length > 0 ) { 434 PalettePanel.this.scrollToCategory(addedCategories[0] ); 435 } 436 } 437 438 public void categoriesRemoved( Category[] removedCategories ) { 439 PalettePanel.this.refresh(); 440 } 441 442 public void categoriesReordered() { 443 PalettePanel.this.refresh(); 444 } 445 446 public void propertyChange( PropertyChangeEvent evt ) { 447 if( ModelListener.PROP_SELECTED_ITEM.equals( evt.getPropertyName() ) ) { 448 Item selectedItem = model.getSelectedItem(); 449 Category selectedCategory = model.getSelectedCategory(); 450 setSelectedItemFromModel( selectedCategory, selectedItem ); 451 } 452 } 453 454 }; 455 } 456 return modelListener; 457 } 458 459 private PropertyChangeListener getSettingsListener() { 460 if( null == settingsListener ) { 461 settingsListener = new PropertyChangeListener () { 462 public void propertyChange( PropertyChangeEvent evt ) { 463 if( PaletteController.ATTR_IS_VISIBLE.equals( evt.getPropertyName() ) ) { 464 PalettePanel.this.refresh(); 465 for( int i=0; null != descriptors && i<descriptors.length; i++ ) { 466 descriptors[i].computeItems(); 467 } 468 } else if( PaletteController.ATTR_ICON_SIZE.equals( evt.getPropertyName() ) ) { 469 470 setIconSize( getSettings().getIconSize() ); 471 472 } else if( PaletteController.ATTR_SHOW_ITEM_NAMES.equals( evt.getPropertyName() ) ) { 473 474 setShowItemNames( getSettings().getShowItemNames() ); 475 setItemWidth( getSettings().getShowItemNames() ? getSettings().getItemWidth() : -1 ); 476 477 } 478 } 479 480 }; 481 } 482 return settingsListener; 483 } 484 485 Model getModel() { 486 return model; 487 } 488 489 Settings getSettings() { 490 return settings; 491 } 492 493 PaletteController getController() { 494 return controller; 495 } 496 497 public void updateUI() { 498 super.updateUI(); 499 if( null != model ) 500 model.refresh(); 501 } 502 503 private class PaletteLayoutManager implements LayoutManager { 504 505 public void addLayoutComponent( String name, Component comp) { 506 } 507 508 public void layoutContainer( Container parent ) { 509 int width = getWidth (); 510 511 int height = 0; 512 for( int i=0; i<descriptors.length; i++ ) { 513 CategoryDescriptor paletteCategoryDescriptor = descriptors[i]; 514 paletteCategoryDescriptor.setPositionY( height ); 515 JComponent comp = paletteCategoryDescriptor.getComponent(); 516 comp.setSize( width, comp.getPreferredSize().height ); 517 height += paletteCategoryDescriptor.getComponent().getHeight(); 518 } 519 } 520 521 public Dimension minimumLayoutSize(Container parent) { 522 return new Dimension (0, 0); 523 } 524 525 public Dimension preferredLayoutSize(Container parent) { 526 int height = 0; 527 int width = getWidth(); 528 for( int i=0; i<descriptors.length; i++ ) { 529 CategoryDescriptor descriptor = descriptors[i]; 530 height += descriptor.getPreferredHeight( width )+1; 531 } 532 return new Dimension ( 10 , height ); 533 } 534 535 public void removeLayoutComponent(Component comp) { 536 } 537 } 538 } 539 | Popular Tags |