org.fife.rsta.ac.GoToMemberWindow Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of languagesupport Show documentation
Show all versions of languagesupport Show documentation
A library adding code completion and other advanced features for Java, JavaScript, Perl, and other languages to RSyntaxTextArea.
/*
* 11/15/2011
*
* Copyright (C) 2010 Robert Futrell
* robert_futrell at users.sourceforge.net
* http://fifesoft.com/rsyntaxtextarea
*
* This library is distributed under a modified BSD license. See the included
* RSTALanguageSupport.License.txt file for details.
*/
package org.fife.rsta.ac;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.tree.DefaultTreeCellRenderer;
import org.fife.ui.rsyntaxtextarea.focusabletip.TipUtil;
import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
/**
* A popup window that displays a text field and tree, allowing the user to
* jump to a specific part of code in the current source file.
*
* @author Robert Futrell
* @version 1.0
* @see GoToMemberAction
*/
public class GoToMemberWindow extends JWindow {
private RSyntaxTextArea textArea;
private JTextField field;
private AbstractSourceTree tree;
private Listener listener;
/**
* Constructor.
*
* @param parent The parent window (hosting the text component).
* @param textArea The text area.
* @param tree The source tree appropriate for the current language.
*/
public GoToMemberWindow(Window parent, RSyntaxTextArea textArea,
AbstractSourceTree tree) {
super(parent);
this.textArea = textArea;
ComponentOrientation o = parent.getComponentOrientation();
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(TipUtil.getToolTipBorder());
listener = new Listener();
addWindowFocusListener(listener);
parent.addComponentListener(listener);
field = createTextField();
contentPane.add(field, BorderLayout.NORTH);
this.tree = tree;
tree.setSorted(true);
tree.setShowMajorElementsOnly(true);
tree.setGotoSelectedElementOnClick(false);
tree.setFocusable(false);
tree.listenTo(textArea);
tree.addMouseListener(listener);
JScrollPane sp = new JScrollPane(tree);
sp.setBorder(null);
sp.setViewportBorder(BorderFactory.createEmptyBorder());
contentPane.add(sp);
Color bg = TipUtil.getToolTipBackground();
setBackground(bg);
field.setBackground(bg);
tree.setBackground(bg);
((DefaultTreeCellRenderer)tree.getCellRenderer()).setBackgroundNonSelectionColor(bg);
// Give apps a chance to decorate us with drop shadows, etc.
setContentPane(contentPane);
PopupWindowDecorator decorator = PopupWindowDecorator.get();
//System.out.println(decorator);
if (decorator!=null) {
decorator.decorate(this);
}
applyComponentOrientation(o);
pack();
JRootPane pane = getRootPane();
InputMap im = pane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "EscapePressed");
ActionMap am = pane.getActionMap();
am.put("EscapePressed", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
/**
* Creates the text field allowing the user to enter filter text.
*
* @return The text field.
*/
private JTextField createTextField() {
JTextField field = new JTextField(30);
field.setUI(new BasicTextFieldUI());
field.setBorder(new TextFieldBorder());
field.addActionListener(listener);
field.addKeyListener(listener);
field.getDocument().addDocumentListener(listener);
return field;
}
public void dispose() {
listener.uninstall();
super.dispose();
// Force refocus of text area to prevent NPE in GoToMemberAction's
// (TextAction's) getTextComponent(ActinEvent) when a different
// component is focused and this action is executed twice.
textArea.requestFocusInWindow();
}
/**
* Listens for events in this window.
*/
private class Listener extends MouseAdapter implements WindowFocusListener,
ComponentListener, DocumentListener, ActionListener, KeyListener {
public void actionPerformed(ActionEvent e) {
if (tree.gotoSelectedElement()) {
dispose();
}
}
public void changedUpdate(DocumentEvent e) {
handleDocumentEvent(e);
}
public void componentHidden(ComponentEvent e) {
dispose();
}
public void componentMoved(ComponentEvent e) {
dispose();
}
public void componentResized(ComponentEvent e) {
dispose();
}
public void componentShown(ComponentEvent e) {
}
private void handleDocumentEvent(DocumentEvent e) {
tree.filter(field.getText());
tree.selectFirstNodeMatchingFilter();
}
public void insertUpdate(DocumentEvent e) {
handleDocumentEvent(e);
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
tree.selectNextVisibleRow();
break;
case KeyEvent.VK_UP:
tree.selectPreviousVisibleRow();
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount()==2) {
tree.gotoSelectedElement();
dispose();
}
}
public void removeUpdate(DocumentEvent e) {
handleDocumentEvent(e);
}
public void uninstall() {
field.removeActionListener(this);
field.getDocument().removeDocumentListener(this);
tree.removeMouseListener(this);
removeWindowFocusListener(this);
}
public void windowGainedFocus(WindowEvent e) {
}
public void windowLostFocus(WindowEvent e) {
dispose();
}
}
/**
* The border for the filtering text field.
*/
private static class TextFieldBorder implements Border {
public Insets getBorderInsets(Component c) {
return new Insets(2, 5, 3, 5);
}
public boolean isBorderOpaque() {
return false;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int w, int h) {
g.setColor(UIManager.getColor("controlDkShadow"));
g.drawLine(x,y+h-1, x+w-1,y+h-1);
}
}
}