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

org.fife.ui.search.FindInFilesTable Maven / Gradle / Ivy

Go to download

RText is a powerful, cross-platform programmer's text editor written in Java. It is designed to be easy to use, highly customizable and flexible. Part of RText's design is for the source code to be simple, easy to understand, and well documented, so that other programmers can look into its inner-workings and figure out how RText ticks with ease. A good place to start (besides the source code) is the Javadoc for all classes used in the project.

There is a newer version: 2.0.7
Show newest version
/*
 * 10/03/2005
 *
 * FindInFilesTable.java - A table listing search results in a Find in Files
 * dialog.
 * Copyright (C) 2005 Robert Futrell
 * http://fifesoft.com/rtext
 * Licensed under a modified BSD license.
 * See the included license file for details.
 */
package org.fife.ui.search;

import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.ToolTipManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import org.fife.ui.FileExplorerTableModel;
import org.fife.ui.RListSelectionModel;
import org.fife.ui.FileExplorerTableModel.SortableHeaderRenderer;


/**
 * The table used to display search results in a
 * FindInFilesDialog.
 *
 * @author Robert Futrell
 * @version 1.0
 */
public class FindInFilesTable extends JTable implements ResultsComponent {

	private FileExplorerTableModel sorter;
	private DefaultTableModel tableModel;
	private ArrayList matchDatas;

	private StandardCellRenderer defaultRenderer;
	private VerboseCellRenderer verboseRenderer;

	private static final String MSG = "org.fife.ui.search.FindInFilesTable";


	/**
	 * Constructor.
	 */
	public FindInFilesTable() {

		ResourceBundle msg = ResourceBundle.getBundle(MSG);

		// Create the table model, and make it sortable.
		// Keep a pointer to the "real" table model since it's a
		// DefaultTableModel and is easy to modify.
		tableModel = createTableModel(msg);
		sorter = new FileExplorerTableModel(tableModel);
		setModel(sorter);
		sorter.setTable(this);

		setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		setSelectionModel(new RListSelectionModel());
		setRowSelectionAllowed(true);
		setShowGrid(false);

		initColumnWidths();

		matchDatas = new ArrayList();
		defaultRenderer = new StandardCellRenderer();

		// By default, tables are registered to give tool tips.  This causes
		// Disable this so the renderer isn't asked for each time the mouse
		// moves, as if styled results are enabled, this can cause some decent
		// slowdown.
		ToolTipManager.sharedInstance().unregisterComponent(this);
		ToolTipManager.sharedInstance().unregisterComponent(getTableHeader());

	}


