001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools;
003
004import java.awt.Component;
005import java.awt.Dimension;
006import java.awt.GridBagConstraints;
007import java.awt.Insets;
008
009import javax.swing.Box;
010
011/**
012 * A wrapper for GridBagConstraints which has sane default static creators and
013 * member functions to chain calling.
014 *
015 * @author imi
016 */
017public final class GBC extends GridBagConstraints {
018
019    /**
020     * Use public static creator functions to create an GBC.
021     */
022    private GBC() {}
023
024    /**
025     * Create a standard constraint (which is not the last).
026     * @return A standard constraint with no filling.
027     */
028    public static GBC std() {
029        GBC c = new GBC();
030        c.anchor = GridBagConstraints.LINE_START;
031        return c;
032    }
033
034    /**
035     * Create the constraint for the last elements on a line.
036     * @return A constraint which indicates the last item on a line.
037     */
038    public static GBC eol() {
039        GBC c = std();
040        c.gridwidth = REMAINDER;
041        return c;
042    }
043
044    /**
045     * Create the constraint for the last elements on a line and on a paragraph.
046     * This is merely a shortcut for eol().insets(0,0,0,10)
047     * @return A constraint which indicates the last item on a line.
048     */
049    public static GBC eop() {
050        return eol().insets(0, 0, 0, 10);
051    }
052
053    /**
054     * Try to fill both, horizontal and vertical
055     * @return This constraint for chaining.
056     */
057    public GBC fill() {
058        return fill(BOTH);
059    }
060
061    /**
062     * Set fill to the given value
063     * @param value The filling value, either NONE, HORIZONTAL, VERTICAL or BOTH
064     * @return This constraint for chaining.
065     */
066    public GBC fill(int value) {
067        fill = value;
068        if (value == HORIZONTAL || value == BOTH)
069            weightx = 1.0;
070        if (value == VERTICAL || value == BOTH)
071            weighty = 1.0;
072        return this;
073    }
074
075    /**
076     * Set the anchor of this GBC to a.
077     * @param a The new anchor, e.g. GBC.CENTER or GBC.EAST.
078     * @return This constraint for chaining.
079     */
080    public GBC anchor(int a) {
081        anchor = a;
082        return this;
083    }
084
085    /**
086     * Adds insets to this GBC.
087     * @param left      The left space of the insets
088     * @param top       The top space of the insets
089     * @param right     The right space of the insets
090     * @param bottom    The bottom space of the insets
091     * @return This constraint for chaining.
092     */
093    public GBC insets(int left, int top, int right, int bottom) {
094        insets = new Insets(top, left, bottom, right);
095        return this;
096    }
097
098    /**
099     * Adds insets to this GBC.
100     * @param insets The insets in all directions.
101     * @return This constraint for chaining.
102     * @since 10649
103     */
104    public GBC insets(int insets) {
105        insets(insets, insets, insets, insets);
106        return this;
107    }
108
109    /**
110     * Specifies how to distribute extra horizontal space.
111     * @param weightx   Weight in horizontal direction
112     * @param weighty   Weight in vertical direction
113     * @return This constraint for chaining.
114     */
115    public GBC weight(double weightx, double weighty) {
116        this.weightx = weightx;
117        this.weighty = weighty;
118        return this;
119    }
120
121    /**
122     * This is a helper to easily create a glue with a minimum default value.
123     * @param x If higher than 0, this will be a horizontal glue with x as minimum
124     *      horizontal strut.
125     * @param y If higher than 0, this will be a vertical glue with y as minimum
126     *      vertical strut.
127     * @return the glue component
128     */
129    public static Component glue(int x, int y) {
130        short maxx = x > 0 ? Short.MAX_VALUE : 0;
131        short maxy = y > 0 ? Short.MAX_VALUE : 0;
132        return new Box.Filler(new Dimension(x, y), new Dimension(x, y), new Dimension(maxx, maxy));
133    }
134
135    /**
136     * Sets the constraint's {@code gridx}, {@code gridy}.
137     * @param gridx cell containing the leading edge of the component's display area
138     * @param gridy cell at the top of the component's display area
139     * @return This constraint for chaining.
140     * @see #gridx
141     * @see #gridy
142     */
143    public GBC grid(int gridx, int gridy) {
144        this.gridx = gridx;
145        this.gridy = gridy;
146        return this;
147    }
148
149    /**
150     * Sets the constraint's {@code gridwidth}, {@code gridheight}.
151     * @param gridwidth number of cells in a row for the component's display area
152     * @param gridheight number of cells in a column for the component's display area
153     * @return This constraint for chaining.
154     * @see #gridwidth
155     * @see #gridheight
156     */
157    public GBC span(int gridwidth, int gridheight) {
158        this.gridwidth = gridwidth;
159        this.gridheight = gridheight;
160        return this;
161    }
162
163    /**
164     * Sets the constraint's {@code gridwidth}.
165     * @param gridwidth number of cells in a row for the component's display area
166     * @return This constraint for chaining.
167     * @see #gridwidth
168     */
169    public GBC span(int gridwidth) {
170        this.gridwidth = gridwidth;
171        return this;
172    }
173
174    /**
175     * Create a standard constraint with the {@code gridx}, {@code gridy} set.
176     *
177     * Is equivalent to {@code std().grid(gridx, gridy)}
178     * @param gridx cell containing the leading edge of the component's display area
179     * @param gridy cell at the top of the component's display area
180     * @return A standard constraint.
181     * @see #std()
182     * @see #grid(int, int)
183     * @see #gridx
184     * @see #gridy
185     */
186    public static GBC std(int gridx, int gridy) {
187        return std().grid(gridx, gridy);
188    }
189}