1 19 20 package org.netbeans.modules.editor.completion; 21 22 import java.awt.*; 23 import java.awt.event.MouseListener ; 24 import java.util.Collections ; 25 import java.util.List ; 26 import javax.swing.*; 27 28 import org.netbeans.editor.LocaleSupport; 29 import org.netbeans.spi.editor.completion.CompletionItem; 30 31 35 36 public class CompletionJList extends JList { 37 38 private static final int DARKER_COLOR_COMPONENT = 5; 39 40 private final RenderComponent renderComponent; 41 42 private Graphics cellPreferredSizeGraphics; 43 44 private int fixedItemHeight; 45 private int maxVisibleRowCount; 46 private int smartIndex; 47 48 public CompletionJList(int maxVisibleRowCount, MouseListener mouseListener) { 49 this.maxVisibleRowCount = maxVisibleRowCount; 50 addMouseListener(mouseListener); 51 setLayoutOrientation(JList.VERTICAL); 52 setFixedCellHeight(fixedItemHeight = Math.max(CompletionLayout.COMPLETION_ITEM_HEIGHT, getFontMetrics(getFont()).getHeight())); 53 setModel(new Model(Collections.EMPTY_LIST)); 54 setFocusable(false); 55 56 renderComponent = new RenderComponent(); 57 setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 58 setCellRenderer(new ListCellRenderer() { 59 private ListCellRenderer defaultRenderer = new DefaultListCellRenderer(); 60 61 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 62 if( value instanceof CompletionItem ) { 63 CompletionItem item = (CompletionItem)value; 64 renderComponent.setItem(item); 65 renderComponent.setSelected(isSelected); 66 renderComponent.setSeparator(smartIndex > 0 && smartIndex == index); 67 Color bgColor; 68 Color fgColor; 69 if (isSelected) { 70 bgColor = list.getSelectionBackground(); 71 fgColor = list.getSelectionForeground(); 72 } else { bgColor = list.getBackground(); 74 if ((index % 2) == 0) { bgColor = new Color( 76 Math.abs(bgColor.getRed() - DARKER_COLOR_COMPONENT), 77 Math.abs(bgColor.getGreen() - DARKER_COLOR_COMPONENT), 78 Math.abs(bgColor.getBlue() - DARKER_COLOR_COMPONENT) 79 ); 80 } 81 fgColor = list.getForeground(); 82 } 83 if (renderComponent.getBackground() != bgColor) { 85 renderComponent.setBackground(bgColor); 86 } 87 if (renderComponent.getForeground() != fgColor) { 88 renderComponent.setForeground(fgColor); 89 } 90 return renderComponent; 91 92 } else { 93 return defaultRenderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); 94 } 95 } 96 }); 97 getAccessibleContext().setAccessibleName(LocaleSupport.getString("ACSN_CompletionView")); 98 getAccessibleContext().setAccessibleDescription(LocaleSupport.getString("ACSD_CompletionView")); 99 } 100 101 void setData(List data) { 102 smartIndex = -1; 103 if (data != null) { 104 int itemCount = data.size(); 105 ListModel lm = LazyListModel.create( new Model(data), CompletionImpl.filter, 1.0d, LocaleSupport.getString("completion-please-wait") ); ListCellRenderer renderer = getCellRenderer(); 107 int lmSize = lm.getSize(); 108 int width = 0; 109 int maxWidth = getParent().getParent().getMaximumSize().width; 110 boolean stop = false; 111 for(int index = 0; index < lmSize; index++) { 112 Object value = lm.getElementAt(index); 113 Component c = renderer.getListCellRendererComponent(this, value, index, false, false); 114 Dimension cellSize = c.getPreferredSize(); 115 if (cellSize.width > width) { 116 width = cellSize.width; 117 if (width >= maxWidth) 118 stop = true; 119 } 120 if (smartIndex < 0 && value instanceof CompletionItem && ((CompletionItem)value).getSortPriority() >= 0) 121 smartIndex = index; 122 if (stop && smartIndex >= 0) 123 break; 124 } 125 setFixedCellWidth(width); 126 setModel(lm); 127 128 if (itemCount > 0) { 129 setSelectedIndex(0); 130 } 131 int visibleRowCount = Math.min(itemCount, maxVisibleRowCount); 132 setVisibleRowCount(visibleRowCount); 133 } 134 } 135 136 public void up() { 137 int size = getModel().getSize(); 138 if (size > 0) { 139 int idx = (getSelectedIndex() - 1 + size) % size; 140 while(idx > 0 && getModel().getElementAt(idx) == null) 141 idx--; 142 setSelectedIndex(idx); 143 ensureIndexIsVisible(idx); 144 } 145 } 146 147 public void down() { 148 int size = getModel().getSize(); 149 if (size > 0) { 150 int idx = (getSelectedIndex() + 1) % size; 151 while(idx < size && getModel().getElementAt(idx) == null) 152 idx++; 153 if (idx == size) 154 idx = 0; 155 setSelectedIndex(idx); 156 ensureIndexIsVisible(idx); 157 } 158 } 159 160 public void pageUp() { 161 if (getModel().getSize() > 0) { 162 int pageSize = Math.max(getLastVisibleIndex() - getFirstVisibleIndex(), 0); 163 int idx = Math.max(getSelectedIndex() - pageSize, 0); 164 while(idx > 0 && getModel().getElementAt(idx) == null) 165 idx--; 166 setSelectedIndex(idx); 167 ensureIndexIsVisible(idx); 168 } 169 } 170 171 public void pageDown() { 172 int size = getModel().getSize(); 173 if (size > 0) { 174 int pageSize = Math.max(getLastVisibleIndex() - getFirstVisibleIndex(), 0); 175 int idx = Math.min(getSelectedIndex() + pageSize, size - 1); 176 while(idx < size && getModel().getElementAt(idx) == null) 177 idx++; 178 if (idx == size) { 179 idx = Math.min(getSelectedIndex() + pageSize, size - 1); 180 while(idx > 0 && getModel().getElementAt(idx) == null) 181 idx--; 182 } 183 setSelectedIndex(idx); 184 ensureIndexIsVisible(idx); 185 } 186 } 187 188 public void begin() { 189 if (getModel().getSize() > 0) { 190 setSelectedIndex(0); 191 ensureIndexIsVisible(0); 192 } 193 } 194 195 public void end() { 196 int size = getModel().getSize(); 197 if (size > 0) { 198 int idx = size - 1; 199 while(idx > 0 && getModel().getElementAt(idx) == null) 200 idx--; 201 setSelectedIndex(idx); 202 ensureIndexIsVisible(idx); 203 } 204 } 205 206 private final class Model extends AbstractListModel { 207 208 List data; 209 210 public Model(List data) { 211 this.data = data; 212 } 213 214 public int getSize() { 215 return data.size(); 216 } 217 218 public Object getElementAt(int index) { 219 return (index >= 0 && index < data.size()) ? data.get(index) : null; 220 } 221 } 222 223 private final class RenderComponent extends JComponent { 224 225 private CompletionItem item; 226 227 private boolean selected; 228 private boolean separator; 229 230 void setItem(CompletionItem item) { 231 this.item = item; 232 } 233 234 void setSelected(boolean selected) { 235 this.selected = selected; 236 } 237 238 void setSeparator(boolean separator) { 239 this.separator = separator; 240 } 241 242 public void paintComponent(Graphics g) { 243 int itemRenderWidth = ((JViewport)CompletionJList.this.getParent()).getWidth(); 250 Color bgColor = getBackground(); 251 Color fgColor = getForeground(); 252 int height = getHeight(); 253 254 g.setColor(bgColor); 256 g.fillRect(0, 0, itemRenderWidth, height); 257 g.setColor(fgColor); 258 259 item.render(g, CompletionJList.this.getFont(), getForeground(), bgColor, 261 itemRenderWidth, getHeight(), selected); 262 263 if (separator) { 264 g.setColor(Color.gray); 265 g.drawLine(0, 0, itemRenderWidth, 0); 266 g.setColor(fgColor); 267 } 268 } 269 270 public Dimension getPreferredSize() { 271 if (cellPreferredSizeGraphics == null) { 272 cellPreferredSizeGraphics = java.awt.GraphicsEnvironment. 274 getLocalGraphicsEnvironment().getDefaultScreenDevice(). 275 getDefaultConfiguration().createCompatibleImage(1, 1).getGraphics(); 276 assert (cellPreferredSizeGraphics != null); 277 } 278 return new Dimension(item.getPreferredWidth(cellPreferredSizeGraphics, CompletionJList.this.getFont()), 279 fixedItemHeight); 280 } 281 282 } 283 284 } 285 | Popular Tags |