1 19 24 25 package org.netbeans.core.output2.ui; 26 27 import javax.swing.border.Border ; 28 import org.netbeans.core.output2.Controller; 29 import org.openide.util.Utilities; 30 import org.openide.windows.TopComponent; 31 import org.openide.awt.TabbedPaneFactory; 32 33 import javax.swing.*; 34 import javax.swing.event.ChangeEvent ; 35 import javax.swing.event.ChangeListener ; 36 import java.awt.*; 37 import java.util.ArrayList ; 38 import java.beans.PropertyChangeListener ; 39 import java.beans.PropertyChangeEvent ; 40 import java.lang.reflect.Method ; 41 import javax.swing.plaf.TabbedPaneUI ; 42 43 49 public abstract class AbstractOutputWindow extends TopComponent implements ChangeListener , PropertyChangeListener { 50 protected JTabbedPane pane = TabbedPaneFactory.createCloseButtonTabbedPane(); 51 private static final String ICON_PROP = "tabIcon"; private JToolBar toolbar = null; 53 54 55 public AbstractOutputWindow() { 56 pane.addChangeListener(this); 57 pane.addPropertyChangeListener(TabbedPaneFactory.PROP_CLOSE, this); 58 setFocusable(true); 59 setBackground(UIManager.getColor("text")); toolbar = new JToolBar(); 61 toolbar.setOrientation(JToolBar.VERTICAL); 62 toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.Y_AXIS)); 63 toolbar.setFloatable(false); 64 Insets ins = toolbar.getMargin(); 65 JButton sample = new JButton(); 66 sample.setBorderPainted(false); 67 sample.setOpaque(false); 68 sample.setText(null); 69 sample.setIcon(new Icon() { 70 public int getIconHeight() { 71 return 16; 72 } 73 public int getIconWidth() { 74 return 16; 75 } 76 public void paintIcon(Component c, Graphics g, int x, int y) { 77 } 78 }); 79 toolbar.add(sample); 80 Dimension buttonPref = sample.getPreferredSize(); 81 Dimension minDim = new Dimension(buttonPref.width + ins.left + ins.right, buttonPref.height + ins.top + ins.bottom); 82 toolbar.setMinimumSize(minDim); 83 toolbar.setPreferredSize(minDim); 84 toolbar.remove(sample); 85 setLayout(new BorderLayout()); 86 add(toolbar, BorderLayout.WEST); 87 toolbar.setBorder(new VariableRightBorder(pane)); 88 toolbar.setBorderPainted(true); 89 } 90 91 public void propertyChange(PropertyChangeEvent pce) { 92 if (TabbedPaneFactory.PROP_CLOSE.equals(pce.getPropertyName())) { 93 AbstractOutputTab tab = (AbstractOutputTab) pce.getNewValue(); 94 closeRequest(tab); 95 } 96 } 97 98 protected abstract void closeRequest(AbstractOutputTab tab); 99 100 protected abstract void removed(AbstractOutputTab view); 101 102 protected void addImpl(Component c, Object constraints, int idx) { 103 setFocusable(false); 104 Component focusOwner = 105 KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 106 boolean hadFocus = hasFocus() || isAncestorOf(focusOwner); 107 108 synchronized (getTreeLock()) { 109 if (c instanceof AbstractOutputTab) { 110 AbstractOutputTab aop = getInternalTab(); 111 if (aop != null) { 112 if (aop == c) { 113 return; 114 } 115 super.remove(aop); 116 assert pane.getParent() != this; 117 pane.add(aop); 118 setTabIcon(aop, (Icon)aop.getClientProperty(ICON_PROP)); 119 pane.add(c); 120 setTabIcon((AbstractOutputTab)c, (Icon)((AbstractOutputTab)c).getClientProperty(ICON_PROP)); 121 122 super.addImpl(pane, constraints, idx); 123 updateSingletonName(null); 124 revalidate(); 125 } else if (pane.getParent() == this) { 126 pane.add(c); 127 setTabIcon((AbstractOutputTab) c, (Icon)((AbstractOutputTab)c).getClientProperty(ICON_PROP)); 128 revalidate(); 129 } else { 130 super.addImpl(c, constraints, idx); 131 setTabIcon((AbstractOutputTab) c, (Icon)((AbstractOutputTab)c).getClientProperty(ICON_PROP)); 132 setToolbarButtons(((AbstractOutputTab)c).getToolbarButtons()); 133 revalidate(); 135 } 136 if (hadFocus) { 137 requestFocus(); 141 } 142 143 return; 144 } 145 super.addImpl(c, constraints, idx); 146 } 147 if (getComponentCount() == 2 && getComponent(1) instanceof AbstractOutputTab) { 148 updateSingletonName(getComponent(1).getName()); 149 } 150 revalidate(); 151 } 152 153 public final AbstractOutputTab[] getTabs() { 154 ArrayList al = new ArrayList (pane.getParent() == this ? pane.getTabCount() : getComponentCount()); 155 if (pane.getParent() == this) { 156 int tabs = pane.getTabCount(); 157 for (int i=0; i < tabs; i++) { 158 Component c = pane.getComponentAt(i); 159 if (c instanceof AbstractOutputTab) { 160 al.add(c); 161 } 162 } 163 } else { 164 Component[] c = getComponents(); 165 for (int i=0; i < c.length; i++) { 166 if (c[i] instanceof AbstractOutputTab) { 167 al.add(c[i]); 168 } 169 } 170 } 171 AbstractOutputTab[] result = new AbstractOutputTab[al.size()]; 172 return (AbstractOutputTab[]) al.toArray(result); 173 } 174 175 176 public void remove(Component c) { 177 AbstractOutputTab removedSelectedView = null; 178 synchronized (getTreeLock()) { 179 if (c.getParent() == pane && c instanceof AbstractOutputTab) { 180 if (c == pane.getSelectedComponent()) { 181 if (Controller.LOG) Controller.log("Selected view is being removed: " + c.getName()); 182 removedSelectedView = (AbstractOutputTab) c; 183 } 184 checkWinXPLFBug(); 185 pane.remove(c); 186 if (pane.getTabCount() == 1) { 187 Component comp = pane.getComponentAt(0); 188 pane.remove(comp); 189 super.remove(pane); 190 add(comp); 191 updateSingletonName(c.getName()); 192 setToolbarButtons(((AbstractOutputTab)comp).getToolbarButtons()); 193 revalidate(); 194 } 195 } else { 196 if (c == getSelectedTab()) { 197 removedSelectedView = (AbstractOutputTab) c; 198 } 199 super.remove(c); 200 setToolbarButtons(new JButton[0]); 201 updateSingletonName(null); 202 } 203 if (removedSelectedView != null) { 204 fire(removedSelectedView); 205 } 206 } 207 if (c instanceof AbstractOutputTab && c.getParent() == null) { 208 removed((AbstractOutputTab) c); 209 } 210 if (getComponentCount() == 2 && getComponent(1) instanceof AbstractOutputTab) { 211 updateSingletonName(getComponent(1).getName()); 212 } 213 revalidate(); 214 setFocusable(getComponentCount() == 1); 215 } 216 217 private AbstractOutputTab getInternalTab() { 218 Component[] c = getComponents(); 219 for (int i=0; i < c.length; i++) { 220 if (c[i] instanceof AbstractOutputTab) { 221 return (AbstractOutputTab) c[i]; 222 } 223 } 224 return null; 225 } 226 227 public final AbstractOutputTab getSelectedTab() { 228 if (pane.getParent() == this) { 229 return (AbstractOutputTab) pane.getSelectedComponent(); 230 } else { 231 return getInternalTab(); 232 } 233 } 234 235 public void setSelectedTab(AbstractOutputTab op) { 236 assert (op.getParent() == this || op.getParent() == pane); 237 if (Controller.LOG) { 238 Controller.log("SetSelectedTab: " + op + " parent is " + op.getParent()); 239 } 240 if (pane.getParent() == this && op != pane.getSelectedComponent()) { 241 pane.setSelectedComponent(op); 242 } 243 244 getActionMap().setParent(op.getActionMap()); 245 } 246 247 public void setTabTitle(AbstractOutputTab tab, String name) { 248 if (tab.getParent() == pane) { 249 pane.setTitleAt(pane.indexOfComponent(tab), name); 250 } else if (tab.getParent() == this) { 251 updateSingletonName(name); 252 } 253 tab.setName(name); 254 } 255 256 public void setTabIcon(AbstractOutputTab tab, Icon icon) { 257 if (icon != null) { 258 tab.putClientProperty(ICON_PROP, icon); 259 if (pane.indexOfComponent(tab) != -1) { 260 pane.setIconAt(pane.indexOfComponent(tab), icon); 261 pane.setDisabledIconAt(pane.indexOfComponent(tab), icon); 262 } 263 } 264 } 265 266 public void requestFocus() { 267 if (!isShowing()) { 268 return; 269 } 270 AbstractOutputTab tab = getSelectedTab(); 271 if (tab != null && pendingFocusRunnable == null) { 272 pendingFocusRunnable = new Runnable () { 275 public void run() { 276 AbstractOutputTab tab = getSelectedTab(); 277 if (tab != null) { 278 tab.requestFocus(); 279 } 280 pendingFocusRunnable = null; 281 } 282 }; 283 SwingUtilities.invokeLater(pendingFocusRunnable); 284 } else { 285 super.requestFocus(); 286 } 287 } 288 289 private Runnable pendingFocusRunnable = null; 290 291 298 protected abstract void updateSingletonName(String name); 299 300 301 private AbstractOutputTab lastKnownSelection = null; 302 protected void fire(AbstractOutputTab formerSelection) { 303 AbstractOutputTab selection = getSelectedTab(); 304 if (formerSelection != selection) { 305 selectionChanged(formerSelection, selection); 306 lastKnownSelection = selection; 307 if (selection != null) { 308 setToolbarButtons(selection.getToolbarButtons()); 309 } else { 310 setToolbarButtons(new JButton[0]); 311 } 312 } 313 } 314 315 private void setToolbarButtons(JButton[] buttons) { 316 toolbar.removeAll(); 317 for (int i = 0; i < buttons.length; i++) { 318 toolbar.add(buttons[i]); 319 } 320 toolbar.revalidate(); 321 toolbar.repaint(); 322 323 } 324 325 public void stateChanged(ChangeEvent e) { 326 if (pane.getSelectedComponent() instanceof AbstractOutputPane) { 327 ((AbstractOutputPane) pane.getSelectedComponent()).ensureCaretPosition(); 328 } 329 fire(lastKnownSelection); 330 } 331 332 protected abstract void selectionChanged(AbstractOutputTab former, AbstractOutputTab current); 333 334 private final boolean isGtk = "GTK".equals(UIManager.getLookAndFeel().getID()) || UIManager.getLookAndFeel().getClass().getSuperclass().getName().indexOf("Synth") != -1; 341 public void paint(Graphics g) { 342 if (isGtk) { 343 Color c = getBackground(); 345 if (c == null) c = Color.WHITE; 346 g.setColor(c); 347 g.fillRect(0, 0, getWidth(), getHeight()); 348 } 349 super.paint(g); 350 } 351 352 358 public final void selectNextTab(AbstractOutputTab tab) { 359 AbstractOutputTab[] tabs = this.getTabs(); 360 if (tabs.length > 1) { 361 int nextTabIndex = getSelectedTabIndex(tabs, tab) + 1; 362 if (nextTabIndex > (tabs.length - 1)) { 363 nextTabIndex = 0; 364 } 365 this.setSelectedTab(tabs[nextTabIndex]); 366 } 367 } 368 369 375 public final void selectPreviousTab(AbstractOutputTab tab) { 376 AbstractOutputTab[] tabs = this.getTabs(); 377 if (tabs.length > 1) { 378 int prevTabIndex = getSelectedTabIndex(tabs, tab) - 1; 379 if (prevTabIndex < 0) { 380 prevTabIndex = tabs.length - 1; 381 } 382 this.setSelectedTab(tabs[prevTabIndex]); 383 } 384 } 385 386 private int getSelectedTabIndex(AbstractOutputTab[] tabs, AbstractOutputTab tab) { 387 for (int i = 0; i < tabs.length; i++) { 388 if (tabs[i] == tab) { 389 return i; 390 } 391 } 392 return -1; 393 } 394 395 private void checkWinXPLFBug() { 400 if ("Windows".equals(UIManager.getLookAndFeel().getID())) { TabbedPaneUI ui = pane.getUI(); 402 try { 403 Method method = ui.getClass().getDeclaredMethod("setRolloverTab", new Class [] {Integer.TYPE}); if (method != null) { 405 method.setAccessible(true); 406 method.invoke(ui, new Object [] { new Integer (-1) }); 407 method.setAccessible(false); 408 } 409 } catch (Exception exc) { 410 } 412 } 413 } 414 415 private class VariableRightBorder implements Border { 416 417 private JTabbedPane pane; 418 419 public VariableRightBorder(JTabbedPane pane) { 420 this.pane = pane; 421 } 422 423 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 424 if (pane.getParent() != AbstractOutputWindow.this) { 425 Color old = g.getColor(); 426 g.setColor(getColor()); 427 g.drawLine(x + width - 1, y, x + width - 1, y + height); 428 g.setColor(old); 429 } 430 } 431 432 public Color getColor() { 433 if (Utilities.isMac()) { 434 Color c1 = UIManager.getColor("controlShadow"); 435 Color c2 = UIManager.getColor("control"); 436 return new Color((c1.getRed() + c2.getRed()) / 2, 437 (c1.getGreen() + c2.getGreen()) / 2, 438 (c1.getBlue() + c2.getBlue()) / 2); 439 } else { 440 return UIManager.getColor("controlShadow"); 441 } 442 } 443 444 public Insets getBorderInsets(Component c) { 445 if (pane.getParent() == AbstractOutputWindow.this) { 446 return new Insets(0,0,0,0); 447 } 448 return new Insets(0, 0, 0, 2); 449 } 450 451 public boolean isBorderOpaque() { 452 return true; 453 } 454 455 } 456 457 } 458 | Popular Tags |