1 /* 2 * Copyright (c) 1996, 2014, 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 package sun.awt.windows; 26 27 import java.awt.*; 28 import java.awt.peer.*; 29 import java.awt.event.ActionEvent; 30 import java.awt.event.ItemEvent; 31 32 final class WListPeer extends WComponentPeer implements ListPeer { 33 34 @Override 35 public boolean isFocusable() { 36 return true; 37 } 38 39 // ListPeer implementation 40 41 @Override 42 public int[] getSelectedIndexes() { 43 List l = (List)target; 44 int len = l.countItems(); 45 int sel[] = new int[len]; 46 int nsel = 0; 47 for (int i = 0 ; i < len ; i++) { 48 if (isSelected(i)) { 49 sel[nsel++] = i; 50 } 51 } 52 int selected[] = new int[nsel]; 53 System.arraycopy(sel, 0, selected, 0, nsel); 54 return selected; 55 } 56 57 /* New method name for 1.1 */ 58 @Override 59 public void add(String item, int index) { 60 addItem(item, index); 61 } 62 63 /* New method name for 1.1 */ 64 @Override 65 public void removeAll() { 66 clear(); 67 } 68 69 /* New method name for 1.1 */ 70 @Override 71 public void setMultipleMode (boolean b) { 72 setMultipleSelections(b); 73 } 74 75 /* New method name for 1.1 */ 76 @Override 77 public Dimension getPreferredSize(int rows) { 78 return preferredSize(rows); 79 } 80 81 /* New method name for 1.1 */ 82 @Override 83 public Dimension getMinimumSize(int rows) { 84 return minimumSize(rows); 85 } 86 87 private FontMetrics fm; 88 public void addItem(String item, int index) { 89 addItems(new String[] {item}, index, fm.stringWidth(item)); 90 } 91 native void addItems(String[] items, int index, int width); 92 93 @Override 94 public native void delItems(int start, int end); 95 public void clear() { 96 List l = (List)target; 97 delItems(0, l.countItems()); 98 } 99 @Override 100 public native void select(int index); 101 @Override 102 public native void deselect(int index); 103 @Override 104 public native void makeVisible(int index); 105 public native void setMultipleSelections(boolean v); 106 public native int getMaxWidth(); 107 108 public Dimension preferredSize(int v) { 109 if ( fm == null ) { 110 List li = (List)target; 111 fm = getFontMetrics( li.getFont() ); 112 } 113 Dimension d = minimumSize(v); 114 d.width = Math.max(d.width, getMaxWidth() + 20); 115 return d; 116 } 117 public Dimension minimumSize(int v) { 118 return new Dimension(20 + fm.stringWidth("0123456789abcde"), 119 (fm.getHeight() * v) + 4); // include borders 120 } 121 122 // Toolkit & peer internals 123 124 WListPeer(List target) { 125 super(target); 126 } 127 128 @Override 129 native void create(WComponentPeer parent); 130 131 @Override 132 void initialize() { 133 List li = (List)target; 134 135 fm = getFontMetrics( li.getFont() ); 136 137 // Fixed 6336384: setFont should be done before addItems 138 Font f = li.getFont(); 139 if (f != null) { 140 setFont(f); 141 } 142 143 // add any items that were already inserted in the target. 144 int nitems = li.countItems(); 145 if (nitems > 0) { 146 String[] items = new String[nitems]; 147 int maxWidth = 0; 148 int width = 0; 149 for (int i = 0; i < nitems; i++) { 150 items[i] = li.getItem(i); 151 width = fm.stringWidth(items[i]); 152 if (width > maxWidth) { 153 maxWidth = width; 154 } 155 } 156 addItems(items, 0, maxWidth); 157 } 158 159 // set whether this list should allow multiple selections. 160 setMultipleSelections(li.allowsMultipleSelections()); 161 162 // select the item if necessary. 163 int sel[] = li.getSelectedIndexes(); 164 for (int i = 0 ; i < sel.length ; i++) { 165 select(sel[i]); 166 } 167 168 // make the visible position visible. 169 // fix for 4676536 by kdm@sparc.spb.su 170 // we should call makeVisible() after we call select() 171 // because of a bug in Windows which is manifested by 172 // incorrect scrolling of the selected item if the list 173 // height is less than an item height of the list. 174 int index = li.getVisibleIndex(); 175 if (index < 0 && sel.length > 0) { 176 index = sel[0]; 177 } 178 if (index >= 0) { 179 makeVisible(index); 180 } 181 182 super.initialize(); 183 } 184 185 @Override 186 public boolean shouldClearRectBeforePaint() { 187 return false; 188 } 189 190 private native void updateMaxItemWidth(); 191 192 /*public*/ native boolean isSelected(int index); 193 194 // update the fontmetrics when the font changes 195 @Override 196 synchronized void _setFont(Font f) 197 { 198 super._setFont( f ); 199 fm = getFontMetrics( ((List)target).getFont() ); 200 updateMaxItemWidth(); 201 } 202 203 // native callbacks 204 205 void handleAction(final int index, final long when, final int modifiers) { 206 final List l = (List)target; 207 WToolkit.executeOnEventHandlerThread(l, new Runnable() { 208 @Override 209 public void run() { 210 l.select(index); 211 postEvent(new ActionEvent(target, ActionEvent.ACTION_PERFORMED, 212 l.getItem(index), when, modifiers)); 213 } 214 }); 215 } 216 217 void handleListChanged(final int index) { 218 final List l = (List)target; 219 WToolkit.executeOnEventHandlerThread(l, new Runnable() { 220 @Override 221 public void run() { 222 postEvent(new ItemEvent(l, ItemEvent.ITEM_STATE_CHANGED, 223 Integer.valueOf(index), 224 isSelected(index)? ItemEvent.SELECTED : 225 ItemEvent.DESELECTED)); 226 227 } 228 }); 229 } 230 }