package com.towel.swing;
import java.awt.FontMetrics;
import java.awt.Point;
import javax.swing.JScrollPane;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;
/**
* Util static methods to becomes easy operation with Text Components. All
* functionalities are available to JTextComponent as well as a Document.
*
* @author Farina, Andre
*/
public class TextUtils
{
/**
* Returns the line number of the caret in a text component.
*
* @param txtCmp Text Component
* @return Line number
*/
public static int getCaretLine(JTextComponent txtCmp)
{
return getLine(txtCmp.getDocument(), txtCmp.getCaretPosition());
}
/**
* Given an offset, returns the line number of a text component.
*
* @param txtCmp Text Component
* @param offset Offset position
* @return Line number starting in 0.
*/
public static int getLine(JTextComponent txtCmp, int offset)
{
return getLine(txtCmp.getDocument(), offset);
}
/**
* Given an offset, returns the line number in a text component.
*
* @param doc JTextComponent document
* @param offset Offset position
* @return Line number starting in 0.
*/
public static int getLine(Document doc, int offset)
{
Element root = doc.getDefaultRootElement();
return root.getElementIndex(offset);
}
/**
* Given an offset, returns the column number in a text component.
*
* @param offset Offset position
* @return Column number starting in 0.
*/
public static int getCaretColumn(JTextComponent txtCmp)
{
return getColumn(txtCmp, txtCmp.getCaretPosition());
}
/**
* Given an offset, returns the column number in a text component.
*
* @param offset Offset position
* @return Column number starting in 0.
*/
public static int getColumn(JTextComponent txtCmp, int offset)
{
return txtCmp.getCaretPosition() - getOffsetStartLine(txtCmp, offset);
}
/**
* Given an offset, returns the offset where the line begins.
*
* @param offset Offset position.
* @return Offset where the line begins.
*/
public static int getOffsetStartLine(JTextComponent txtCmp, int offset)
{
return getOffsetStartLine(txtCmp.getDocument(), offset);
}
/**
* Given an offset, returns the offset where the line begins.
*
* @param doc JTextComponent document
* @param offset Offset position.
* @return Offset where the line begins.
*/
public static int getOffsetStartLine(Document doc, int offset)
{
int line = getLine(doc, offset);
return getWhereLineStarts(doc, line);
}
/**
* Given an offset, returns the offset where the line ends.
*
* @param offset Offset position.
* @return Offset where the line ends.
*/
public static int getOffsetEndLine(JTextComponent txtCmp, int offset)
{
return getOffsetEndLine(txtCmp.getDocument(), offset);
}
/**
* Given an offset, returns the offset where the line ends.
*
* @param doc JTextComponent document
* @param offset Offset position.
* @return Offset where the line ends.
*/
public static int getOffsetEndLine(Document doc, int offset)
{
int line = getLine(doc, offset);
return getWhereLineEnds(doc, line);
}
/**
* Given a line returns the offset number where the line starts.
*
* @param line Line number
* @return Offset number
*/
public static int getWhereLineStarts(JTextComponent txtCmp, int line)
{
return getWhereLineStarts(txtCmp.getDocument(), line);
}
/**
* Given a line returns the offset number where the line starts.
*
* @param doc JTextComponent document
* @param line Line number
* @return Offset number
*/
public static int getWhereLineStarts(Document doc, int line)
{
Element el = doc.getDefaultRootElement().getElement(line);
if (el != null)
return el.getStartOffset();
return doc.getStartPosition().getOffset();
}
/**
* Given a line returns the offset number where the line ends.
*
* @param line Line number
* @return Offset number
*/
public static int getWhereLineEnds(JTextComponent txtCmp, int line)
{
return getWhereLineEnds(txtCmp.getDocument(), line);
}
/**
* Given a line returns the offset number where the line ends.
*
* @param doc JTextComponent document
* @param line Line number
* @return Offset number
*/
public static int getWhereLineEnds(Document doc, int line)
{
Element el = doc.getDefaultRootElement().getElement(line);
if (el != null)
return el.getEndOffset();
return doc.getEndPosition().getOffset();
}
/**
* Count the line number.
*
* @return Amount of lines.
*/
public static int countLines(JTextComponent txtCmp)
{
return countLines(txtCmp.getDocument());
}
/**
* Count the line number.
*
* @param doc JTextComponent document
* @return Amount of lines.
*/
public static int countLines(Document doc)
{
return doc.getDefaultRootElement().getElementCount();
}
/**
* Get number of rows in the content being shown. Independent of the text's
* size.
*
* @return Amount of rows.
*/
public static int getRows(JTextComponent txtCmp)
{
FontMetrics fm = txtCmp.getFontMetrics(txtCmp.getFont());
int fontHeight = fm.getHeight();
int ybaseline = txtCmp.getY() + fm.getAscent();
int yend = ybaseline + txtCmp.getHeight();
int rows = 1;
while (ybaseline < yend)
{
ybaseline += fontHeight;
rows++;
}
return rows;
}
/**
* Get first visible line of the text component in a JScrollPane.
*
* @param txtCmp Text component.
* @return The line.
*/
public static int getTopLine(JTextComponent txtCmp)
{
FontMetrics fm = txtCmp.getFontMetrics(txtCmp.getFont());
int fontHeight = fm.getHeight();
return (Math.abs(txtCmp.getY()) + fm.getAscent()) / fontHeight + 1;
}
/**
* Get last visible line of the text component in a JScrollPane.
*
* @param txtCmp Text component.
* @return The line.
*/
public static int getBottomLine(JTextComponent txtCmp)
{
FontMetrics fm = txtCmp.getFontMetrics(txtCmp.getFont());
int fontHeight = fm.getHeight();
View view = txtCmp.getUI().getRootView(txtCmp).getView(0);
int height = view.getContainer().getParent().getHeight();
return (Math.abs(txtCmp.getY()) + fm.getAscent() + height) / fontHeight;
}
/**
* Scroll the pane until offset becomes visible.
*
* @param scroll
* @param offset
*/
public static void scrollToVisible(final JScrollPane scroll, int offset)
{
if (!(scroll.getViewport().getView() instanceof JTextComponent))
return;
JTextComponent txtCmp = (JTextComponent) scroll.getViewport().getView();
Element root = txtCmp.getDocument().getDefaultRootElement();
int line = root.getElementIndex(offset);
scrollLineToVisible(scroll, line);
}
/**
* Scroll the pane until line becomes visible.
*
* @param scroll
* @param line
*/
public static void scrollLineToVisible(final JScrollPane scroll, int line)
{
if (!(scroll.getViewport().getView() instanceof JTextComponent))
return;
JTextComponent txtCmp = (JTextComponent) scroll.getViewport().getView();
FontMetrics fm = txtCmp.getFontMetrics(txtCmp.getFont());
int fontHeight = fm.getHeight();
scroll.getViewport().setViewPosition(new Point(0, fontHeight*line));
}
public static String generateEscapeRegex(String text)
{
text = text.replaceAll("\\\\", "\\\\\\\\");
text = text.replaceAll("\\.", "\\\\.");
text = text.replaceAll("\\*", "\\\\*");
text = text.replaceAll("\\?", "\\\\?");
text = text.replaceAll("\\(", "\\\\(");
text = text.replaceAll("\\)", "\\\\)");
text = text.replaceAll("\\[", "\\\\[");
text = text.replaceAll("\\]", "\\\\]");
text = text.replaceAll("\\{", "\\\\{");
text = text.replaceAll("\\}", "\\\\}");
text = text.replaceAll("\\^", "\\\\^");
text = text.replaceAll("\\$", "\\\\\\$");
text = text.replaceAll("\\+", "\\\\+");
text = text.replaceAll("\\|", "\\\\|");
return text;
}
}