42 |
import java.awt.Dimension; |
import java.awt.Dimension; |
43 |
import java.awt.Graphics; |
import java.awt.Graphics; |
44 |
import java.awt.Insets; |
import java.awt.Insets; |
45 |
|
import java.awt.LayoutManager; |
46 |
import java.awt.Point; |
import java.awt.Point; |
47 |
import java.awt.Rectangle; |
import java.awt.Rectangle; |
48 |
|
import java.awt.event.ComponentAdapter; |
49 |
|
import java.awt.event.ComponentEvent; |
50 |
|
import java.io.Serializable; |
51 |
|
|
52 |
import javax.swing.border.Border; |
import javax.swing.border.Border; |
53 |
import javax.swing.event.ChangeEvent; |
import javax.swing.event.ChangeEvent; |
97 |
*/ |
*/ |
98 |
public class JViewport extends JComponent |
public class JViewport extends JComponent |
99 |
{ |
{ |
100 |
|
|
101 |
|
/** |
102 |
|
* A {@link java.awt.event.ComponentListener} that listens for |
103 |
|
* changes of the view's size. This class forbids changes of the view |
104 |
|
* component's size that would exceed the viewport's size. |
105 |
|
*/ |
106 |
|
protected class ViewListener |
107 |
|
extends ComponentAdapter |
108 |
|
implements Serializable |
109 |
|
{ |
110 |
|
/** |
111 |
|
* Creates a new instance of ViewListener. |
112 |
|
*/ |
113 |
|
protected ViewListener() |
114 |
|
{ |
115 |
|
} |
116 |
|
|
117 |
|
/** |
118 |
|
* Receives notification when a component (in this case: the view |
119 |
|
* component) changes it's size. |
120 |
|
* |
121 |
|
* @param ev the ComponentEvent describing the change |
122 |
|
*/ |
123 |
|
public void componentResized(ComponentEvent ev) |
124 |
|
{ |
125 |
|
// According to some tests that I did with Sun's implementation |
126 |
|
// this class is supposed to make sure that the view component |
127 |
|
// is not resized to a larger size than the viewport. |
128 |
|
// This is not documented anywhere. What I did is: I subclassed JViewport |
129 |
|
// and ViewListener and 'disabled' the componentResized method by |
130 |
|
// overriding it and not calling super.componentResized(). |
131 |
|
// When this method is disabled I can set the size on the view component |
132 |
|
// normally, when it is enabled, it gets immediatly resized back, |
133 |
|
// after a resize attempt that would exceed the Viewport's size. |
134 |
|
Component comp = ev.getComponent(); |
135 |
|
Dimension newSize = comp.getSize(); |
136 |
|
Dimension viewportSize = getSize(); |
137 |
|
boolean revert = false; |
138 |
|
if (newSize.width > viewportSize.width) |
139 |
|
{ |
140 |
|
newSize.width = viewportSize.width; |
141 |
|
revert = true; |
142 |
|
} |
143 |
|
if (newSize.height > viewportSize.height) |
144 |
|
{ |
145 |
|
newSize.height = viewportSize.height; |
146 |
|
revert = true; |
147 |
|
} |
148 |
|
if (revert == true) |
149 |
|
comp.setSize(newSize); |
150 |
|
} |
151 |
|
} |
152 |
|
|
153 |
private static final long serialVersionUID = -6925142919680527970L; |
private static final long serialVersionUID = -6925142919680527970L; |
154 |
|
|
155 |
public static final int SIMPLE_SCROLL_MODE = 0; |
public static final int SIMPLE_SCROLL_MODE = 0; |
182 |
|
|
183 |
Point lastPaintPosition; |
Point lastPaintPosition; |
184 |
|
|
185 |
|
/** |
186 |
|
* The ViewListener instance. |
187 |
|
*/ |
188 |
|
ViewListener viewListener; |
189 |
|
|
190 |
public JViewport() |
public JViewport() |
191 |
{ |
{ |
192 |
setOpaque(true); |
setOpaque(true); |
193 |
setScrollMode(BLIT_SCROLL_MODE); |
setScrollMode(BLIT_SCROLL_MODE); |
194 |
|
setLayout(createLayoutManager()); |
195 |
updateUI(); |
updateUI(); |
196 |
} |
} |
197 |
|
|
330 |
public void setView(Component v) |
public void setView(Component v) |
331 |
{ |
{ |
332 |
while (getComponentCount() > 0) |
while (getComponentCount() > 0) |
333 |
remove(0); |
{ |
334 |
|
if (viewListener != null) |
335 |
|
getView().removeComponentListener(viewListener); |
336 |
|
remove(0); |
337 |
|
} |
338 |
|
|
339 |
if (v != null) |
if (v != null) |
340 |
{ |
{ |
341 |
|
if (viewListener == null) |
342 |
|
viewListener = createViewListener(); |
343 |
|
v.addComponentListener(viewListener); |
344 |
add(v); |
add(v); |
345 |
fireStateChanged(); |
fireStateChanged(); |
346 |
} |
} |
463 |
if (border != null) |
if (border != null) |
464 |
throw new IllegalArgumentException(); |
throw new IllegalArgumentException(); |
465 |
} |
} |
466 |
|
|
467 |
|
/** |
468 |
|
* Creates a {@link ViewListener} that is supposed to listen for |
469 |
|
* size changes on the view component. |
470 |
|
* |
471 |
|
* @return a ViewListener instance |
472 |
|
*/ |
473 |
|
protected ViewListener createViewListener() |
474 |
|
{ |
475 |
|
return new ViewListener(); |
476 |
|
} |
477 |
|
|
478 |
|
/** |
479 |
|
* Creates the LayoutManager that is used for this viewport. Override |
480 |
|
* this method if you want to use a custom LayoutManager. |
481 |
|
* |
482 |
|
* @return a LayoutManager to use for this viewport |
483 |
|
*/ |
484 |
|
protected LayoutManager createLayoutManager() |
485 |
|
{ |
486 |
|
return new ViewportLayout(); |
487 |
|
} |
488 |
} |
} |