OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 132 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.ui;
15
 
16
import org.openconcerto.utils.CollectionUtils;
17
 
18
import java.awt.Component;
19
import java.awt.Container;
20
import java.awt.Font;
21
import java.awt.GridLayout;
80 ilm 22
import java.util.Arrays;
17 ilm 23
import java.util.Collections;
24
 
25
import javax.swing.BorderFactory;
26
import javax.swing.JButton;
27
import javax.swing.JLabel;
28
import javax.swing.JPanel;
29
 
30
import com.jgoodies.forms.layout.CellConstraints;
67 ilm 31
import com.jgoodies.forms.layout.CellConstraints.Alignment;
17 ilm 32
import com.jgoodies.forms.layout.FormLayout;
33
import com.jgoodies.forms.layout.RowSpec;
34
 
35
/**
132 ilm 36
 * Permet de disposer des champs avec labels en colonnes. Exemple :
37
 * <img src="doc-files/FormLayouter.png"/>.<br/>
17 ilm 38
 *
39
 * Les champs sont placés grace aux add*().
40
 *
41
 * @author ILM Informatique 2 sept. 2004
42
 */
43
public class FormLayouter {
44
 
45
    // Label, gap, Field, gap
46
    private static final int CELL_WIDTH = 4;
47
    // row, gap
48
    private static final int CELL_HEIGHT = 2;
49
 
50
    private static final String BORDER_GAP = "3dlu";
51
    private static final String ROW_GAP = BORDER_GAP;
67 ilm 52
    private static String ROW_HEIGHT;
17 ilm 53
 
67 ilm 54
    public static final void setDefaultRowAlign(Alignment align) {
55
        ROW_HEIGHT = align.abbreviation() + ":p";
56
    }
57
 
58
    static {
59
        // that way labels are aligned with JTextComponents' content
60
        setDefaultRowAlign(CellConstraints.CENTER);
61
    }
62
 
17 ilm 63
    private final Container co;
64
    // le nombre de colonnes
65
    private final int width;
66
    // le nombre de colonnes par défaut
67
    private final int defaultWidth;
68
    // le layout
132 ilm 69
    private FormLayout layout;
17 ilm 70
    private final CellConstraints constraints;
67 ilm 71
    private Alignment rowAlign;
17 ilm 72
    // les coordonnées de la prochaine cellule
73
    private int x, y;
74
 
75
    public FormLayouter(Container co, int width) {
76
        this(co, width, 1);
77
    }
78
 
79
    public FormLayouter(Container co, int width, int defaultWidth) {
80
        if (width < 1)
81
            throw new IllegalArgumentException("width must be at least 1 : " + width);
82
 
83
        this.constraints = new CellConstraints();
67 ilm 84
        // i.e. from ROW_HEIGHT
85
        this.rowAlign = CellConstraints.DEFAULT;
17 ilm 86
 
87
        this.co = co;
88
        this.width = width;
89
        this.defaultWidth = defaultWidth;
132 ilm 90
 
91
        this.clear();
92
    }
93
 
94
    /**
95
     * Remove all children components of our container and reset this instance.
96
     */
97
    public void clear() {
98
        if (this.layout != null && this.co.getComponentCount() == 0)
99
            return;
100
 
101
        this.x = 0;
102
        this.y = 0;
103
 
104
        final String colSpec = BORDER_GAP + ", " + CollectionUtils.join(Collections.nCopies(this.width, "max(25dlu;p), 5dlu, d:g"), ", 5dlu, ") + ", " + BORDER_GAP;
17 ilm 105
        final String rowSpec = BORDER_GAP + ", " + ROW_HEIGHT + ", " + BORDER_GAP;
106
        // tous les fields ont une taille égale
132 ilm 107
        final int[] colGroups = new int[this.width];
108
        for (int i = 0; i < this.width; i++) {
17 ilm 109
            colGroups[i] = CELL_WIDTH * (i + 1);
110
        }
111
 
112
        this.layout = new FormLayout(colSpec, rowSpec);
113
        this.layout.setColumnGroups(new int[][] { colGroups });
132 ilm 114
        this.co.removeAll();
115
        this.co.setLayout(this.layout);
17 ilm 116
    }
117
 
67 ilm 118
    public final void setRowAlign(Alignment rowAlign) {
119
        this.rowAlign = rowAlign;
120
    }
121
 
122
    public final Alignment getRowAlign() {
123
        return this.rowAlign;
124
    }
125
 
17 ilm 126
    /**
127
     * Ajout un composant sur une ligne avec la description passee en parametre. Si comp est null,
128
     * un titre est créé.
129
     *
130
     * @param desc le label du champ
131
     * @param comp le composant graphique d'edition ou null si titre
57 ilm 132
     * @return the created label.
17 ilm 133
     */
57 ilm 134
    public JLabel add(String desc, Component comp) {
17 ilm 135
        if (comp != null) {
57 ilm 136
            return this.add(desc, comp, this.defaultWidth);
17 ilm 137
        } else {
138
            this.newLine();
139
            final JLabel lab = new JLabel(desc);
140
            lab.setFont(lab.getFont().deriveFont(Font.BOLD, 15));
141
            this.layout.setRowSpec(this.getY() - 1, new RowSpec("10dlu"));
142
            this.co.add(lab, this.constraints.xyw(this.getLabelX(), this.getY(), this.width * CELL_WIDTH - 1));
143
            this.endLine();
57 ilm 144
            return lab;
17 ilm 145
        }
146
    }
147
 
148
    /**
180 ilm 149
     * Ajout un composant sur une ligne.
17 ilm 150
     *
180 ilm 151
     * @param desc le label du champ, <code>null</code> if <code>comp</<code> should use its area.
17 ilm 152
     * @param comp le composant graphique d'edition.
153
     * @param w la largeur, entre 1 et la largeur de ce layout, ou 0 pour toute la largeur.
57 ilm 154
     * @return the created label.
17 ilm 155
     * @throws NullPointerException if comp is <code>null</code>.
156
     * @throws IllegalArgumentException if w is less than 1.
157
     */
57 ilm 158
    public JLabel add(String desc, Component comp, int w) {
17 ilm 159
        w = this.checkArgs(comp, w);
160
 
180 ilm 161
        int realWidth = this.getRealFieldWidth(w);
162
        final JLabel lab;
163
        final int fieldX;
164
        if (desc == null) {
165
            lab = null;
166
            fieldX = this.getLabelX();
167
            realWidth += this.getFieldX() - fieldX;
168
        } else {
169
            lab = new JLabel(desc);
170
            // Guillaume : right alignment like the Mac
171
            this.co.add(lab, this.constraints.xy(this.getLabelX(), this.getY(), CellConstraints.RIGHT, this.getRowAlign()));
172
            fieldX = this.getFieldX();
173
        }
174
        this.co.add(comp, this.constraints.xyw(fieldX, this.getY(), realWidth, CellConstraints.DEFAULT, this.getRowAlign()));
17 ilm 175
        this.x += w;
57 ilm 176
        return lab;
17 ilm 177
    }
178
 
179
    // assure that comp & w are valid, and do a newLine if necessary
180
    private int checkArgs(Component comp, int w) {
181
        if (comp == null)
182
            throw new NullPointerException();
183
        if (w < 0 || w > this.width)
184
            throw new IllegalArgumentException("w must be between 0 and " + this.width + " but is : " + w);
185
 
186
        int res = w == 0 ? w = this.width : w;
187
 
188
        if (this.x + res - 1 >= this.width) {
189
            this.newLine();
190
        }
191
        return res;
192
    }
193
 
57 ilm 194
    public JPanel addBordered(String desc, Component comp) {
195
        return this.addBordered(desc, comp, this.defaultWidth);
17 ilm 196
    }
197
 
57 ilm 198
    public JPanel addBordered(String desc, Component comp, int w) {
17 ilm 199
        w = this.checkArgs(comp, w);
200
 
201
        final int realWidth = w * CELL_WIDTH - 1;
202
        JPanel p = new JPanel();
25 ilm 203
        p.setOpaque(false);
17 ilm 204
        p.setLayout(new GridLayout());
205
        p.setBorder(BorderFactory.createTitledBorder(desc));
206
        p.add(comp);
207
 
67 ilm 208
        this.co.add(p, this.constraints.xyw(this.getLabelX(), this.getY(), realWidth, CellConstraints.DEFAULT, this.getRowAlign()));
17 ilm 209
        this.x += w;
57 ilm 210
        return p;
17 ilm 211
    }
212
 
213
    private final int getRealFieldWidth(int w) {
214
        return (w - 1) * CELL_WIDTH + 1;
215
    }
216
 
217
    private final int getY() {
218
        // +1 pour le premier gap, et +1 car formLayout indexé a partir de 1
219
        return this.y * CELL_HEIGHT + 2;
220
    }
221
 
222
    private final int getLabelX() {
223
        return this.x * CELL_WIDTH + 2;
224
    }
225
 
226
    private final int getFieldX() {
227
        return this.getLabelX() + 2;
228
    }
229
 
230
    // next line
231
    public final void newLine() {
232
        // only append => remove the BORDER_GAP
233
        this.layout.removeRow(this.getY() + 1);
234
        this.layout.appendRow(new RowSpec(ROW_GAP));
235
        this.layout.appendRow(new RowSpec(ROW_HEIGHT));
236
        this.layout.appendRow(new RowSpec(BORDER_GAP));
237
 
238
        this.y++;
239
        this.x = 0;
240
    }
241
 
242
    /** Finit la ligne actuelle */
243
    private void endLine() {
244
        this.x = this.width;
245
    }
246
 
57 ilm 247
    public JLabel addRight(String desc, Component comp) {
17 ilm 248
        this.newLine();
249
        this.x = this.width - 1;
57 ilm 250
        final JLabel res = this.add(desc, comp);
17 ilm 251
        this.endLine();
57 ilm 252
        return res;
17 ilm 253
    }
254
 
255
    public void add(JButton btn) {
256
        this.addRight("", btn);
257
    }
258
 
80 ilm 259
    public final Component getLabel(final Component comp) {
260
        final Component[] comps = this.getComponent().getComponents();
261
        final int index = Arrays.asList(comps).indexOf(comp);
262
        return comps[index - 1];
263
    }
264
 
17 ilm 265
    public final Container getComponent() {
266
        return this.co;
267
    }
268
 
269
    public final int getWidth() {
270
        return this.width;
271
    }
272
}