1. /*
  2. * @(#)WindowsComboBoxUI.java 1.21 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.windows;
  8. import javax.swing.plaf.basic.*;
  9. import javax.swing.plaf.*;
  10. import javax.swing.border.*;
  11. import javax.swing.*;
  12. import java.awt.event.*;
  13. import java.awt.*;
  14. /**
  15. * Windows combo box.
  16. * <p>
  17. * <strong>Warning:</strong>
  18. * Serialized objects of this class will not be compatible with
  19. * future Swing releases. The current serialization support is appropriate
  20. * for short term storage or RMI between applications running the same
  21. * version of Swing. A future release of Swing will provide support for
  22. * long term persistence.
  23. *
  24. * @version 1.18 10/30/98
  25. * @author Tom Santos
  26. */
  27. public class WindowsComboBoxUI extends BasicComboBoxUI {
  28. private static final JTextField sizer = new JTextField();
  29. public static ComponentUI createUI(JComponent c) {
  30. return new WindowsComboBoxUI();
  31. }
  32. public void installUI( JComponent c ) {
  33. super.installUI( c );
  34. comboBox.setRequestFocusEnabled( true );
  35. }
  36. public Dimension getMinimumSize( JComponent c ) {
  37. if ( !isMinimumSizeDirty ) {
  38. return new Dimension( cachedMinimumSize );
  39. }
  40. Dimension size = getDisplaySize();
  41. Insets insets = getInsets();
  42. if ( comboBox.getRenderer() instanceof UIResource ) {
  43. sizer.setFont( comboBox.getFont() );
  44. size.height = sizer.getPreferredSize().height;
  45. }
  46. else {
  47. size.height += insets.top + insets.bottom;
  48. }
  49. int buttonSize = size.height - (insets.top + insets.bottom);
  50. size.width += insets.left + insets.right + buttonSize;
  51. cachedMinimumSize.setSize( size.width, size.height );
  52. isMinimumSizeDirty = false;
  53. return size;
  54. }
  55. protected void selectNextPossibleValue() {
  56. super.selectNextPossibleValue();
  57. }
  58. protected void selectPreviousPossibleValue() {
  59. super.selectPreviousPossibleValue();
  60. }
  61. JComboBox windowsGetComboBox() {
  62. return comboBox;
  63. }
  64. protected void installKeyboardActions() {
  65. super.installKeyboardActions();
  66. ActionListener downAction = new ActionListener() {
  67. public void actionPerformed( ActionEvent e ) {
  68. if ( windowsGetComboBox().isEnabled() ) {
  69. if ( !windowsGetComboBox().isEditable() ||
  70. (windowsGetComboBox().isEditable() && isPopupVisible(windowsGetComboBox())) ) {
  71. selectNextPossibleValue();
  72. }
  73. }
  74. }
  75. };
  76. comboBox.registerKeyboardAction( downAction,
  77. KeyStroke.getKeyStroke( KeyEvent.VK_DOWN, 0 ),
  78. JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  79. ActionListener upAction = new ActionListener() {
  80. public void actionPerformed( ActionEvent e ) {
  81. if ( windowsGetComboBox().isEnabled() ) {
  82. if ( !windowsGetComboBox().isEditable() ||
  83. (windowsGetComboBox().isEditable() && isPopupVisible(windowsGetComboBox())) ) {
  84. selectPreviousPossibleValue();
  85. }
  86. }
  87. }
  88. };
  89. comboBox.registerKeyboardAction( upAction,
  90. KeyStroke.getKeyStroke( KeyEvent.VK_UP, 0 ),
  91. JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  92. }
  93. void windowsSetPopupVisible( boolean visible ) {
  94. setPopupVisible( comboBox, visible );
  95. }
  96. protected void uninstallKeyboardActions() {
  97. super.uninstallKeyboardActions();
  98. comboBox.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0));
  99. comboBox.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0));
  100. }
  101. protected ComboPopup createPopup() {
  102. return new WindowsComboPopup( comboBox );
  103. }
  104. /**
  105. * This inner class is marked "public" due to a compiler bug.
  106. * This class should be treated as a "protected" inner class.
  107. * Instantiate it only within subclasses of <FooUI>.
  108. */
  109. public class WindowsComboPopup extends BasicComboPopup {
  110. // This is here because the compiler isn't currently letting this
  111. // inner class have access to its parent's inherited data members.
  112. JComboBox comboBox;
  113. public WindowsComboPopup( JComboBox cBox ) {
  114. super( cBox );
  115. comboBox = cBox;
  116. }
  117. protected KeyListener createKeyListener() {
  118. return new InvocationKeyHandler();
  119. }
  120. /**
  121. * This inner class is marked "public" due to a compiler bug.
  122. * This class should be treated as a "protected" inner class.
  123. * Instantiate it only within subclasses of <FooUI>.
  124. */
  125. public class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler {
  126. public void keyReleased( KeyEvent e ) {
  127. if ( e.getKeyCode() == KeyEvent.VK_F4 ) {
  128. if ( isVisible() ) {
  129. hide();
  130. }
  131. else {
  132. show();
  133. }
  134. }
  135. else if ( e.isAltDown() && e.getKeyCode() != KeyEvent.VK_ALT ) {
  136. if ( e.getKeyCode() == KeyEvent.VK_UP ||
  137. e.getKeyCode() == KeyEvent.VK_DOWN ) {
  138. if ( isVisible() ) {
  139. hide();
  140. }
  141. else {
  142. show();
  143. }
  144. }
  145. }
  146. else if ( comboBox.isEditable() &&
  147. !isVisible() &&
  148. (e.getKeyCode() == KeyEvent.VK_UP ||
  149. e.getKeyCode() == KeyEvent.VK_DOWN) ) {
  150. show();
  151. }
  152. else if ( !comboBox.isEditable() && isVisible() ) {
  153. super.keyReleased( e );
  154. }
  155. }
  156. }
  157. }
  158. }