Skip to content

Commit 5a73939

Browse files
authored
Merge pull request #47 from acardona/autocompletion
Autocompletion of imports, class names, and static fields and methods after a classname
2 parents 91fadb6 + 167ab74 commit 5a73939

File tree

9 files changed

+772
-2
lines changed

9 files changed

+772
-2
lines changed

src/main/java/org/scijava/ui/swing/script/EditorPane.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import org.scijava.script.ScriptHeaderService;
7272
import org.scijava.script.ScriptLanguage;
7373
import org.scijava.script.ScriptService;
74+
import org.scijava.ui.swing.script.autocompletion.JythonAutoCompletion;
7475
import org.scijava.util.FileUtils;
7576

7677
/**
@@ -106,6 +107,8 @@ public class EditorPane extends RSyntaxTextArea implements DocumentListener {
106107
private PrefService prefService;
107108
@Parameter
108109
private LogService log;
110+
111+
private JythonAutoCompletion autoCompletionProxy;
109112

110113
/**
111114
* Constructor.

src/main/java/org/scijava/ui/swing/script/TextEditor.java

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
package org.scijava.ui.swing.script;
3131

3232
import java.awt.Color;
33+
import java.awt.Cursor;
3334
import java.awt.Dimension;
3435
import java.awt.Font;
3536
import java.awt.GridBagConstraints;
@@ -108,6 +109,7 @@
108109
import javax.swing.JCheckBoxMenuItem;
109110
import javax.swing.JFileChooser;
110111
import javax.swing.JFrame;
112+
import javax.swing.JLabel;
111113
import javax.swing.JMenu;
112114
import javax.swing.JMenuBar;
113115
import javax.swing.JMenuItem;
@@ -156,6 +158,7 @@
156158
import org.scijava.thread.ThreadService;
157159
import org.scijava.ui.CloseConfirmable;
158160
import org.scijava.ui.UIService;
161+
import org.scijava.ui.swing.script.autocompletion.ClassUtil;
159162
import org.scijava.ui.swing.script.commands.ChooseFontSize;
160163
import org.scijava.ui.swing.script.commands.ChooseTabSize;
161164
import org.scijava.ui.swing.script.commands.GitGrep;
@@ -214,7 +217,7 @@ public class TextEditor extends JFrame implements ActionListener,
214217
openMacroFunctions, decreaseFontSize, increaseFontSize, chooseFontSize,
215218
chooseTabSize, gitGrep, openInGitweb, replaceTabsWithSpaces,
216219
replaceSpacesWithTabs, toggleWhiteSpaceLabeling, zapGremlins,
217-
savePreferences, toggleAutoCompletionMenu;
220+
savePreferences, toggleAutoCompletionMenu, openClassOrPackageHelp;
218221
private RecentFilesMenuItem openRecent;
219222
private JMenu gitMenu, tabsMenu, fontSizeMenu, tabSizeMenu, toolsMenu,
220223
runMenu, whiteSpaceMenu;
@@ -483,6 +486,8 @@ public TextEditor(final Context context) {
483486
openHelp =
484487
addToMenu(toolsMenu, "Open Help for Class (with frames)...", 0, 0);
485488
openHelp.setMnemonic(KeyEvent.VK_P);
489+
openClassOrPackageHelp = addToMenu(toolsMenu, "Source or javadoc for class or package...", 0, 0);
490+
openClassOrPackageHelp.setMnemonic(KeyEvent.VK_S);
486491
openMacroFunctions =
487492
addToMenu(toolsMenu, "Open Help on Macro Functions...", 0, 0);
488493
openMacroFunctions.setMnemonic(KeyEvent.VK_H);
@@ -988,7 +993,12 @@ public void loadPreferences() {
988993

989994
final int windowWidth = prefService.getInt(getClass(), WINDOW_WIDTH, dim.width);
990995
final int windowHeight = prefService.getInt(getClass(), WINDOW_HEIGHT, dim.height);
991-
setPreferredSize(new Dimension(windowWidth, windowHeight));
996+
// Avoid creating a window larger than the desktop
997+
final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
998+
if (windowWidth > screen.getWidth() || windowHeight > screen.getHeight())
999+
setPreferredSize(new Dimension(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT));
1000+
else
1001+
setPreferredSize(new Dimension(windowWidth, windowHeight));
9921002

9931003
final int mainDivLocation = prefService.getInt(getClass(), MAIN_DIV_LOCATION, body.getDividerLocation());
9941004
body.setDividerLocation(mainDivLocation);
@@ -1395,6 +1405,7 @@ else if (source == savePreferences) {
13951405
}
13961406
else if (source == openHelp) openHelp(null);
13971407
else if (source == openHelpWithoutFrames) openHelp(null, false);
1408+
else if (source == openClassOrPackageHelp) openClassOrPackageHelp(null);
13981409
else if (source == openMacroFunctions) try {
13991410
new MacroFunctions(this).openHelp(getTextArea().getSelectedText());
14001411
}
@@ -2659,6 +2670,87 @@ public void openHelp(String className, final boolean withFrames) {
26592670
handleException(e);
26602671
}
26612672
}
2673+
2674+
/**
2675+
* @param text Either a classname, or a partial class name, or package name or any part of the fully qualified class name.
2676+
*/
2677+
public void openClassOrPackageHelp(String text) {
2678+
if (text == null)
2679+
text = getSelectedClassNameOrAsk();
2680+
if (null == text) return;
2681+
new Thread(new FindClassSourceAndJavadoc(text)).start(); // fork away from event dispatch thread
2682+
}
2683+
2684+
public class FindClassSourceAndJavadoc implements Runnable {
2685+
private final String text;
2686+
public FindClassSourceAndJavadoc(final String text) {
2687+
this.text = text;
2688+
}
2689+
@Override
2690+
public void run() {
2691+
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
2692+
final HashMap<String, ArrayList<String>> matches;
2693+
try {
2694+
matches = ClassUtil.findDocumentationForClass(text);
2695+
} finally {
2696+
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
2697+
}
2698+
if (matches.isEmpty()) {
2699+
JOptionPane.showMessageDialog(getEditorPane(), "No info found for:\n'" + text +'"');
2700+
return;
2701+
}
2702+
final JPanel panel = new JPanel();
2703+
final GridBagLayout gridbag = new GridBagLayout();
2704+
final GridBagConstraints c = new GridBagConstraints();
2705+
panel.setLayout(gridbag);
2706+
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
2707+
final List<String> keys = new ArrayList<String>(matches.keySet());
2708+
Collections.sort(keys);
2709+
c.gridy = 0;
2710+
for (final String classname: keys) {
2711+
c.gridx = 0;
2712+
c.anchor = GridBagConstraints.EAST;
2713+
final JLabel class_label = new JLabel(classname);
2714+
gridbag.setConstraints(class_label, c);
2715+
panel.add(class_label);
2716+
ArrayList<String> urls = matches.get(classname);
2717+
if (urls.isEmpty()) {
2718+
urls = new ArrayList<String>();
2719+
urls.add("https://duckduckgo.com/?q=" + classname);
2720+
}
2721+
for (final String url: urls) {
2722+
c.gridx += 1;
2723+
c.anchor = GridBagConstraints.WEST;
2724+
String title = "JavaDoc";
2725+
if (url.endsWith(".java")) title = "Source";
2726+
else if (url.contains("duckduckgo")) title = "Search...";
2727+
final JButton link = new JButton(title);
2728+
gridbag.setConstraints(link, c);
2729+
panel.add(link);
2730+
link.addActionListener(new ActionListener() {
2731+
public void actionPerformed(final ActionEvent event) {
2732+
try {
2733+
platformService.open(new URL(url));
2734+
} catch (Exception e) {
2735+
e.printStackTrace();
2736+
}
2737+
}
2738+
});
2739+
}
2740+
c.gridy += 1;
2741+
}
2742+
final JScrollPane jsp = new JScrollPane(panel);
2743+
//jsp.setPreferredSize(new Dimension(800, 500));
2744+
SwingUtilities.invokeLater(new Runnable() {
2745+
public void run() {
2746+
final JFrame frame = new JFrame(text);
2747+
frame.getContentPane().add(jsp);
2748+
frame.pack();
2749+
frame.setVisible(true);
2750+
}
2751+
});
2752+
}
2753+
}
26622754

26632755
public void extractSourceJar() {
26642756
final File file = openWithDialog(null);

0 commit comments

Comments
 (0)