All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.rsta.ac.GoToMemberWindow Maven / Gradle / Ivy

Go to download

A library adding code completion and other advanced features for Java, JavaScript, Perl, and other languages to RSyntaxTextArea.

There is a newer version: 3.3.0
Show newest version
/*
 * 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);
		}
		
	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy