1. /*
  2. * @(#)ViewportLayout.java 1.28 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 javax.swing;
  8. import java.awt.LayoutManager;
  9. import java.awt.Component;
  10. import java.awt.Container;
  11. import java.awt.Rectangle;
  12. import java.awt.Point;
  13. import java.awt.Dimension;
  14. import java.awt.Insets;
  15. import java.io.Serializable;
  16. /**
  17. * The default layout manager for JViewport. JViewportLayout defines
  18. * a policy for layout that should be useful for most applications.
  19. * The viewport makes its view the same size as the viewport,
  20. * however it will not make the view smaller than its minimum size.
  21. * As the viewport grows the view is kept bottom justified until
  22. * the entire view is visible, subsequently the view is kept top
  23. * justified.
  24. * <p>
  25. * <strong>Warning:</strong>
  26. * Serialized objects of this class will not be compatible with
  27. * future Swing releases. The current serialization support is appropriate
  28. * for short term storage or RMI between applications running the same
  29. * version of Swing. A future release of Swing will provide support for
  30. * long term persistence.
  31. *
  32. * @version 1.28 11/29/01
  33. * @author Hans Muller
  34. */
  35. public class ViewportLayout implements LayoutManager, Serializable
  36. {
  37. /**
  38. * Adds the specified component to the layout. Not used by this class.
  39. * @param name the name of the component
  40. * @param comp the the component to be added
  41. */
  42. public void addLayoutComponent(String name, Component c) { }
  43. /**
  44. * Removes the specified component from the layout. Not used by
  45. * this class.
  46. * @param comp the component to remove
  47. */
  48. public void removeLayoutComponent(Component c) { }
  49. /**
  50. * Returns the preferred dimensions for this layout given the components
  51. * in the specified target container.
  52. * @param target the component which needs to be laid out
  53. * @return a Dimension object containing the preferred dimensions
  54. * @see #minimumLayoutSize
  55. */
  56. public Dimension preferredLayoutSize(Container parent) {
  57. Component view = ((JViewport)parent).getView();
  58. if (view == null) {
  59. return new Dimension(0, 0);
  60. }
  61. else if (view instanceof Scrollable) {
  62. return ((Scrollable)view).getPreferredScrollableViewportSize();
  63. }
  64. else {
  65. return view.getPreferredSize();
  66. }
  67. }
  68. /**
  69. * Returns the minimum dimensions needed to layout the components
  70. * contained in the specified target container.
  71. *
  72. * @param target the component which needs to be laid out
  73. * @return a Dimension object containing the minimum dimensions
  74. * @see #preferredLayoutSize
  75. */
  76. public Dimension minimumLayoutSize(Container parent) {
  77. return new Dimension(4, 4);
  78. }
  79. /**
  80. * Called by the AWT when the specified container needs to be laid out.
  81. *
  82. * @param parent the container to lay out
  83. *
  84. * @exception AWTError if the target isn't the container specified to the
  85. * BoxLayout constructor
  86. */
  87. public void layoutContainer(Container parent)
  88. {
  89. JViewport vp = (JViewport)parent;
  90. Component view = vp.getView();
  91. Scrollable scrollableView = null;
  92. if (view == null) {
  93. return;
  94. }
  95. else if (view instanceof Scrollable) {
  96. scrollableView = (Scrollable) view;
  97. }
  98. /* All of the dimensions below are in view coordinates, except
  99. * vpSize which we're converting.
  100. */
  101. Insets insets = vp.getInsets();
  102. Dimension viewPrefSize = view.getPreferredSize();
  103. Dimension vpSize = vp.getSize();
  104. Dimension extentSize = vp.toViewCoordinates(vpSize);
  105. Dimension viewSize = new Dimension(viewPrefSize);
  106. if (scrollableView != null) {
  107. if (scrollableView.getScrollableTracksViewportWidth()) {
  108. viewSize.width = vpSize.width;
  109. }
  110. if (scrollableView.getScrollableTracksViewportHeight()) {
  111. viewSize.height = vpSize.height;
  112. }
  113. }
  114. Point viewPosition = vp.getViewPosition();
  115. /* If the new viewport size would leave empty space to the
  116. * right of the view, right justify the view or left justify
  117. * the view when the width of the view is smaller than the
  118. * container.
  119. */
  120. if ((viewPosition.x + extentSize.width) > viewSize.width) {
  121. viewPosition.x = Math.max(0, viewSize.width - extentSize.width);
  122. }
  123. /* If the new viewport size would leave empty space below the
  124. * view, bottom justify the view or top justify the view when
  125. * the height of the view is smaller than the container.
  126. */
  127. if ((viewPosition.y + extentSize.height) > viewSize.height) {
  128. viewPosition.y = Math.max(0, viewSize.height - extentSize.height);
  129. }
  130. /* If we haven't been advised about how the viewports size
  131. * should change wrt to the viewport, i.e. if the view isn't
  132. * an instance of Scrollable, then adjust the views size as follows.
  133. *
  134. * If the orgin of the view is showing and the viewport is
  135. * bigger than the views preferred size, then make the view
  136. * the same size as the viewport.
  137. */
  138. if (scrollableView == null) {
  139. if ((viewPosition.x == 0) && (vpSize.width > viewPrefSize.width)) {
  140. viewSize.width = vpSize.width;
  141. }
  142. if ((viewPosition.y == 0) && (vpSize.height > viewPrefSize.height)) {
  143. viewSize.height = vpSize.height;
  144. }
  145. }
  146. vp.setViewPosition(viewPosition);
  147. vp.setViewSize(viewSize);
  148. }
  149. }