OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 180 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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