~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to flamingo/src/main/java/org/pushingpixels/flamingo/internal/ui/ribbon/BasicBandControlPanelUI.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without 
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 * 
 
7
 *  o Redistributions of source code must retain the above copyright notice, 
 
8
 *    this list of conditions and the following disclaimer. 
 
9
 *     
 
10
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 
11
 *    this list of conditions and the following disclaimer in the documentation 
 
12
 *    and/or other materials provided with the distribution. 
 
13
 *     
 
14
 *  o Neither the name of Flamingo Kirill Grouchnikov nor the names of 
 
15
 *    its contributors may be used to endorse or promote products derived 
 
16
 *    from this software without specific prior written permission. 
 
17
 *     
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 
20
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 
21
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 
25
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 
26
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 
27
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
29
 */
 
30
package org.pushingpixels.flamingo.internal.ui.ribbon;
 
31
 
 
32
import java.awt.*;
 
33
import java.util.*;
 
34
import java.util.List;
 
35
 
 
36
import javax.swing.*;
 
37
import javax.swing.event.ChangeEvent;
 
38
import javax.swing.event.ChangeListener;
 
39
import javax.swing.plaf.ComponentUI;
 
40
 
 
41
import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
 
42
import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
 
43
import org.pushingpixels.flamingo.api.ribbon.*;
 
44
import org.pushingpixels.flamingo.api.ribbon.resize.IconRibbonBandResizePolicy;
 
45
import org.pushingpixels.flamingo.api.ribbon.resize.RibbonBandResizePolicy;
 
46
import org.pushingpixels.flamingo.internal.ui.ribbon.BasicRibbonBandUI.CollapsedButtonPopupPanel;
 
47
 
 
48
/**
 
49
 * Basic UI for control panel of ribbon band {@link JBandControlPanel}.
 
50
 * 
 
51
 * @author Kirill Grouchnikov
 
52
 */
 
