Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java
38827 views
1
/*
2
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.lwawt;
27
28
import javax.swing.*;
29
import javax.swing.event.*;
30
import java.awt.*;
31
import java.awt.event.*;
32
import java.awt.peer.ListPeer;
33
import java.util.Arrays;
34
35
/**
36
* Lightweight implementation of {@link ListPeer}. Delegates most of the work to
37
* the {@link JList}, which is placed inside {@link JScrollPane}.
38
*/
39
final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
40
implements ListPeer {
41
42
/**
43
* The default number of visible rows.
44
*/
45
private static final int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
46
47
/**
48
* This text is used for cell bounds calculation.
49
*/
50
private static final String TEXT = "0123456789abcde";
51
52
LWListPeer(final List target, final PlatformComponent platformComponent) {
53
super(target, platformComponent);
54
if (!getTarget().isBackgroundSet()) {
55
getTarget().setBackground(SystemColor.text);
56
}
57
}
58
59
@Override
60
ScrollableJList createDelegate() {
61
return new ScrollableJList();
62
}
63
64
@Override
65
void initializeImpl() {
66
super.initializeImpl();
67
setMultipleMode(getTarget().isMultipleMode());
68
final int[] selectedIndices = getTarget().getSelectedIndexes();
69
synchronized (getDelegateLock()) {
70
getDelegate().setSkipStateChangedEvent(true);
71
getDelegate().getView().setSelectedIndices(selectedIndices);
72
getDelegate().setSkipStateChangedEvent(false);
73
}
74
}
75
76
@Override
77
public boolean isFocusable() {
78
return true;
79
}
80
81
@Override
82
Component getDelegateFocusOwner() {
83
return getDelegate().getView();
84
}
85
86
@Override
87
public int[] getSelectedIndexes() {
88
synchronized (getDelegateLock()) {
89
return getDelegate().getView().getSelectedIndices();
90
}
91
}
92
93
@Override
94
public void add(final String item, final int index) {
95
synchronized (getDelegateLock()) {
96
getDelegate().getModel().add(index, item);
97
revalidate();
98
}
99
}
100
101
@Override
102
public void delItems(final int start, final int end) {
103
synchronized (getDelegateLock()) {
104
getDelegate().getModel().removeRange(start, end);
105
revalidate();
106
}
107
}
108
109
@Override
110
public void removeAll() {
111
synchronized (getDelegateLock()) {
112
getDelegate().getModel().removeAllElements();
113
revalidate();
114
}
115
}
116
117
@Override
118
public void select(final int index) {
119
synchronized (getDelegateLock()) {
120
getDelegate().setSkipStateChangedEvent(true);
121
getDelegate().getView().setSelectedIndex(index);
122
getDelegate().setSkipStateChangedEvent(false);
123
}
124
}
125
126
@Override
127
public void deselect(final int index) {
128
synchronized (getDelegateLock()) {
129
getDelegate().getView().getSelectionModel().
130
removeSelectionInterval(index, index);
131
}
132
}
133
134
@Override
135
public void makeVisible(final int index) {
136
synchronized (getDelegateLock()) {
137
getDelegate().getView().ensureIndexIsVisible(index);
138
}
139
}
140
141
@Override
142
public void setMultipleMode(final boolean m) {
143
synchronized (getDelegateLock()) {
144
getDelegate().getView().setSelectionMode(m ?
145
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
146
: ListSelectionModel.SINGLE_SELECTION);
147
}
148
}
149
150
@Override
151
public Dimension getPreferredSize() {
152
return getMinimumSize();
153
}
154
155
@Override
156
public Dimension getMinimumSize() {
157
return getMinimumSize(DEFAULT_VISIBLE_ROWS);
158
}
159
160
@Override
161
public Dimension getPreferredSize(final int rows) {
162
return getMinimumSize(rows);
163
}
164
165
@Override
166
public Dimension getMinimumSize(final int rows) {
167
synchronized (getDelegateLock()) {
168
final Dimension size = getCellSize();
169
size.height *= rows;
170
// Always take vertical scrollbar into account.
171
final JScrollBar vbar = getDelegate().getVerticalScrollBar();
172
size.width += vbar != null ? vbar.getMinimumSize().width : 0;
173
// JScrollPane and JList insets
174
final Insets pi = getDelegate().getInsets();
175
final Insets vi = getDelegate().getView().getInsets();
176
size.width += pi.left + pi.right + vi.left + vi.right;
177
size.height += pi.top + pi.bottom + vi.top + vi.bottom;
178
return size;
179
}
180
}
181
182
private Dimension getCellSize() {
183
final JList<String> jList = getDelegate().getView();
184
final ListCellRenderer<? super String> cr = jList.getCellRenderer();
185
final Component cell = cr.getListCellRendererComponent(jList, TEXT, 0,
186
false, false);
187
return cell.getPreferredSize();
188
}
189
190
private void revalidate() {
191
synchronized (getDelegateLock()) {
192
getDelegate().getView().invalidate();
193
getDelegate().validate();
194
}
195
}
196
197
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
198
final class ScrollableJList extends JScrollPane implements ListSelectionListener {
199
200
private boolean skipStateChangedEvent;
201
202
private final DefaultListModel<String> model =
203
new DefaultListModel<String>() {
204
@Override
205
public void add(final int index, final String element) {
206
if (index == -1) {
207
addElement(element);
208
} else {
209
super.add(index, element);
210
}
211
}
212
};
213
214
private int[] oldSelectedIndices = new int[0];
215
216
ScrollableJList() {
217
getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
218
final JList<String> list = new JListDelegate();
219
list.addListSelectionListener(this);
220
221
getViewport().setView(list);
222
223
// Pull the items from the target.
224
final String[] items = getTarget().getItems();
225
for (int i = 0; i < items.length; i++) {
226
model.add(i, items[i]);
227
}
228
}
229
230
public boolean isSkipStateChangedEvent() {
231
return skipStateChangedEvent;
232
}
233
234
public void setSkipStateChangedEvent(boolean skipStateChangedEvent) {
235
this.skipStateChangedEvent = skipStateChangedEvent;
236
}
237
238
@Override
239
@SuppressWarnings("unchecked")
240
public void valueChanged(final ListSelectionEvent e) {
241
if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) {
242
final JList<?> source = (JList<?>) e.getSource();
243
for(int i = 0 ; i < source.getModel().getSize(); i++) {
244
245
final boolean wasSelected = Arrays.binarySearch(oldSelectedIndices, i) >= 0;
246
final boolean isSelected = source.isSelectedIndex(i);
247
248
if (wasSelected == isSelected) {
249
continue;
250
}
251
252
final int state = !wasSelected && isSelected ? ItemEvent.SELECTED: ItemEvent.DESELECTED;
253
254
LWListPeer.this.postEvent(new ItemEvent(getTarget(), ItemEvent.ITEM_STATE_CHANGED,
255
i, state));
256
}
257
oldSelectedIndices = source.getSelectedIndices();
258
}
259
}
260
261
@SuppressWarnings("unchecked")
262
public JList<String> getView() {
263
return (JList<String>) getViewport().getView();
264
}
265
266
public DefaultListModel<String> getModel() {
267
return model;
268
}
269
270
@Override
271
public void setEnabled(final boolean enabled) {
272
getView().setEnabled(enabled);
273
super.setEnabled(enabled);
274
}
275
276
@Override
277
public void setOpaque(final boolean isOpaque) {
278
super.setOpaque(isOpaque);
279
if (getView() != null) {
280
getView().setOpaque(isOpaque);
281
}
282
}
283
284
@Override
285
public void setFont(Font font) {
286
super.setFont(font);
287
if (getView() != null) {
288
getView().setFont(font);
289
LWListPeer.this.revalidate();
290
}
291
}
292
293
private final class JListDelegate extends JList<String> {
294
295
JListDelegate() {
296
super(model);
297
}
298
299
@Override
300
public boolean hasFocus() {
301
return getTarget().hasFocus();
302
}
303
304
@Override
305
protected void processMouseEvent(final MouseEvent e) {
306
super.processMouseEvent(e);
307
if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 2) {
308
final int index = locationToIndex(e.getPoint());
309
if (0 <= index && index < getModel().getSize()) {
310
LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,
311
getModel().getElementAt(index), e.getWhen(), e.getModifiers()));
312
}
313
}
314
}
315
316
@Override
317
protected void processKeyEvent(final KeyEvent e) {
318
super.processKeyEvent(e);
319
if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ENTER) {
320
final String selectedValue = getSelectedValue();
321
if(selectedValue != null){
322
LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED,
323
selectedValue, e.getWhen(), e.getModifiers()));
324
}
325
}
326
}
327
328
//Needed for Autoscroller.
329
@Override
330
public Point getLocationOnScreen() {
331
return LWListPeer.this.getLocationOnScreen();
332
}
333
}
334
}
335
}
336
337