KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > completion > CompletionJList


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.editor.completion;
21
22 import java.awt.*;
23 import java.awt.event.MouseListener JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.List JavaDoc;
26 import javax.swing.*;
27
28 import org.netbeans.editor.LocaleSupport;
29 import org.netbeans.spi.editor.completion.CompletionItem;
30
31 /**
32 * @author Miloslav Metelka, Dusan Balek
33 * @version 1.00
34 */

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 JavaDoc 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 JavaDoc 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 { // not selected
73
bgColor = list.getBackground();
74                         if ((index % 2) == 0) { // every second item slightly different
75
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                     // quick check Component.setBackground() always fires change
84
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 JavaDoc 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") ); //NOI18N
106
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 JavaDoc 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 JavaDoc data;
209
210         public Model(List JavaDoc data) {
211             this.data = data;
212         }
213         
214         public int getSize() {
215             return data.size();
216         }
217
218         public Object JavaDoc 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             // Although the JScrollPane without horizontal scrollbar
244
// is explicitly set with a preferred size
245
// it does not force its items with the only width into which
246
// they can render (and still leaves them with the preferred width
247
// of the widest item).
248
// Therefore the item's render width is taken from the viewport's width.
249
int itemRenderWidth = ((JViewport)CompletionJList.this.getParent()).getWidth();
250             Color bgColor = getBackground();
251             Color fgColor = getForeground();
252             int height = getHeight();
253
254             // Clear the background
255
g.setColor(bgColor);
256             g.fillRect(0, 0, itemRenderWidth, height);
257             g.setColor(fgColor);
258
259             // Render the item
260
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                 // CompletionJList.this.getGraphics() is null
273
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