53
public class BasicBandControlPanelUI extends AbstractBandControlPanelUI {
 
54
        private JSeparator[] groupSeparators;
 
55
 
 
56
        private JLabel[] groupLabels;
 
57
 
 
58
        protected ChangeListener changeListener;
 
59
 
 
60
        /*
 
61
         * (non-Javadoc)
 
62
         * 
 
63
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
64
         */
 
65
        public static ComponentUI createUI(JComponent c) {
 
66
                return new BasicBandControlPanelUI();
 
67
        }
 
68
 
 
69
        /**
 
70
         * Invoked by <code>installUI</code> to create a layout manager object to
 
71
         * manage the {@link JBandControlPanel}.
 
72
         * 
 
73
         * @return a layout manager object
 
74
         */
 
75
        @Override
 
76
        protected LayoutManager createLayoutManager() {
 
77
                return new ControlPanelLayout();
 
78
        }
 
79
 
 
80
        @Override
 
81
        protected void installListeners() {
 
82
                super.installListeners();
 
83
 
 
84
                this.changeListener = new ChangeListener() {
 
85
                        @Override
 
86
                        public void stateChanged(ChangeEvent e) {
 
87
                                syncGroupHeaders();
 
88
                                controlPanel.revalidate();
 
89
                        }
 
90
                };
 
91
                ((JBandControlPanel) this.controlPanel)
 
92
                                .addChangeListener(this.changeListener);
 
93
        }
 
94
 
 
95
        @Override
 
96
        protected void uninstallListeners() {
 
97
                ((JBandControlPanel) this.controlPanel)
 
98
                                .removeChangeListener(this.changeListener);
 
99
                this.changeListener = null;
 
100
 
 
101
                super.uninstallListeners();
 
102
        }
 
103
 
 
104
        @Override
 
105
        protected void installComponents() {
 
106
                super.installComponents();
 
107
 
 
108
                this.syncGroupHeaders();
 
109
        }
 
110
 
 
111
        @Override
 
112
        protected void uninstallComponents() {
 
113
                if (this.groupSeparators != null) {
 
114
                        for (JSeparator groupSeparator : this.groupSeparators) {
 
115
                                this.controlPanel.remove(groupSeparator);
 
116
                        }
 
117
                }
 
118
                if (this.groupLabels != null) {
 
119
                        for (JLabel groupLabel : this.groupLabels) {
 
120
                                if (groupLabel != null)
 
121
                                        this.controlPanel.remove(groupLabel);
 
122
                        }
 
123
                }
 
124
 
 
125
                super.uninstallComponents();
 
126
        }
 
127
 
 
128
        protected void syncGroupHeaders() {
 
129
                if (this.groupSeparators != null) {
 
130
                        for (JSeparator groupSeparator : this.groupSeparators) {
 
131
                                this.controlPanel.remove(groupSeparator);
 
132
                        }
 
133
                }
 
134
                if (this.groupLabels != null) {
 
135
                        for (JLabel groupLabel : this.groupLabels) {
 
136
                                if (groupLabel != null)
 
137
                                        this.controlPanel.remove(groupLabel);
 
138
                        }
 
139
                }
 
140
 
 
141
                int groupCount = ((JBandControlPanel) this.controlPanel)
 
142
                                .getControlPanelGroupCount();
 
143
                if (groupCount > 1) {
 
144
                        this.groupSeparators = new JSeparator[groupCount - 1];
 
145
                        for (int i = 0; i < groupCount - 1; i++) {
 
146
                                this.groupSeparators[i] = new JSeparator(JSeparator.VERTICAL);
 
147
                                this.controlPanel.add(this.groupSeparators[i]);
 
148
                        }
 
149
                }
 
150
                if (groupCount > 0) {
 
151
                        this.groupLabels = new JLabel[groupCount];
 
152
                        for (int i = 0; i < groupCount; i++) {
 
153
                                String title = ((JBandControlPanel) this.controlPanel)
 
154
                                                .getControlPanelGroupTitle(i);
 
155
                                if (title != null) {
 
156
                                        this.groupLabels[i] = new JLabel(title);
 
157
                                        this.controlPanel.add(this.groupLabels[i]);
 
158
                                }
 
159
                        }
 
160
                }
 
161
 
 
162
        }
 
163
 
 
164
        /**
 
165
         * Layout for the control panel of ribbon band.
 
166
         * 
 
167
         * @author Kirill Grouchnikov
 
168
         */
 
169
        private class ControlPanelLayout implements LayoutManager {
 
170
 
 
171
                /*
 
172
                 * (non-Javadoc)
 
173
                 * 
 
174
                 * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String,
 
175
                 * java.awt.Component)
 
176
                 */
 
177
                @Override
 
178
        public void addLayoutComponent(String name, Component c) {
 
179
                }
 
180
 
 
181
                /*
 
182
                 * (non-Javadoc)
 
183
                 * 
 
184
                 * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
 
185
                 */
 
186
                @Override
 
187
        public void removeLayoutComponent(Component c) {
 
188
                }
 
189
 
 
190
                /*
 
191
                 * (non-Javadoc)
 
192
                 * 
 
193
                 * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
 
194
                 */
 
195
                @Override
 
196
        public Dimension preferredLayoutSize(Container c) {
 
197
                        // The height of ribbon band control panel is
 
198
                        // computed based on the preferred height of a command
 
199
                        // button in BIG state.
 
200
                        int buttonHeight = dummy.getPreferredSize().height;
 
201
                        int vGap = getLayoutGap() * 3 / 4;
 
202
                        int minusGaps = buttonHeight - 2 * vGap;
 
203
                        switch (minusGaps % 3) {
 
204
                        case 1:
 
205
                                buttonHeight += 2;
 
206
                                break;
 
207
                        case 2:
 
208
                                buttonHeight++;
 
209
                                break;
 
210
                        }
 
211
 
 
212
                        Insets ins = c.getInsets();
 
213
 
 
214
                        // System.out.println("Control panel pref = "
 
215
                        // + (buttonHeight + ins.top + ins.bottom));
 
216
 
 
217
                        return new Dimension(c.getWidth(), buttonHeight + ins.top
 
218
                                        + ins.bottom);
 
219
                }
 
220
 
 
221
                /*
 
222
                 * (non-Javadoc)
 
223
                 * 
 
224
                 * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
 
225
                 */
 
226
                @Override
 
227
        public Dimension minimumLayoutSize(Container c) {
 
228
                        return this.preferredLayoutSize(c);
 
229
                }
 
230
 
 
231
                /*
 
232
                 * (non-Javadoc)
 
233
                 * 
 
234
                 * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
 
235
                 */
 
236
                @Override
 
237
        public void layoutContainer(Container c) {
 
238
                        // System.out.println("Control panel real = " + c.getHeight());
 
239
 
 
240
                        AbstractRibbonBand ribbonBand = ((JBandControlPanel) c)
 
241
                                        .getRibbonBand();
 
242
                        RibbonBandResizePolicy currentResizePolicy = ribbonBand
 
243
                                        .getCurrentResizePolicy();
 
244
                        if (currentResizePolicy == null)
 
245
                                return;
 
246
 
 
247
                        boolean ltr = c.getComponentOrientation().isLeftToRight();
 
248
 
 
249
                        // need place for border
 
250
                        Insets ins = c.getInsets();
 
251
                        int gap = getLayoutGap();
 
252
                        int x = ltr ? ins.left + gap / 2 : c.getWidth() - ins.right - gap
 
253
                                        / 2;
 
254
                        int availableHeight = c.getHeight() - ins.top - ins.bottom;
 
255
 
 
256
                        if (SwingUtilities.getAncestorOfClass(
 
257
                                        CollapsedButtonPopupPanel.class, c) != null) {
 
258
                                // install the most permissive resize policy on the popup
 
259
                                // panel of a collapsed ribbon band
 
260
                                List<RibbonBandResizePolicy> resizePolicies = ribbonBand
 
261
                                                .getResizePolicies();
 
262
                                resizePolicies.get(0).install(availableHeight, gap);
 
263
                        } else {
 
264
                                if (currentResizePolicy instanceof IconRibbonBandResizePolicy) {
 
265
                                        return;
 
266
                                }
 
267
 
 
268
                                // Installs the resize policy - this updates the display
 
269
                                // priority of all the galleries and buttons
 
270
                                currentResizePolicy.install(availableHeight, gap);
 
271
                        }
 
272
 
 
273
                        int controlPanelGroupIndex = 0;
 
274
                        for (JBandControlPanel.ControlPanelGroup controlPanelGroup : ((JBandControlPanel) controlPanel)
 
275
                                        .getControlPanelGroups()) {
 
276
                                // handle the group separators
 
277
                                if (controlPanelGroupIndex > 0) {
 
278
                                        int prefW = groupSeparators[controlPanelGroupIndex - 1]
 
279
                                                        .getPreferredSize().width;
 
280
                                        int sepX = ltr ? x - gap + (gap - prefW) / 2 : x + gap / 2
 
281
                                                        - (gap - prefW) / 2;
 
282
                                        groupSeparators[controlPanelGroupIndex - 1].setBounds(sepX,
 
283
                                                        ins.top, prefW, availableHeight);
 
284
                                }
 
285
 
 
286
                                boolean hasLeadingComponent = false;
 
287
                                boolean isCoreContent = controlPanelGroup.isCoreContent();
 
288
                                if (isCoreContent) {
 
289
                                        // how much vertical space is available in each row?
 
290
                                        int singleRowHeight = availableHeight / 3;
 
291
 
 
292
                                        boolean hasTitle = (controlPanelGroup.getGroupTitle() != null);
 
293
                                        int maxWidthInCurrColumn = 0;
 
294
                                        if (hasTitle) {
 
295
                                                JLabel titleLabel = groupLabels[controlPanelGroupIndex];
 
296
                                                int pw = titleLabel.getPreferredSize().width;
 
297
                                                int titleLabelHeight = Math.min(singleRowHeight - gap
 
298
                                                                / 4, titleLabel.getPreferredSize().height);
 
299
                                                int yNudge = singleRowHeight - titleLabelHeight;
 
300
                                                int baseline = (titleLabelHeight > 0) ? titleLabel
 
301
                                                                .getBaseline(pw, titleLabelHeight) : 0;
 
302
                                                if (ltr) {
 
303
                                                        titleLabel.setBounds(x + gap, ins.top + yNudge
 
304
                                                                        - titleLabelHeight + baseline, pw,
 
305
                                                                        titleLabelHeight);
 
306
                                                } else {
 
307
                                                        titleLabel.setBounds(x - gap - pw, ins.top + yNudge
 
308
                                                                        - titleLabelHeight + baseline, pw,
 
309
                                                                        titleLabelHeight);
 
310
                                                }
 
311
                                                maxWidthInCurrColumn = gap + pw;
 
312
                                        }
 
313
                                        List<JRibbonComponent> ribbonComps = controlPanelGroup
 
314
                                                        .getRibbonComps();
 
315
                                        Map<JRibbonComponent, Integer> ribbonCompRowSpans = controlPanelGroup
 
316
                                                        .getRibbonCompsRowSpans();
 
317
                                        List<JRibbonComponent> currColumn = new ArrayList<JRibbonComponent>();
 
318
 
 
319
                                        // if a group has a title, then the core components in that
 
320
                                        // group will take two rows instead of three
 
321
                                        int startingRow = hasTitle ? 1 : 0;
 
322
                                        int rowIndex = startingRow;
 
323
 
 
324
                                        for (int i = 0; i < ribbonComps.size(); i++) {
 
325
                                                JRibbonComponent coreComp = ribbonComps.get(i);
 
326
                                                int prefWidth = coreComp.getPreferredSize().width;
 
327
                                                int rowSpan = ribbonCompRowSpans.get(coreComp);
 
328
 
 
329
                                                // do we need to start a new column?
 
330
                                                int nextRowIndex = rowIndex + rowSpan;
 
331
                                                if (nextRowIndex > 3) {
 
332
                                                        if (ltr) {
 
333
                                                                if (hasLeadingComponent)
 
334
                                                                        x += gap;
 
335
                                                                x += maxWidthInCurrColumn;
 
336
                                                        } else {
 
337
                                                                if (hasLeadingComponent)
 
338
                                                                        x -= gap;
 
339
                                                                x -= maxWidthInCurrColumn;
 
340
                                                        }
 
341
                                                        hasLeadingComponent = true;
 
342
                                                        maxWidthInCurrColumn = 0;
 
343
                                                        rowIndex = startingRow;
 
344
                                                        currColumn.clear();
 
345
                                                }
 
346
 
 
347
                                                // how much vertical space does a component get?
 
348
                                                int compHeight = Math.min(rowSpan * singleRowHeight
 
349
                                                                - gap / 4, coreComp.getPreferredSize().height);
 
350
                                                int yNudge = rowSpan * singleRowHeight - compHeight;
 
351
                                                int y = rowIndex * singleRowHeight + ins.top;
 
352
 
 
353
                                                if (ltr) {
 
354
                                                        coreComp.setBounds(x, y + yNudge, prefWidth,
 
355
                                                                        compHeight);
 
356
                                                } else {
 
357
                                                        coreComp.setBounds(x - prefWidth, y + yNudge,
 
358
                                                                        prefWidth, compHeight);
 
359
                                                }
 
360
                                                maxWidthInCurrColumn = Math.max(maxWidthInCurrColumn,
 
361
                                                                prefWidth);
 
362
                                                currColumn.add(coreComp);
 
363
 
 
364
                                                coreComp.putClientProperty(
 
365
                                                                AbstractBandControlPanelUI.TOP_ROW, rowIndex == 0);
 
366
                                                coreComp.putClientProperty(
 
367
                                                                AbstractBandControlPanelUI.MID_ROW, (rowIndex > 0)
 
368
                                        && (rowIndex < 2));
 
369
                                                coreComp.putClientProperty(
 
370
                                                                AbstractBandControlPanelUI.BOTTOM_ROW, rowIndex == 2);
 
371
 
 
372
                                                // scan the components in this column and make them to
 
373
                                                // have the same width as the widest component in this
 
374
                                                // column
 
375
                                                for (JRibbonComponent comp : currColumn) {
 
376
                                                        Rectangle bounds = comp.getBounds();
 
377
                                                        if (ltr) {
 
378
                                                                comp.setBounds(bounds.x, bounds.y,
 
379
                                                                                maxWidthInCurrColumn, bounds.height);
 
380
                                                        } else {
 
381
                                                                comp.setBounds(bounds.x + bounds.width
 
382
                                                                                - maxWidthInCurrColumn, bounds.y,
 
383
                                                                                maxWidthInCurrColumn, bounds.height);
 
384
                                                        }
 
385
                                                        comp.doLayout();
 
386
                                                }
 
387
 
 
388
                                                // System.out
 
389
                                                // .println(rowSpan + ":" + coreComp.getBounds());
 
390
 
 
391
                                                rowIndex += rowSpan;
 
392
                                        }
 
393
                                        if ((rowIndex > 0) && (rowIndex <= 3)) {
 
394
                                                if (ltr) {
 
395
                                                        if (hasLeadingComponent)
 
396
                                                                x += gap;
 
397
                                                        x += maxWidthInCurrColumn;
 
398
                                                } else {
 
399
                                                        if (hasLeadingComponent)
 
400
                                                                x -= gap;
 
401
                                                        x -= maxWidthInCurrColumn;
 
402
                                                }
 
403
                                                hasLeadingComponent = true;
 
404
                                        }
 
405
                                } else {
 
406
                                        // The galleries
 
407
                                        for (RibbonElementPriority elementPriority : RibbonElementPriority
 
408
                                                        .values()) {
 
409
                                                for (JRibbonGallery gallery : controlPanelGroup
 
410
                                                                .getRibbonGalleries(elementPriority)) {
 
411
                                                        int pw = gallery.getPreferredWidth(gallery
 
412
                                                                        .getDisplayPriority(), availableHeight);
 
413
                                                        if (ltr) {
 
414
                                                                gallery.setBounds(x, ins.top, pw,
 
415
                                                                                availableHeight);
 
416
                                                                if (hasLeadingComponent)
 
417
                                                                        x += gap;
 
418
                                                                x += pw;
 
419
                                                        } else {
 
420
                                                                gallery.setBounds(x - pw, ins.top, pw,
 
421
                                                                                availableHeight);
 
422
                                                                if (hasLeadingComponent)
 
423
                                                                        x -= gap;
 
424
                                                                x -= pw;
 
425
                                                        }
 
426
                                                        hasLeadingComponent = true;
 
427
                                                }
 
428
                                        }
 
429
 
 
430
                                        Map<CommandButtonDisplayState, List<AbstractCommandButton>> buttonMap = new HashMap<CommandButtonDisplayState, List<AbstractCommandButton>>();
 
431
                                        for (RibbonElementPriority elementPriority : RibbonElementPriority
 
432
                                                        .values()) {
 
433
                                                for (AbstractCommandButton commandButton : controlPanelGroup
 
434
                                                                .getRibbonButtons(elementPriority)) {
 
435
                                                        CommandButtonDisplayState state = commandButton
 
436
                                                                        .getDisplayState();
 
437
                                                        if (buttonMap.get(state) == null) {
 
438
                                                                buttonMap.put(state,
 
439
                                                                                new ArrayList<AbstractCommandButton>());
 
440
                                                        }
 
441
                                                        buttonMap.get(state).add(commandButton);
 
442
                                                }
 
443
                                        }
 
444
 
 
445
                                        List<AbstractCommandButton> bigs = buttonMap
 
446
                                                        .get(CommandButtonDisplayState.BIG);
 
447
                                        if (bigs != null) {
 
448
                                                for (AbstractCommandButton bigButton : bigs) {
 
449
                                                        // Big buttons
 
450
                                                        int bigButtonWidth = bigButton.getPreferredSize().width;
 
451
                                                        if (hasLeadingComponent) {
 
452
                                                                if (ltr) {
 
453
                                                                        x += gap;
 
454
                                                                } else {
 
455
                                                                        x -= gap;
 
456
                                                                }
 
457
                                                        }
 
458
                                                        if (ltr) {
 
459
                                                                bigButton.setBounds(x, ins.top, bigButtonWidth,
 
460
                                                                                availableHeight);
 
461
                                                        } else {
 
462
                                                                bigButton.setBounds(x - bigButtonWidth,
 
463
                                                                                ins.top, bigButtonWidth,
 
464
                                                                                availableHeight);
 
465
                                                        }
 
466
                                                        bigButton.putClientProperty(TOP_ROW, Boolean.FALSE);
 
467
                                                        bigButton.putClientProperty(MID_ROW, Boolean.FALSE);
 
468
                                                        bigButton.putClientProperty(BOTTOM_ROW,
 
469
                                                                        Boolean.FALSE);
 
470
                                                        if (ltr) {
 
471
                                                                x += bigButtonWidth;
 
472
                                                        } else {
 
473
                                                                x -= bigButtonWidth;
 
474
                                                        }
 
475
                                                        hasLeadingComponent = true;
 
476
                                                }
 
477
                                        }
 
478
 
 
479
                                        // Medium buttons
 
480
                                        int vGap = gap * 3 / 4;
 
481
                                        int medSmallButtonHeight = (availableHeight - 2 * vGap) / 3;
 
482
 
 
483
                                        int index3 = 0;
 
484
                                        int maxWidth3 = 0;
 
485
                                        List<AbstractCommandButton> mediums = buttonMap
 
486
                                                        .get(CommandButtonDisplayState.MEDIUM);
 
487
                                        if (mediums != null) {
 
488
                                                for (AbstractCommandButton mediumButton : mediums) {
 
489
                                                        int medWidth = mediumButton.getPreferredSize().width;
 
490
                                                        maxWidth3 = Math.max(maxWidth3, medWidth);
 
491
 
 
492
                                                        if (hasLeadingComponent && (index3 == 0)) {
 
493
                                                                if (ltr) {
 
494
                                                                        x += gap;
 
495
                                                                } else {
 
496
                                                                        x -= gap;
 
497
                                                                }
 
498
                                                        }
 
499
                                                        int buttonTop = (medSmallButtonHeight + vGap)
 
500
                                                                        * index3;
 
501
                                                        int buttonBottom = (medSmallButtonHeight + vGap)
 
502
                                                                        * (index3 + 1) - vGap;
 
503
                                                        if (ltr) {
 
504
                                                                mediumButton.setBounds(x, ins.top + buttonTop,
 
505
                                                                                medWidth, buttonBottom - buttonTop);
 
506
                                                        } else {
 
507
                                                                mediumButton.setBounds(x - medWidth, ins.top
 
508
                                                                                + buttonTop, medWidth, buttonBottom
 
509
                                                                                - buttonTop);
 
510
                                                        }
 
511
                                                        mediumButton.putClientProperty(TOP_ROW, index3 == 0);
 
512
                                                        mediumButton.putClientProperty(MID_ROW, index3 == 1);
 
513
                                                        mediumButton.putClientProperty(BOTTOM_ROW, index3 == 2);
 
514
 
 
515
                                                        index3++;
 
516
                                                        if (index3 == 3) {
 
517
                                                                // last button in threesome
 
518
                                                                index3 = 0;
 
519
                                                                if (ltr) {
 
520
                                                                        x += maxWidth3;
 
521
                                                                } else {
 
522
                                                                        x -= maxWidth3;
 
523
                                                                }
 
524
                                                                hasLeadingComponent = true;
 
525
                                                                maxWidth3 = 0;
 
526
                                                        }
 
527
                                                }
 
528
                                        }
 
529
                                        // at this point, maxWidth3 may be non-null. We can safely
 
530
                                        // add it, since in this case there will be no buttons
 
531
                                        // left in lowButtons
 
532
                                        if (maxWidth3 > 0) {
 
533
                                                if (ltr) {
 
534
                                                        x += maxWidth3;
 
535
                                                } else {
 
536
                                                        x -= maxWidth3;
 
537
                                                }
 
538
                                                hasLeadingComponent = true;
 
539
                                        }
 
540
 
 
541
                                        index3 = 0;
 
542
                                        maxWidth3 = 0;
 
543
                                        List<AbstractCommandButton> smalls = buttonMap
 
544
                                                        .get(CommandButtonDisplayState.SMALL);
 
545
                                        if (smalls != null) {
 
546
                                                for (AbstractCommandButton smallButton : smalls) {
 
547
                                                        int lowWidth = smallButton.getPreferredSize().width;
 
548
                                                        maxWidth3 = Math.max(maxWidth3, lowWidth);
 
549
                                                        if (hasLeadingComponent && (index3 == 0)) {
 
550
                                                                if (ltr) {
 
551
                                                                        x += gap;
 
552
                                                                } else {
 
553
                                                                        x -= gap;
 
554
                                                                }
 
555
                                                        }
 
556
                                                        int buttonTop = (medSmallButtonHeight + vGap)
 
557
                                                                        * index3;
 
558
                                                        int buttonBottom = (medSmallButtonHeight + vGap)
 
559
                                                                        * (index3 + 1) - vGap;
 
560
                                                        if (ltr) {
 
561
                                                                smallButton.setBounds(x, ins.top + buttonTop,
 
562
                                                                                lowWidth, buttonBottom - buttonTop);
 
563
                                                        } else {
 
564
                                                                smallButton.setBounds(x - lowWidth, ins.top
 
565
                                                                                + buttonTop, lowWidth, buttonBottom
 
566
                                                                                - buttonTop);
 
567
                                                        }
 
568
                                                        smallButton.putClientProperty(TOP_ROW, index3 == 0);
 
569
                                                        smallButton.putClientProperty(MID_ROW, index3 == 1);
 
570
                                                        smallButton.putClientProperty(BOTTOM_ROW, index3 == 2);
 
571
 
 
572
                                                        index3++;
 
573
                                                        if (index3 == 3) {
 
574
                                                                // last button in threesome
 
575
                                                                index3 = 0;
 
576
                                                                if (ltr) {
 
577
                                                                        x += maxWidth3;
 
578
                                                                } else {
 
579
                                                                        x -= maxWidth3;
 
580
                                                                }
 
581
                                                                hasLeadingComponent = true;
 
582
                                                                maxWidth3 = 0;
 
583
                                                        }
 
584
                                                }
 
585
                                        }
 
586
                                        if ((index3 < 3) && (maxWidth3 > 0)) {
 
587
                                                if (ltr) {
 
588
                                                        x += maxWidth3;
 
589
                                                } else {
 
590
                                                        x -= maxWidth3;
 
591
                                                }
 
592
                                                hasLeadingComponent = true;
 
593
                                        }
 
594
                                }
 
595
                                // space for the separator
 
596
                                if (ltr) {
 
597
                                        x += gap * 3 / 2;
 
598
                                } else {
 
599
                                        x -= gap * 3 / 2;
 
600
                                }
 
601
                                controlPanelGroupIndex++;
 
602
                        }
 
603
                }
 
604
        }
 
605
}