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