001    /*
002     * LAPIS lightweight structured text processing system
003     *
004     * Copyright (C) 1998-2002 Carnegie Mellon University,
005     * Copyright (C) 2003 Massachusetts Institute of Technology.
006     * All rights reserved.
007     *
008     * This library is free software; you can redistribute it
009     * and/or modify it under the terms of the GNU General
010     * Public License as published by the Free Software
011     * Foundation, version 2.
012     *
013     * LAPIS homepage: http://graphics.lcs.mit.edu/lapis/
014     */
015    
016    package lapisx.swing;
017    
018    import java.awt.*;
019    import javax.swing.*;
020    
021    public abstract class Layout {
022        Container container;
023        Size defaultSize = ANY_SIZE;
024        Alignment defaultAlignment = CENTER;
025        Insets defaultInsets = null;
026    
027        protected Layout (Container container) {
028            this.container = container;
029        }
030    
031        public static Layout horizontal () {
032            return horizontal (new JPanel ());
033        }
034    
035        public static Layout vertical () {
036            return vertical (new JPanel ());
037        }
038    
039        public static Layout border () {
040            return border (new JPanel ());
041        }
042    
043        public static Layout gridbag () {
044            return gridbag (new JPanel ());
045        }
046    
047        public static Layout horizontal (Container comp) {
048            comp.setLayout (new BoxLayout (comp, BoxLayout.X_AXIS));
049            return new BoxHandler (comp);
050        }
051    
052        public static Layout vertical (Container comp) {
053            comp.setLayout (new BoxLayout (comp, BoxLayout.Y_AXIS));
054            return new BoxHandler (comp);
055        }
056    
057        public static Layout border (Container comp) {
058            comp.setLayout (new BorderLayout ());
059            return new BorderHandler (comp);
060        }
061    
062        public static Layout gridbag (Container comp) {
063            comp.setLayout (new GridBagLayout ());
064            return new GridBagHandler (comp);
065        }
066    
067        public Layout add (Component comp) {
068            return add (comp, defaultSize, defaultAlignment, defaultInsets);
069        }
070    
071        public Layout add (Component comp, Size size) {
072            return add (comp, size, defaultAlignment, defaultInsets);
073        }
074    
075        public Layout add (Component comp, Alignment alignment) {
076            return add (comp, defaultSize, alignment, defaultInsets);
077        }
078    
079        public Layout add (Component comp, Size size, Alignment alignment) {
080            return add (comp, size, alignment, defaultInsets);
081        }
082    
083        public Layout add (Component comp, Insets insets) {
084            return add (comp, defaultSize, defaultAlignment, insets);
085        }
086    
087        public Layout add (Component comp, Size size, Insets insets) {
088            return add (comp, size, defaultAlignment, insets);
089        }
090    
091        public Layout add (Component comp, Alignment alignment, Insets insets) {
092            return add (comp, defaultSize, alignment, insets);
093        }
094    
095        public abstract Layout add (Component comp, Size size, Alignment alignment, Insets insets);
096    
097        public abstract Layout addGlue ();
098        public abstract Layout nextRow ();
099        public abstract Layout nextColumn ();
100    
101        public Container done () {
102            return container;
103        }
104    
105        public Layout setContainerInsets (int top, int left, 
106                                          int bottom, int right) {
107            ((JComponent)container).setBorder 
108                (BorderFactory.createEmptyBorder (top, left, bottom, right));
109            return this;
110        }
111    
112        public Layout setInsets (int top, int left, int bottom, int right) {
113            return setInsets (new Insets (top, left, bottom, right));
114        }
115    
116        public Layout setInsets (Insets insets) {
117            defaultInsets = insets;
118            return this;
119        }
120    
121        public Layout setAlignment (Alignment alignment) {
122            defaultAlignment = alignment;
123            return this;
124        }
125    
126        public Layout setSize (Size size) {
127            defaultSize = size;
128            return this;
129        }
130    
131        
132        static class BoxHandler extends Layout {
133            public BoxHandler (Container container) {
134                super (container);
135            }
136    
137            public Layout add (Component comp, Size size, 
138                               Alignment alignment, Insets insets) {
139                if (comp instanceof JComponent) {
140                    JComponent jc = (JComponent)comp;
141                    size.set (jc);
142                    alignment.set (jc);
143                    if (insets != null)
144                        jc.setBorder (BorderFactory.createEmptyBorder 
145                                      (insets.top, insets.left, 
146                                       insets.bottom, insets.right));
147                }
148                container.add (comp);
149                return this;
150            }
151    
152            public Layout addGlue () {
153                container.add (Box.createGlue ());
154                return this;
155            }
156    
157            public Layout nextRow () {
158                throw new RuntimeException ("not supported by BoxLayout");
159            }
160    
161            public Layout nextColumn () {
162                throw new RuntimeException ("not supported by BoxLayout");
163            }
164        }
165    
166        static class GridBagHandler extends Layout {
167            GridBagConstraints gbc = new GridBagConstraints ();
168            static final Insets NO_INSETS = new Insets (0, 0, 0, 0);
169    
170            public GridBagHandler (Container container) {
171                super (container);
172                gbc.gridx = 0;
173                gbc.gridy = 0;
174            }
175    
176            public Layout add (Component comp, Size size, 
177                               Alignment alignment, Insets insets) {
178                size.set (gbc);
179                alignment.set (gbc);
180                gbc.insets = (insets != null) ? insets : NO_INSETS;
181                container.add (comp, gbc);
182                nextColumn ();
183                return this;
184            }
185    
186            public Layout addGlue () {
187                throw new RuntimeException ("not supported by GridBagLayout");
188            }
189    
190            public Layout nextRow () {
191                ++gbc.gridy;
192                gbc.gridx = 0;
193                return this;
194            }
195    
196            public Layout nextColumn () {
197                ++gbc.gridx;
198                return this;
199            }
200        }
201    
202        static class BorderHandler extends Layout {
203            public BorderHandler (Container container) {
204                super (container);
205            }
206    
207            public Layout add (Component comp, Size size, 
208                               Alignment alignment, Insets insets) {
209                container.add (comp, alignment.getBorderName ());
210                return this;
211            }
212    
213            public Layout addGlue () {
214                throw new RuntimeException ("not supported by BorderLayout");
215            }
216    
217            public Layout nextRow () {
218                throw new RuntimeException ("not supported by BorderLayout");
219            }
220    
221            public Layout nextColumn () {
222                throw new RuntimeException ("not supported by BorderLayout");
223            }
224        }
225    
226        public static interface Size {
227            void set (JComponent c);
228            void set (GridBagConstraints c);
229        }
230        public static final Size ANY_SIZE = new Size () {
231            public void set (JComponent c) {
232            }
233            public void set (GridBagConstraints gbc) {
234                gbc.fill = GridBagConstraints.BOTH;
235                gbc.weightx = 1.0;
236                gbc.weighty = 1.0;
237            }
238        };
239        public static final Size FIXED_HEIGHT = new Size () {
240            public void set (JComponent c) {
241                c.setMaximumSize (new Dimension 
242                                  (Short.MAX_VALUE,
243                                   c.getPreferredSize ().height));
244            }
245            public void set (GridBagConstraints gbc) {
246                gbc.fill = GridBagConstraints.HORIZONTAL;
247                gbc.weightx = 1.0;
248                gbc.weighty = 0.0;
249            }
250        };
251        public static final Size FIXED_WIDTH = new Size () {
252            public void set (JComponent c) {
253                c.setMaximumSize (new Dimension 
254                                  (c.getPreferredSize ().width,
255                                   Short.MAX_VALUE));
256            }
257            public void set (GridBagConstraints gbc) {
258                gbc.fill = GridBagConstraints.VERTICAL;
259                gbc.weightx = 0.0;
260                gbc.weighty = 1.0;
261            }
262        };
263        public static final Size FIXED_SIZE = new Size () {
264            public void set (JComponent c) {
265                c.setMaximumSize (c.getPreferredSize ());
266            }
267            public void set (GridBagConstraints gbc) {
268                gbc.fill = GridBagConstraints.NONE;
269                gbc.weightx = 0.0;
270                gbc.weighty = 0.0;
271            }
272        };
273    
274    
275        public static interface Alignment {
276            void set (JComponent c);
277            void set (GridBagConstraints c);
278            String getBorderName ();
279        }
280        public static final Alignment CENTER = new Alignment () {
281            public void set (JComponent c) {
282                c.setAlignmentX (0.5f);
283                c.setAlignmentY (0.5f);
284            }
285            public void set (GridBagConstraints gbc) {
286                gbc.anchor = GridBagConstraints.CENTER;
287            }
288            public String getBorderName () {
289                return BorderLayout.CENTER;
290            }
291        };
292        public static final Alignment NORTH = new Alignment () {
293            public void set (JComponent c) {
294                c.setAlignmentX (0.5f);
295                c.setAlignmentY (0.0f);
296            }
297            public void set (GridBagConstraints gbc) {
298                gbc.anchor = GridBagConstraints.NORTH;
299            }
300            public String getBorderName () {
301                return BorderLayout.NORTH;
302            }
303        };
304        public static final Alignment NORTHEAST = new Alignment () {
305            public void set (JComponent c) {
306                c.setAlignmentX (1.0f);
307                c.setAlignmentY (0.0f);
308            }
309            public void set (GridBagConstraints gbc) {
310                gbc.anchor = GridBagConstraints.NORTHEAST;
311            }
312            public String getBorderName () {
313                throw new RuntimeException ("ambiguous with BorderLayout");
314            }
315        };
316        public static final Alignment EAST = new Alignment () {
317            public void set (JComponent c) {
318                c.setAlignmentX (1.0f);
319                c.setAlignmentY (0.5f);
320            }
321            public void set (GridBagConstraints gbc) {
322                gbc.anchor = GridBagConstraints.EAST;
323            }
324            public String getBorderName () {
325                return BorderLayout.EAST;
326            }
327        };
328        public static final Alignment SOUTHEAST = new Alignment () {
329            public void set (JComponent c) {
330                c.setAlignmentX (1.0f);
331                c.setAlignmentY (1.0f);
332            }
333            public void set (GridBagConstraints gbc) {
334                gbc.anchor = GridBagConstraints.SOUTHEAST;
335            }
336            public String getBorderName () {
337                throw new RuntimeException ("ambiguous with BorderLayout");
338            }
339        };
340        public static final Alignment SOUTH = new Alignment () {
341            public void set (JComponent c) {
342                c.setAlignmentX (0.5f);
343                c.setAlignmentY (1.0f);
344            }
345            public void set (GridBagConstraints gbc) {
346                gbc.anchor = GridBagConstraints.SOUTH;
347            }
348            public String getBorderName () {
349                return BorderLayout.SOUTH;
350            }
351        };
352        public static final Alignment SOUTHWEST = new Alignment () {
353            public void set (JComponent c) {
354                c.setAlignmentX (0.0f);
355                c.setAlignmentY (1.0f);
356            }
357            public void set (GridBagConstraints gbc) {
358                gbc.anchor = GridBagConstraints.SOUTHWEST;
359            }
360            public String getBorderName () {
361                throw new RuntimeException ("ambiguous with BorderLayout");
362            }
363        };
364        public static final Alignment WEST = new Alignment () {
365            public void set (JComponent c) {
366                c.setAlignmentX (0.0f);
367                c.setAlignmentY (0.5f);
368            }
369            public void set (GridBagConstraints gbc) {
370                gbc.anchor = GridBagConstraints.WEST;
371            }
372            public String getBorderName () {
373                return BorderLayout.WEST;
374            }
375        };
376        public static final Alignment NORTHWEST = new Alignment () {
377            public void set (JComponent c) {
378                c.setAlignmentX (0.0f);
379                c.setAlignmentY (0.0f);
380            }
381            public void set (GridBagConstraints gbc) {
382                gbc.anchor = GridBagConstraints.NORTHWEST;
383            }
384            public String getBorderName () {
385                throw new RuntimeException ("ambiguous with BorderLayout");
386            }
387        };
388    }