	/**
	 * Adds data on a match to the table.
	 *
	 * @param matchData The data.
	 * @param dirName The "root directory" searching was done in.  This is
	 *        used so all file paths displayed in the table are abbreviated
	 *        to be relative to this directory.
	 * @see #clear()
	 */
	public void addMatchData(MatchData matchData, String dirName) {

		// Make the displayed filename be in a path relative to the
		// directory typed into the Find in Files dialog.
		int pos = 0;
		String fileName = matchData.getFileName().toLowerCase();
		dirName = dirName.toLowerCase();
		int dirNameLength = dirName.length();
		while (posgetPreferredSize().height : false;
	}


	/**
	 * Overridden in a "hack" to ensure that the table's contents are
	 * always at least as large as the enclosing JScrollPane's
	 * viewport.
	 */
	public boolean getScrollableTracksViewportWidth() {
 		Container parent = getParent();
		if (parent instanceof JViewport) {
			return parent.getSize().getWidth()>getPreferredSize().getWidth();
		}
		return super.getScrollableTracksViewportWidth();
	}


	/**
	 * Initializes the column widths.
	 */
	protected void initColumnWidths() {
		TableColumnModel columnModel = getColumnModel();
		columnModel.getColumn(0).setPreferredWidth(80);
		columnModel.getColumn(1).setPreferredWidth(40);
		columnModel.getColumn(2).setPreferredWidth(180);
	}


	/**
	 * This method always returns false, as match data is immutable.
	 *
	 * @param row The row of the cell.
	 * @param column The column of the cell.
	 * @return false always.
	 */
	public boolean isCellEditable(int row, int column) {
		return false;
	}


	private static final boolean isFileSeparatorChar(char ch) {
		return ch=='\\' || ch=='/';
	}


	/**
	 * Allows the results component to update its appearance after
	 * having lots of data added to it.
	 */
	public void prettyUp() {
		refreshColumnWidths();
		revalidate();
	}


	/**
	 * Resizes the columns of the table to accommodate their data.
	 */
	private void refreshColumnWidths() {

		TableColumnModel columnModel = getColumnModel();
		int columnCount = getColumnCount();
		int width;
		int rowCount = getRowCount();

		for (int j=0; j3000 && value.startsWith("")) {
					value = value.replaceAll("<[^>]+>", "");
				}

				Component comp = renderer.getTableCellRendererComponent(
								this, value, false, false, i, j);
				width = Math.max(width, comp.getPreferredSize().width);

			}

			// Set the size of the column.
			// NOTE: Why do we need to add a small amount to prevent "..."?
			column.setPreferredWidth(width + 20);

		}

	}


	/**
	 * Overridden to keep the left-hand side of the row visible on selection.
	 * This is because otherwise the viewport jumps to show the entire cell
	 * selected.
	 */
	public void scrollRectToVisible(Rectangle r) {
		r.x = 0; r.width = 0;
		super.scrollRectToVisible(r);
	}


	/**
	 * Overridden to also update the UI of custom renderers.
	 */
	public void updateUI() {

		/*
		 * NOTE: This is silly, but it's what it took to get a LaF change to
		 * occur without throwing an NPE because of the JRE bug.  No doubt there
		 * is a better way to handle this.  What we do is:
		 *
		 * 1. Before updating the UI, reset the JTableHeader's default renderer
		 *    to what it was originally.  This prevents the NPE from the JRE
		 *    bug, since we're no longer using the renderer with a cached
		 *    Windows-specific TableCellRenderer (when Windows LaF is enabled).
		 * 2. Update the UI, like normal.
		 * 3. After the update, we must explicitly re-set the JTableHeader as
		 *    the column view in the enclosing JScrollPane.  This is done by
		 *    default the first time you add a JTable to a JScrollPane, but
		 *    since we gave the JTable a new header as a workaround for the JRE
		 *    bug, we must explicitly tell the JScrollPane about it as well.
		 */

		// Temporarily set the table header's renderer to the default.
		Container parent = getParent();
		if (parent!=null) { // First time through, it'll be null
			TableCellRenderer r = getTableHeader().getDefaultRenderer();
			if (r instanceof SortableHeaderRenderer) { // Always true
				SortableHeaderRenderer shr = (SortableHeaderRenderer)r;
				getTableHeader().setDefaultRenderer(shr.getDelegateRenderer());
			}
		}

		super.updateUI();

		// Now set the renderer back to our custom one.
		if (parent!=null) {
			JScrollPane sp = (JScrollPane)parent.getParent();
			sp.setColumnHeaderView(getTableHeader());
			sp.revalidate();
			sp.repaint();
		}

		// Update our custom renderers too.
		if (defaultRenderer!=null) { // First time through, it's null
			defaultRenderer.updateUI();
		}
		if (verboseRenderer!=null) {
			verboseRenderer.updateUI();
		}

	}


	/**
	 * The default renderer for the table.
	 */
	private class StandardCellRenderer extends DefaultTableCellRenderer {

		public Component getTableCellRendererComponent(JTable table,
								Object value, boolean selected,
								boolean focused, int row, int column) {

			// If it's HTML and selected, don't colorize the HTML, let the
			// text all be the table's "selected text" color.
			if (value instanceof String) {
				String str = (String)value;
				if (str.startsWith("")) {
					if (selected) {
						value = str.replaceAll("color=\"[^\"]+\"", "");
					}
				}
			}

			super.getTableCellRendererComponent(table, value, selected,
												focused, row, column);
			return this;

		}

	}


	/**
	 * Renderer for "verbose information" and "error" cells.
	 */
	private class VerboseCellRenderer extends DefaultTableCellRenderer {

		public Component getTableCellRendererComponent(JTable table,
								Object value, boolean isSelected,
								boolean hasFocus, int row, int column) {
			super.getTableCellRendererComponent(table, value, isSelected,
										hasFocus, row, column);
			if (!isSelected) {
				MatchData data = getMatchDataForRow(row);
				if (data.isVerboseSearchInfo()) {
					setForeground(Color.GRAY);
				}
				else if (data.isError()) {
					setForeground(Color.RED);
				}
			}
			return this;
		}

	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy