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

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/internal/utils/combo/SubstanceComboPopup.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 Substance 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 Substance 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.substance.internal.utils.combo;
 
31
 
 
32
import java.awt.Component;
 
33
import java.awt.Dimension;
 
34
import java.awt.GraphicsConfiguration;
 
35
import java.awt.Insets;
 
36
import java.awt.Point;
 
37
import java.awt.Rectangle;
 
38
import java.awt.Toolkit;
 
39
 
 
40
import javax.swing.JComboBox;
 
41
import javax.swing.JScrollBar;
 
42
import javax.swing.ListCellRenderer;
 
43
import javax.swing.SwingConstants;
 
44
import javax.swing.SwingUtilities;
 
45
import javax.swing.plaf.basic.BasicComboPopup;
 
46
 
 
47
import org.pushingpixels.substance.internal.ui.SubstanceListUI;
 
48
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
 
49
import org.pushingpixels.substance.internal.utils.border.SubstanceBorder;
 
50
 
 
51
/**
 
52
 * Combo popup implementation in <b>Substance</b> look-and-feel. This class is
 
53
 * <b>for internal use only</b>.
 
54
 * 
 
55
 * @author Kirill Grouchnikov
 
56
 */
 
57
public class SubstanceComboPopup extends BasicComboPopup {
 
58
 
 
59
        /**
 
60
         * Creates combo popup for the specified combobox.
 
61
         * 
 
62
         * @param combo
 
63
         *            Combobox.
 
64
         */
 
65
        public SubstanceComboPopup(JComboBox combo) {
 
66
                super(combo);
 
67
                // fix for defect 154
 
68
                this.setOpaque(true);
 
69
                this.list.setBackground(combo.getBackground());
 
70
        }
 
71
 
 
72
        /*
 
73
         * (non-Javadoc)
 
74
         * 
 
75
         * @see javax.swing.plaf.basic.BasicComboPopup#configurePopup()
 
76
         */
 
77
        @Override
 
78
        protected void configurePopup() {
 
79
                super.configurePopup();
 
80
                setBorder(new SubstanceBorder(new Insets(0, 2, 2, 2)));
 
81
        }
 
82
 
 
83
        /**
 
84
         * Sets the list selection index to the selectedIndex. This method is used
 
85
         * to synchronize the list selection with the combo box selection.
 
86
         * 
 
87
         * @param selectedIndex
 
88
         *            the index to set the list
 
89
         */
 
90
        private void setListSelection(int selectedIndex) {
 
91
                if (selectedIndex == -1) {
 
92
                        this.list.clearSelection();
 
93
                } else {
 
94
                        this.list.setSelectedIndex(selectedIndex);
 
95
                        this.list.ensureIndexIsVisible(selectedIndex);
 
96
                }
 
97
        }
 
98
 
 
99
        /**
 
100
         * Calculates the upper left location of the popup.
 
101
         * 
 
102
         * @return The upper left location of the popup.
 
103
         */
 
104
        private Point getPopupLocation() {
 
105
                Dimension popupSize = this.comboBox.getSize();
 
106
                Insets insets = this.getInsets();
 
107
 
 
108
                // reduce the width of the scrollpane by the insets so that the popup
 
109
                // is the same width as the combo box.
 
110
                popupSize.setSize(popupSize.width - (insets.right + insets.left), this
 
111
                                .getPopupHeightForRowCount(this.comboBox.getMaximumRowCount()));
 
112
                Rectangle popupBounds = this.computePopupBounds(0, this.comboBox
 
113
                                .getBounds().height, popupSize.width, popupSize.height);
 
114
                Dimension scrollSize = popupBounds.getSize();
 
115
                Point popupLocation = popupBounds.getLocation();
 
116
 
 
117
                this.scroller.setMaximumSize(scrollSize);
 
118
                this.scroller.setPreferredSize(scrollSize);
 
119
                this.scroller.setMinimumSize(scrollSize);
 
120
 
 
121
                this.list.revalidate();
 
122
 
 
123
                return new Point(popupLocation.x, popupLocation.y);
 
124
        }
 
125
 
 
126
        /*
 
127
         * (non-Javadoc)
 
128
         * 
 
129
         * @see javax.swing.plaf.basic.BasicComboPopup#computePopupBounds(int, int,
 
130
         * int, int)
 
131
         */
 
132
        @Override
 
133
        protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
 
134
                int popupFlyoutOrientation = SubstanceCoreUtilities
 
135
                                .getPopupFlyoutOrientation(this.comboBox);
 
136
                Insets insets = this.getInsets();
 
137
                int dx = 0;
 
138
                int dy = 0;
 
139
                switch (popupFlyoutOrientation) {
 
140
                case SwingConstants.NORTH:
 
141
                        dy = -ph - (int) this.comboBox.getSize().getHeight() - insets.top
 
142
                                        - insets.bottom;
 
143
                        break;
 
144
                case SwingConstants.CENTER:
 
145
                        dy = -ph / 2 - (int) this.comboBox.getSize().getHeight() / 2
 
146
                                        - insets.top / 2 - insets.bottom / 2;
 
147
                        break;
 
148
                case SwingConstants.EAST:
 
149
                        dx = pw + insets.left + insets.right;
 
150
                        dy = -(int) this.comboBox.getSize().getHeight();
 
151
                        break;
 
152
                case SwingConstants.WEST:
 
153
                        dx = -pw - insets.left - insets.right;
 
154
                        dy = -(int) this.comboBox.getSize().getHeight();
 
155
                }
 
156
                Toolkit toolkit = Toolkit.getDefaultToolkit();
 
157
                Rectangle screenBounds;
 
158
 
 
159
                // Calculate the desktop dimensions relative to the combo box.
 
160
                GraphicsConfiguration gc = this.comboBox.getGraphicsConfiguration();
 
161
                Point p = new Point();
 
162
                SwingUtilities.convertPointFromScreen(p, this.comboBox);
 
163
                if (gc != null) {
 
164
                        Insets screenInsets = toolkit.getScreenInsets(gc);
 
165
                        screenBounds = gc.getBounds();
 
166
                        screenBounds.width -= (screenInsets.left + screenInsets.right);
 
167
                        screenBounds.height -= (screenInsets.top + screenInsets.bottom);
 
168
                        screenBounds.x += (p.x + screenInsets.left);
 
169
                        screenBounds.y += (p.y + screenInsets.top);
 
170
                } else {
 
171
                        screenBounds = new Rectangle(p, toolkit.getScreenSize());
 
172
                }
 
173
 
 
174
                Rectangle rect = new Rectangle(px + dx, py + dy, pw, ph);
 
175
                if ((py + ph > screenBounds.y + screenBounds.height)
 
176
                                && (ph < screenBounds.height)) {
 
177
                        rect.y = -rect.height - insets.top - insets.bottom;
 
178
                }
 
179
 
 
180
                // The following has been taken from JGoodies' Looks implementation
 
181
                // for the popup prototype value
 
182
                Object popupPrototypeDisplayValue = SubstanceCoreUtilities
 
183
                                .getComboPopupPrototypeDisplayValue(this.comboBox);
 
184
                if (popupPrototypeDisplayValue != null) {
 
185
                        ListCellRenderer renderer = this.list.getCellRenderer();
 
186
                        Component c = renderer.getListCellRendererComponent(this.list,
 
187
                                        popupPrototypeDisplayValue, -1, true, true);
 
188
                        int npw = c.getPreferredSize().width;
 
189
                        boolean hasVerticalScrollBar = this.comboBox.getItemCount() > this.comboBox
 
190
                                        .getMaximumRowCount();
 
191
                        if (hasVerticalScrollBar) {
 
192
                                // Add the scrollbar width.
 
193
                                JScrollBar verticalBar = this.scroller.getVerticalScrollBar();
 
194
                                npw += verticalBar.getPreferredSize().width;
 
195
                        }
 
196
 
 
197
                        pw = Math.max(pw, npw);
 
198
                        rect.width = pw;
 
199
                }
 
200
 
 
201
                return rect;
 
202
        }
 
203
 
 
204
        /*
 
205
         * (non-Javadoc)
 
206
         * 
 
207
         * @see javax.swing.plaf.basic.BasicComboPopup#hide()
 
208
         */
 
209
        @Override
 
210
        public void hide() {
 
211
                super.hide();
 
212
                SubstanceListUI ui = (SubstanceListUI) this.list.getUI();
 
213
                ui.resetRolloverIndex();
 
214
                // this.list.putClientProperty(SubstanceListUI.ROLLED_OVER_INDEX, null);
 
215
        }
 
216
 
 
217
        public JComboBox getCombobox() {
 
218
                return this.comboBox;
 
219
        }
 
220
}