2
package org.crosswire.swing;
4
import java.awt.Insets;
5
import java.awt.Dimension;
6
import java.awt.Component;
7
import java.awt.Container;
8
import java.awt.LayoutManager2;
9
import java.io.Serializable;
10
import java.util.Hashtable;
11
import java.util.Enumeration;
14
* DeckLayout is very similar to the awt CardLayout, except the
15
* latter is supposed to have some focus problems. I've not
16
* come across these before, and DeckLayout seems to be
17
* broken anyway, so I don't use it at all.
18
* <p>DeckLayout treats each component in the container as a card.
19
* Only one card is visible at a time, and the container acts
20
* like a deck of cards.
21
* The ordering of cards is determined by the container's own
22
* internal ordering of its component objects. DeckLayout
23
* defines a set of methods that allow an application to flip
24
* through the cards sequentially, or to show a specified card.
25
* The addLayoutComponent method can be used to associate a
26
* string identifier with a given card for faster random access.
28
* <table border='1' cellPadding='3' cellSpacing='0' width="100%">
29
* <tr><td bgColor='white'class='TableRowColor'><font size='-7'>
30
* Distribution Licence:<br />
31
* Project B is free software; you can redistribute it
32
* and/or modify it under the terms of the GNU General Public License,
33
* version 2 as published by the Free Software Foundation.<br />
34
* This program is distributed in the hope that it will be useful,
35
* but WITHOUT ANY WARRANTY; without even the implied warranty of
36
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37
* General Public License for more details.<br />
38
* The License is available on the internet
39
* <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, by writing to
40
* <i>Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
41
* MA 02111-1307, USA</i>, Or locally at the Licence link below.<br />
42
* The copyright to this program is held by it's authors.
43
* </font></td></tr></table>
44
* @see <a href='http://www.eireneh.com/servlets/Web'>Project B Home</a>
45
* @see <{docs.Licence}>
47
* @author Claude Duguay Copyright (c) 1998
49
public class DeckLayout extends AbstractLayout implements LayoutManager2, Serializable
51
protected Hashtable tab = new Hashtable();
52
protected int count = 0;
53
protected boolean wrap = false;
60
public DeckLayout(boolean wrap)
65
public DeckLayout(int hgap, int vgap)
67
this(hgap, vgap, false);
70
public DeckLayout(int hgap, int vgap, boolean wrap)
77
* Adds the specified component to this deck layout's internal
78
* table, by name. The object specified by constraints must be
79
* a string. The deck layout stores this string as a key-value
80
* pair that can be used for random access to a particular card.
81
* By calling the show method, an application can display the
82
* component with the specified name.
83
* @param comp The component to be added.
84
* @param constraints A name that identifies the component
86
public void addLayoutComponent(Component comp, Object constraints)
88
if (constraints instanceof String || constraints == null)
90
addLayoutComponent((String) constraints, comp);
94
throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
99
* Removes the specified component from the layout.
100
* @param comp The component to be removed.
102
public void removeLayoutComponent(Component comp)
104
Enumeration enum = tab.keys();
105
while(enum.hasMoreElements())
107
String key = (String)enum.nextElement();
108
if (tab.get(key) == comp)
118
* Calculates the preferred size for the specified panel.
119
* @param parent The name of the parent container
120
* @return minimum dimensions required to lay out the components.
122
public Dimension preferredLayoutSize(Container parent)
124
Insets insets = parent.getInsets();
125
int ncomponents = parent.getComponentCount();
129
for (int i = 0 ; i < ncomponents ; i++)
131
Component comp = parent.getComponent(i);
132
Dimension d = comp.getPreferredSize();
142
return new Dimension(
143
insets.left + insets.right + w + hgap * 2,
144
insets.top + insets.bottom + h + vgap * 2);
148
* Calculates the minimum size for the specified panel.
149
* @param parent The name of the parent container
150
* @return minimum dimensions required to lay out the components.
152
public Dimension minimumLayoutSize(Container parent)
154
Insets insets = parent.getInsets();
155
int ncomponents = parent.getComponentCount();
159
for (int i = 0 ; i < ncomponents ; i++)
161
Component comp = parent.getComponent(i);
162
Dimension d = comp.getMinimumSize();
172
return new Dimension(
173
insets.left + insets.right + w + hgap * 2,
174
insets.top + insets.bottom + h + vgap * 2);
178
* Lays out the specified container using this deck layout.
179
* Each component in the parent container is reshaped to be
180
* the same size as the container, minus insets, horizontal
182
* @param parent The name of the parent container
184
public void layoutContainer(Container parent)
186
Insets insets = parent.getInsets();
187
int ncomponents = parent.getComponentCount();
188
for (int i = 0 ; i < ncomponents ; i++)
190
Component comp = parent.getComponent(i);
191
if (comp.isVisible())
193
comp.setBounds(hgap + insets.left, vgap + insets.top,
194
parent.getSize().width - (hgap * 2 + insets.left + insets.right),
195
parent.getSize().height - (vgap * 2 + insets.top + insets.bottom));
201
* Make sure that the Container really has this layout installed,
202
* to avoid serious problems.
204
private void checkLayout(Container parent)
206
if (parent.getLayout() != this)
208
throw new IllegalArgumentException("wrong parent for CardLayout");
213
* Enable or disable the specified component and all its children.
214
* This makes focus traversal function properly. The side effect
215
* is that all children are enabled or disabled and specific
216
* contexts are not maintained. You can get around this by
217
* intercepting setEnabled in your component to restore state
218
* if this is important in your context.
220
private void setActive(Component comp, boolean enabled)
222
comp.setVisible(enabled);
223
comp.setEnabled(enabled);
224
if (comp instanceof Container)
226
Container cont = (Container)comp;
227
int count = cont.getComponentCount();
228
for (int i = 0; i < count; i++)
230
setActive(cont.getComponent(i), enabled);
236
* Flips to the first card of the container.
237
* @param parent The name of the parent container
239
public void first(Container parent)
241
synchronized (parent.getTreeLock())
244
int ncomponents = parent.getComponentCount();
245
for (int i = 0 ; i < ncomponents ; i++)
247
Component comp = parent.getComponent(i);
248
if (comp.isVisible())
250
setActive(comp, false);
251
comp = parent.getComponent(0);
252
setActive(comp, true);
261
* Flips to the next card of the specified container. If the
262
* currently visible card is the last one, this method flips
263
* to the first card in the layout.
264
* @param parent The name of the parent container
265
* @return Index of the selected component
267
public int next(Container parent)
269
synchronized (parent.getTreeLock())
272
int ncomponents = parent.getComponentCount();
273
for (int i = 0 ; i < ncomponents ; i++)
275
Component comp = parent.getComponent(i);
276
if (comp.isVisible())
278
if (i + 1 >= ncomponents && !wrap) return i;
279
int index = (i + 1 < ncomponents) ? i + 1 : 0;
280
setActive(comp, false);
281
comp = parent.getComponent(index);
282
setActive(comp, true);
292
* Flips to the previous card of the specified container. If the
293
* currently visible card is the first one, this method flips to
294
* the last card in the layout.
295
* @param parent The name of the parent container
296
* @return Index of the selected component
298
public int previous(Container parent)
300
synchronized (parent.getTreeLock())
303
int ncomponents = parent.getComponentCount();
304
for (int i = 0 ; i < ncomponents ; i++)
306
Component comp = parent.getComponent(i);
307
if (comp.isVisible())
309
if (i <= 0 && !wrap) return i;
310
setActive(comp, false);
311
int index = (i > 0) ? i - 1 : ncomponents - 1;
312
comp = parent.getComponent(index);
313
setActive(comp, true);
323
* Flips to the last card of the container.
324
* @param parent The name of the parent container
326
public void last(Container parent)
328
synchronized (parent.getTreeLock())
331
int ncomponents = parent.getComponentCount();
332
for (int i = 0 ; i < ncomponents ; i++)
334
Component comp = parent.getComponent(i);
335
if (comp.isVisible())
337
setActive(comp, false);
338
comp = parent.getComponent(ncomponents - 1);
339
setActive(comp, true);
348
* Flips to the component that was added to this layout using
349
* the specified name. If no such component exists, nothing happens.
350
* @param parent The name of the parent container in which to do the layout.
351
* @param name The component name.
353
public void show(Container parent, String name)
355
synchronized (parent.getTreeLock())
358
Component next = (Component)tab.get(name);
359
if (next != null && !next.isVisible())
361
int ncomponents = parent.getComponentCount();
362
for (int i=0; i<ncomponents; i++)
364
Component comp = parent.getComponent(i);
365
if (comp.isVisible())
367
setActive(comp, false);
371
setActive(next, true);
378
* Flips to the component at the numbered position. If no such
379
* component exists, nothing happens.
380
* @param parent The name of the parent container in which to do the layout.
381
* @param index The index (between 0 and component count - 1)
383
public void show(Container parent, int index)
385
synchronized (parent.getTreeLock())
388
if (index < 0 || index > parent.getComponentCount() - 1)
390
int ncomponents = parent.getComponentCount();
392
for (int i = 0 ; i < ncomponents ; i++)
394
Component comp = parent.getComponent(i);
395
if (comp.isVisible())
397
setActive(comp, false);
398
comp = parent.getComponent(index);
399
setActive(comp, true);
407
public Component getComponent(String name)
409
return (Component) tab.get(name);
412
public String getName(Container parent, int index)
414
Component comp = parent.getComponent(index);
415
Enumeration keys = tab.keys();
416
Enumeration enum = tab.elements();
419
while (enum.hasMoreElements())
421
key = (String) keys.nextElement();
422
if (comp == enum.nextElement())
429
public int getIndex(Container parent, String name)
431
Component comp = getComponent(name);
432
for (int i = 0; i < parent.getComponentCount(); i++)
434
if (parent.getComponent(i) == comp)