update copyright
[fedora-idea.git] / plugins / maven / src / main / java / org / jetbrains / idea / maven / indices / MavenArtifactSearchPanel.java
blob7c1b3d290b7d235e68766219f62587ceab6bda8f
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.jetbrains.idea.maven.indices;
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.ui.DocumentAdapter;
21 import com.intellij.ui.SimpleColoredComponent;
22 import com.intellij.ui.SimpleTextAttributes;
23 import com.intellij.ui.treeStructure.Tree;
24 import com.intellij.util.Alarm;
25 import com.intellij.util.ui.UIUtil;
26 import com.intellij.util.ui.tree.TreeUtil;
27 import org.jetbrains.idea.maven.project.MavenId;
28 import org.jetbrains.idea.maven.utils.MavenLog;
29 import org.sonatype.nexus.index.ArtifactInfo;
31 import javax.swing.*;
32 import javax.swing.event.DocumentEvent;
33 import javax.swing.event.TreeModelListener;
34 import javax.swing.event.TreeSelectionEvent;
35 import javax.swing.event.TreeSelectionListener;
36 import javax.swing.tree.TreeCellRenderer;
37 import javax.swing.tree.TreeModel;
38 import javax.swing.tree.TreePath;
39 import java.awt.*;
40 import java.awt.event.KeyAdapter;
41 import java.awt.event.KeyEvent;
42 import java.awt.event.MouseAdapter;
43 import java.awt.event.MouseEvent;
44 import java.util.List;
46 public class MavenArtifactSearchPanel extends JPanel {
47 private final Project myProject;
48 private final boolean myClassMode;
49 private final Listener myListener;
51 private JTextField mySearchField;
52 private Tree myResultList;
54 private final Alarm myAlarm;
56 public MavenArtifactSearchPanel(Project project, String initialText, boolean classMode, Listener listener, Disposable parent) {
57 myProject = project;
58 myClassMode = classMode;
59 myListener = listener;
61 initComponents(initialText);
62 myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, parent);
65 public JTextField getSearchField() {
66 return mySearchField;
69 private void initComponents(String initialText) {
70 mySearchField = new JTextField(initialText);
71 myResultList = new Tree();
73 setLayout(new BorderLayout());
74 add(mySearchField, BorderLayout.NORTH);
75 add(new JScrollPane(myResultList), BorderLayout.CENTER);
77 mySearchField.getDocument().addDocumentListener(new DocumentAdapter() {
78 protected void textChanged(DocumentEvent e) {
79 scheduleSearch();
81 });
83 myResultList.addTreeSelectionListener(new TreeSelectionListener() {
84 public void valueChanged(TreeSelectionEvent e) {
85 if (myAlarm.getActiveRequestCount() > 0) return;
87 boolean hasSelection = !myResultList.isSelectionEmpty();
88 myListener.canSelectStateChanged(MavenArtifactSearchPanel.this, hasSelection);
90 });
92 mySearchField.addKeyListener(new KeyAdapter() {
93 @Override
94 public void keyPressed(KeyEvent e) {
95 final Object action = getAction(e, myResultList);
96 if ("selectNext".equals(action)) {
97 TreeUtil.moveDown(myResultList);
99 else if ("selectPrevious".equals(action)) {
100 TreeUtil.moveUp(myResultList);
102 else if ("scrollUpChangeSelection".equals(action)) {
103 TreeUtil.movePageUp(myResultList);
105 else if ("scrollDownChangeSelection".equals(action)) {
106 TreeUtil.movePageDown(myResultList);
110 private Object getAction(final KeyEvent e, final JComponent comp) {
111 final KeyStroke stroke = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
112 return comp.getInputMap().get(stroke);
116 myResultList.setRootVisible(false);
117 myResultList.setShowsRootHandles(true);
118 myResultList.setModel(null);
119 myResultList.setFocusable(false);
120 myResultList.setCellRenderer(myClassMode ? new MyClassCellRenderer() : new MyArtifactCellRenderer());
122 myResultList.addMouseListener(new MouseAdapter() {
123 @Override
124 public void mouseClicked(MouseEvent e) {
125 if (e.getClickCount() == 2) {
126 Object sel = myResultList.getLastSelectedPathComponent();
127 if (sel != null && myResultList.getModel().isLeaf(sel)) {
128 myListener.doubleClicked();
132 if (!mySearchField.hasFocus()) {
133 mySearchField.requestFocus();
139 public void scheduleSearch() {
140 myListener.canSelectStateChanged(this, false);
142 // evaluate text value in the swing thread
143 final String text = mySearchField.getText();
145 myAlarm.cancelAllRequests();
146 myAlarm.addRequest(new Runnable() {
147 public void run() {
148 try {
149 doSearch(text);
151 catch (Throwable e) {
152 MavenLog.LOG.warn(e);
155 }, 500);
158 private void doSearch(String searchText) {
159 MavenSearcher searcher = myClassMode ? new MavenClassSearcher() : new MavenArtifactSearcher();
160 List<MavenArtifactSearchResult> result = searcher.search(myProject, searchText, 200);
161 final TreeModel model = new MyTreeModel(result);
163 SwingUtilities.invokeLater(new Runnable() {
164 public void run() {
165 if (myProject.isDisposed()) return;
166 myResultList.setModel(model);
167 myResultList.setSelectionRow(0);
172 public MavenId getResult() {
173 Object sel = myResultList.getLastSelectedPathComponent();
174 ArtifactInfo info;
175 if (sel instanceof ArtifactInfo) {
176 info = (ArtifactInfo)sel;
178 else {
179 info = ((MavenArtifactSearchResult)sel).versions.get(0);
182 return new MavenId(info.groupId, info.artifactId, info.version);
185 private static class MyTreeModel implements TreeModel {
186 List<? extends MavenArtifactSearchResult> myItems;
188 private MyTreeModel(List<? extends MavenArtifactSearchResult> items) {
189 myItems = items;
192 public Object getRoot() {
193 return myItems;
196 public Object getChild(Object parent, int index) {
197 return getList(parent).get(index);
200 public int getChildCount(Object parent) {
201 return getList(parent).size();
204 public List getList(Object parent) {
205 if (parent == myItems) return myItems;
206 if (parent instanceof MavenArtifactSearchResult) return ((MavenArtifactSearchResult)parent).versions;
207 return null;
210 public boolean isLeaf(Object node) {
211 return getList(node) == null;
214 public int getIndexOfChild(Object parent, Object child) {
215 return getList(parent).indexOf(child);
218 public void valueForPathChanged(TreePath path, Object newValue) {
221 public void addTreeModelListener(TreeModelListener l) {
224 public void removeTreeModelListener(TreeModelListener l) {
228 private static class MyArtifactCellRenderer extends JPanel implements TreeCellRenderer {
229 protected SimpleColoredComponent myLeftComponent = new SimpleColoredComponent();
230 protected SimpleColoredComponent myRightComponent = new SimpleColoredComponent();
232 private MyArtifactCellRenderer() {
233 setLayout(new BorderLayout());
236 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
237 boolean hasFocus) {
238 myLeftComponent.clear();
239 myRightComponent.clear();
241 if (UIUtil.isUnderQuaquaLookAndFeel()) {
242 setBackground(selected ? UIUtil.getTreeSelectionBackground() : null);
244 else {
245 if (selected) {
246 setBackground(UIUtil.getTreeSelectionBackground());
247 setForeground(UIUtil.getTreeSelectionForeground());
249 else {
250 setBackground(null);
251 setForeground(tree.getForeground());
255 if (getFont() == null) setFont(tree.getFont());
257 if (value == tree.getModel().getRoot()) {
258 myLeftComponent.append("Results", SimpleTextAttributes.REGULAR_ATTRIBUTES);
260 else if (value instanceof MavenArtifactSearchResult) {
261 formatSearchResult(tree, (MavenArtifactSearchResult)value);
263 else if (value instanceof ArtifactInfo) {
264 ArtifactInfo info = (ArtifactInfo)value;
265 myLeftComponent.append(info.groupId + ":" + info.artifactId + ":" + info.version,
266 SimpleTextAttributes.GRAY_ATTRIBUTES);
269 removeAll();
270 add(myLeftComponent, BorderLayout.WEST);
271 JPanel spacer = new JPanel();
272 spacer.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
273 spacer.setBackground(selected ? UIUtil.getTreeSelectionBackground() : tree.getBackground());
274 add(spacer, BorderLayout.CENTER);
275 add(myRightComponent, BorderLayout.EAST);
276 return this;
279 protected void formatSearchResult(JTree tree, MavenArtifactSearchResult searchResult) {
280 ArtifactInfo first = searchResult.versions.get(0);
281 ArtifactInfo last = searchResult.versions.get(searchResult.versions.size() - 1);
282 myLeftComponent.append(first.groupId + ":" + first.artifactId, SimpleTextAttributes.REGULAR_ATTRIBUTES);
283 myLeftComponent.append(":" + last.version + "-" + first.version, SimpleTextAttributes.GRAY_ATTRIBUTES);
287 private static class MyClassCellRenderer extends MyArtifactCellRenderer {
288 @Override
289 protected void formatSearchResult(JTree tree, MavenArtifactSearchResult searchResult) {
290 MavenClassSearchResult classResult = (MavenClassSearchResult)searchResult;
291 ArtifactInfo info = searchResult.versions.get(0);
293 myLeftComponent.append(classResult.className, SimpleTextAttributes.REGULAR_ATTRIBUTES);
294 myLeftComponent.append(" (" + classResult.packageName + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
296 myRightComponent.append(" " + info.groupId + ":" + info.artifactId,
297 SimpleTextAttributes.GRAY_ATTRIBUTES);
301 public interface Listener {
302 void doubleClicked();
304 void canSelectStateChanged(MavenArtifactSearchPanel from, boolean canSelect);