1 7 8 package com.sun.java.swing.plaf.windows; 9 10 import java.beans.PropertyChangeListener ; 11 import java.beans.PropertyChangeEvent ; 12 import javax.swing.plaf.basic.*; 13 import javax.swing.plaf.*; 14 import javax.swing.border.*; 15 import javax.swing.*; 16 import java.awt.event.*; 17 import java.awt.*; 18 19 import com.sun.java.swing.plaf.windows.TMSchema.*; 20 import com.sun.java.swing.plaf.windows.XPStyle.Skin; 21 import sun.swing.DefaultLookup; 22 23 37 38 public class WindowsComboBoxUI extends BasicComboBoxUI { 39 40 private static final MouseListener rolloverListener = 41 new MouseAdapter() { 42 private void handleRollover(MouseEvent e, boolean isRollover) { 43 JComboBox comboBox = getComboBox(e); 44 WindowsComboBoxUI comboBoxUI = getWindowsComboBoxUI(e); 45 if (comboBox == null || comboBoxUI == null) { 46 return; 47 } 48 if (! comboBox.isEditable()) { 49 ButtonModel m = null; 52 if (comboBoxUI.arrowButton != null) { 53 m = comboBoxUI.arrowButton.getModel(); 54 } 55 if (m != null ) { 56 m.setRollover(isRollover); 57 } 58 } 59 comboBoxUI.isRollover = isRollover; 60 comboBox.repaint(); 61 } 62 63 public void mouseEntered(MouseEvent e) { 64 handleRollover(e, true); 65 } 66 67 public void mouseExited(MouseEvent e) { 68 handleRollover(e, false); 69 } 70 71 private JComboBox getComboBox(MouseEvent event) { 72 Object source = event.getSource(); 73 JComboBox rv = null; 74 if (source instanceof JComboBox) { 75 rv = (JComboBox) source; 76 } else if (source instanceof XPComboBoxButton) { 77 rv = ((XPComboBoxButton) source) 78 .getWindowsComboBoxUI().comboBox; 79 } 80 return rv; 81 } 82 83 private WindowsComboBoxUI getWindowsComboBoxUI(MouseEvent event) { 84 JComboBox comboBox = getComboBox(event); 85 WindowsComboBoxUI rv = null; 86 if (comboBox != null 87 && comboBox.getUI() instanceof WindowsComboBoxUI) { 88 rv = (WindowsComboBoxUI) comboBox.getUI(); 89 } 90 return rv; 91 } 92 93 }; 94 private boolean isRollover = false; 95 96 private static final PropertyChangeListener componentOrientationListener = 97 new PropertyChangeListener () { 98 public void propertyChange(PropertyChangeEvent e) { 99 String propertyName = e.getPropertyName(); 100 Object source = null; 101 if ("componentOrientation" == propertyName 102 && (source = e.getSource()) instanceof JComboBox 103 && ((JComboBox) source).getUI() instanceof 104 WindowsComboBoxUI) { 105 JComboBox comboBox = (JComboBox) source; 106 WindowsComboBoxUI comboBoxUI = (WindowsComboBoxUI) comboBox.getUI(); 107 if (comboBoxUI.arrowButton instanceof XPComboBoxButton) { 108 ((XPComboBoxButton) comboBoxUI.arrowButton).setPart( 109 (comboBox.getComponentOrientation() == 110 ComponentOrientation.RIGHT_TO_LEFT) 111 ? Part.CP_DROPDOWNBUTTONLEFT 112 : Part.CP_DROPDOWNBUTTONRIGHT); 113 } 114 } 115 } 116 }; 117 118 public static ComponentUI createUI(JComponent c) { 119 return new WindowsComboBoxUI(); 120 } 121 122 public void installUI( JComponent c ) { 123 super.installUI( c ); 124 isRollover = false; 125 comboBox.setRequestFocusEnabled( true ); 126 if (XPStyle.getXP() != null && arrowButton != null) { 127 comboBox.addMouseListener(rolloverListener); 130 arrowButton.addMouseListener(rolloverListener); 131 } 132 } 133 134 public void uninstallUI(JComponent c) { 135 if (XPStyle.getXP() != null) { 136 comboBox.removeMouseListener(rolloverListener); 137 arrowButton.removeMouseListener(rolloverListener); 138 } 139 super.uninstallUI( c ); 140 } 141 142 @Override 143 protected void installListeners() { 144 super.installListeners(); 145 XPStyle xp = XPStyle.getXP(); 146 if (xp != null 148 && xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) { 149 comboBox.addPropertyChangeListener("componentOrientation", 150 componentOrientationListener); 151 } 152 } 153 154 @Override 155 protected void uninstallListeners() { 156 super.uninstallListeners(); 157 comboBox.removePropertyChangeListener("componentOrientation", 158 componentOrientationListener); 159 } 160 161 @Override 162 protected void configureEditor() { 163 super.configureEditor(); 164 if (XPStyle.getXP() != null) { 165 editor.addMouseListener(rolloverListener); 166 } 167 } 168 169 @Override 170 protected void unconfigureEditor() { 171 super.unconfigureEditor(); 172 if (XPStyle.getXP() != null) { 173 editor.removeMouseListener(rolloverListener); 174 } 175 } 176 177 @Override 178 public void paint(Graphics g, JComponent c) { 179 if (XPStyle.getXP() != null) { 180 paintXPComboBoxBackground(g, c); 181 } 182 super.paint(g, c); 183 } 184 185 State getXPComboBoxState(JComponent c) { 186 State state = State.NORMAL; 187 if (!c.isEnabled()) { 188 state = State.DISABLED; 189 } else if (isPopupVisible(comboBox)) { 190 state = State.PRESSED; 191 } else if (isRollover) { 192 state = State.HOT; 193 } 194 return state; 195 } 196 197 private void paintXPComboBoxBackground(Graphics g, JComponent c) { 198 XPStyle xp = XPStyle.getXP(); 199 State state = getXPComboBoxState(c); 200 Skin skin = null; 201 if (! comboBox.isEditable() 202 && xp.isSkinDefined(c, Part.CP_READONLY)) { 203 skin = xp.getSkin(c, Part.CP_READONLY); 204 } 205 if (skin == null) { 206 skin = xp.getSkin(c, Part.CP_COMBOBOX); 207 } 208 skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state); 209 } 210 211 220 public void paintCurrentValue(Graphics g, Rectangle bounds, 221 boolean hasFocus) { 222 XPStyle xp = XPStyle.getXP(); 223 if (xp != null) { 224 bounds.x += 2; 225 bounds.y += 2; 226 bounds.width -= 3; 227 bounds.height -= 4; 228 } else { 229 bounds.x += 1; 230 bounds.y += 1; 231 bounds.width -= 2; 232 bounds.height -= 2; 233 } 234 if (! comboBox.isEditable() 235 && xp != null 236 && xp.isSkinDefined(comboBox, Part.CP_READONLY)) { 237 240 ListCellRenderer renderer = comboBox.getRenderer(); 242 Component c; 243 if ( hasFocus && !isPopupVisible(comboBox) ) { 244 c = renderer.getListCellRendererComponent( 245 listBox, 246 comboBox.getSelectedItem(), 247 -1, 248 true, 249 false ); 250 } else { 251 c = renderer.getListCellRendererComponent( 252 listBox, 253 comboBox.getSelectedItem(), 254 -1, 255 false, 256 false ); 257 } 258 c.setFont(comboBox.getFont()); 259 if ( comboBox.isEnabled() ) { 260 c.setForeground(comboBox.getForeground()); 261 c.setBackground(comboBox.getBackground()); 262 } else { 263 c.setForeground(DefaultLookup.getColor( 264 comboBox, this, "ComboBox.disabledForeground", null)); 265 c.setBackground(DefaultLookup.getColor( 266 comboBox, this, "ComboBox.disabledBackground", null)); 267 } 268 boolean shouldValidate = false; 269 if (c instanceof JPanel) { 270 shouldValidate = true; 271 } 272 currentValuePane.paintComponent(g, c, comboBox, bounds.x, bounds.y, 273 bounds.width, bounds.height, shouldValidate); 274 275 } else { 276 super.paintCurrentValue(g, bounds, hasFocus); 277 } 278 } 279 280 @Override 281 public void paintCurrentValueBackground(Graphics g, Rectangle bounds, 282 boolean hasFocus) { 283 if (XPStyle.getXP() == null) { 284 super.paintCurrentValueBackground(g, bounds, hasFocus); 285 } 286 } 287 288 public Dimension getPreferredSize( JComponent c ) { 289 Dimension d = super.getPreferredSize(c); 290 d.width += 4; 291 d.height += 2; 292 if (XPStyle.getXP() != null) { 293 d.height += 2; 294 } 295 return d; 296 } 297 298 304 protected LayoutManager createLayoutManager() { 305 return new BasicComboBoxUI.ComboBoxLayoutManager() { 306 public void layoutContainer(Container parent) { 307 super.layoutContainer(parent); 308 309 if (XPStyle.getXP() != null && arrowButton != null) { 310 Dimension d = parent.getSize(); 311 Insets insets = getInsets(); 312 int buttonWidth = arrowButton.getPreferredSize().width; 313 arrowButton.setBounds(WindowsUtils.isLeftToRight((JComboBox)parent) 314 ? (d.width - insets.right - buttonWidth) 315 : insets.left, 316 insets.top, 317 buttonWidth, d.height - insets.top - insets.bottom); 318 } 319 } 320 }; 321 } 322 323 protected void installKeyboardActions() { 324 super.installKeyboardActions(); 325 } 326 327 protected ComboPopup createPopup() { 328 return super.createPopup(); 329 } 330 331 339 protected ComboBoxEditor createEditor() { 340 return new WindowsComboBoxEditor(); 341 } 342 343 @Override 344 protected ListCellRenderer createRenderer() { 345 XPStyle xp = XPStyle.getXP(); 346 if (xp != null && xp.isSkinDefined(comboBox, Part.CP_READONLY)) { 347 return new WindowsComboBoxRenderer(); 348 } else { 349 return super.createRenderer(); 350 } 351 } 352 353 359 protected JButton createArrowButton() { 360 if (XPStyle.getXP() != null) { 361 return new XPComboBoxButton(); 362 } else { 363 return super.createArrowButton(); 364 } 365 } 366 367 private class XPComboBoxButton extends XPStyle.GlyphButton { 368 public XPComboBoxButton() { 369 super(null, 370 (! XPStyle.getXP().isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) 371 ? Part.CP_DROPDOWNBUTTON 372 : (comboBox.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) 373 ? Part.CP_DROPDOWNBUTTONLEFT 374 : Part.CP_DROPDOWNBUTTONRIGHT 375 ); 376 setRequestFocusEnabled(false); 377 } 378 379 @Override 380 protected State getState() { 381 State rv; 382 rv = super.getState(); 383 if (rv != State.DISABLED 384 && ! comboBox.isEditable() 385 && XPStyle.getXP().isSkinDefined(comboBox, 386 Part.CP_DROPDOWNBUTTONRIGHT)) { 387 391 rv = State.NORMAL; 392 } 393 return rv; 394 } 395 396 public Dimension getPreferredSize() { 397 return new Dimension(17, 20); 398 } 399 400 void setPart(Part part) { 401 setPart(comboBox, part); 402 } 403 404 WindowsComboBoxUI getWindowsComboBoxUI() { 405 return WindowsComboBoxUI.this; 406 } 407 } 408 409 417 @Deprecated 418 protected class WindowsComboPopup extends BasicComboPopup { 419 420 public WindowsComboPopup( JComboBox cBox ) { 421 super( cBox ); 422 } 423 424 protected KeyListener createKeyListener() { 425 return new InvocationKeyHandler(); 426 } 427 428 protected class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler { 429 protected InvocationKeyHandler() { 430 WindowsComboPopup.this.super(); 431 } 432 } 433 } 434 435 436 439 public static class WindowsComboBoxEditor 440 extends BasicComboBoxEditor.UIResource { 441 442 public void setItem(Object item) { 443 super.setItem(item); 444 if (editor.hasFocus()) { 445 editor.selectAll(); 446 } 447 } 448 } 449 450 454 private static class WindowsComboBoxRenderer 455 extends BasicComboBoxRenderer.UIResource { 456 private static final Object BORDER_KEY = new StringBuilder ("BORDER_KEY"); 457 private static final Border NULL_BORDER = new EmptyBorder(0, 0, 0, 0); 458 461 @Override 462 public Component getListCellRendererComponent( 463 JList list, 464 Object value, 465 int index, 466 boolean isSelected, 467 boolean cellHasFocus) { 468 Component rv = 469 super.getListCellRendererComponent(list, value, index, 470 isSelected, cellHasFocus); 471 if (rv instanceof JComponent) { 472 JComponent component = (JComponent) rv; 473 if (index == -1 && isSelected) { 474 Border border = component.getBorder(); 475 Border dashedBorder = 476 new WindowsBorders.DashedBorder(list.getForeground()); 477 component.setBorder(dashedBorder); 478 if (component.getClientProperty(BORDER_KEY) == null) { 480 component.putClientProperty(BORDER_KEY, 481 (border == null) ? NULL_BORDER : border); 482 } 483 } else { 484 if (component.getBorder() instanceof 485 WindowsBorders.DashedBorder) { 486 Object storedBorder = component.getClientProperty(BORDER_KEY); 487 if (storedBorder instanceof Border) { 488 component.setBorder( 489 (storedBorder == NULL_BORDER) ? null 490 : (Border) storedBorder); 491 } 492 component.putClientProperty(BORDER_KEY, null); 493 } 494 } 495 if (index == -1) { 496 component.setOpaque(false); 497 component.setForeground(list.getForeground()); 498 } else { 499 component.setOpaque(true); 500 } 501 } 502 return rv; 503 } 504 505 } 506 } 507 | Popular Tags |