Re: JTexPane: Cross-platform chaos



Christian Kaufhold wrote:

> Do not use getText() (which returns in platform- etc. specific text),
> but getDocument().getText() (which always uses '\n' for newline, and
> which caret and selection positions refer to).

Wow, great, thanks alot! Thought for a moment that I had to build my own
cross-platform abstraction layer for this stuff; this tip really does the
trick! I really like this newsgroup - I've gotten lot's of useful input
in just a few hours, only too bad I ran into another cross-platform
issue: My internet provider makes it available for Windows newsclients,
but it is invisible to my Linux desktop. Really strange.

Thanks again! Here comes the working source code for whoever might
stumble upon this thread someday:



import java.applet.Applet;
import java.awt.Color;
import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;
import javax.swing.InputMap;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;

public class EditorTextPane extends JTextPane implements KeyListener {

private boolean wrap = false;
private AbstractDocument doc;
private StyledDocument styledDoc;
private Applet container;

// newline and tab
private final static char NEW = '\n', TAB = '\t';

// snapshot variables
private String value;
private boolean isSelection;
private boolean isEnd;
private int start;
private int end;
private String selection;

// syntax painter
private SimpleAttributeSet textattributes = new SimpleAttributeSet();

/**
* Construct
*/
public EditorTextPane() {

super();

styledDoc = getStyledDocument();
doc = (AbstractDocument) styledDoc;
StyleConstants.setForeground(textattributes, Color.BLACK);

// keybindings, keylisteners and undolistener
addKeyBindings();
addKeyListener(this);
}

private void addKeyBindings() {

InputMap inputMap = this.getInputMap();

KeyStroke cut = KeyStroke.getKeyStroke
(KeyEvent.VK_X, Event.CTRL_MASK);
KeyStroke copy = KeyStroke.getKeyStroke
(KeyEvent.VK_C, Event.CTRL_MASK);
KeyStroke paste = KeyStroke
.getKeyStroke(KeyEvent.VK_V, Event.CTRL_MASK);

inputMap.put(cut, DefaultEditorKit.cutAction);
inputMap.put(copy, DefaultEditorKit.copyAction);
inputMap.put(paste, DefaultEditorKit.pasteAction);
}

/**
* Insert text at caret position
* @param text
*/
public void insertText(String text) {
try {
doc.insertString(getCaretPosition(), text, textattributes);
} catch (BadLocationException e) {
System.out.println(e.getStackTrace());
}
}

/**
* Insert new text, delete all previous content
* @param text
*/
public void insertNewText(String text) {

setText("");
try {
Document blank = new DefaultStyledDocument();
setDocument(blank);
doc.insertString(0, text, textattributes);
setDocument(doc);
} catch (BadLocationException e) {
System.out.println("paint method: bad location");
}
}

/**
* Insert char at caret position
* @param character
*/
private void insertChar(char character) {
insertText(String.valueOf(character));
}

/**
* Snapshot current setup
*/
private void snapshot() {

int selectionStart = this.getSelectionStart();
int selectionEnd = this.getSelectionEnd();

try {
int length = doc.getLength();
value = doc.getText(0, length);
} catch (BadLocationException e) {
System.out.println("snapshot: bad location");
}
isSelection = selectionStart != selectionEnd;
isEnd = selectionStart < selectionEnd;
start = isEnd ? selectionStart : selectionEnd;
end = isEnd ? selectionEnd : selectionStart;
selection = isSelection ? value.substring(start, end) : null;
}

/**
* must implement
*/
public void keyTyped(KeyEvent event) {
}

public void keyReleased(KeyEvent event) {
}

/**
* intercepting tabs and newlines
*/
public void keyPressed(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.VK_TAB:
insertTabChar(event.isShiftDown());
event.consume();
break;
case KeyEvent.VK_ENTER:
insertNewLine();
event.consume();
break;
}
}

/**
* insert tabs before newline character
*/
private void insertNewLine() {
snapshot(); // snapshot current setup
StringBuffer tabs = new StringBuffer();
int indent = getIndentation(), i = 0;
while (i++ < indent)
tabs.append(TAB);
insertText(NEW + tabs.toString());
}

/**
* manage keyboard tabbing, implementing blockindent.
* @param isUnindent
*/
private void insertTabChar(boolean isUnindent) {

snapshot(); // snapshot current setup

if (isSelection) { // blockindent

StringBuffer buffer = new StringBuffer();
int count = 0;
int selectStart = start;
int selectEnd = end;

// expand to nearest newlines
while (start > 0 && value.charAt(start) != NEW)
start--;
while (end < value.length() && value.charAt(end) != NEW)
end++;

// isolate each line
String temp = value.substring(start, end);
String[] lines = temp.split(String.valueOf(NEW));

// iterate lines, rebuilding tabs and newlines
for (int it = (start == 0 ? 0 : 1); it < lines.length; it++) {
if (!(start == 0 && it == 0))
buffer.append(NEW);
String line = lines[it];
if (isUnindent) {
if (line.charAt(0) == TAB) {
buffer.append(line.substring(1, line.length()));
count++;
} else
buffer.append(line);
} else {
buffer.append(TAB + line);
count++;
}
}
// replace old text with new
// TODO: optimize large selections
try {
doc.remove(start, temp.length());
} catch (BadLocationException e) {
System.out.print(e.getStackTrace());
}
insertText(buffer.toString());

// restore selection
int mod = isUnindent ? -1 : 1;
if (count > 0) {
selectStart = selectStart + mod;
selectEnd = selectEnd + count * mod;
}
setSelectionStart(isEnd ? selectStart : selectEnd);
setSelectionEnd(isEnd ? selectEnd : selectStart);
}

// normal indent
else {
if (isUnindent) {
System.out.println("TODO!");
} else
insertChar(TAB);
}
}

/**
* compute indendation level of current line
* @return indent
*/
private int getIndentation() {
int iTabs = 0;
int iChar = start - 1;
char current;
while (iChar >= 0) {
current = value.charAt(iChar);
if (current == NEW)
break;
else if (current == TAB)
iTabs++;
else
iTabs = 0;
iChar--;
}
return iTabs;
}

/**
* Set the text style.
* Tab matrix calculation presupposes a monospaced font
* @param fontFamily
* @param fontSize
* @param charsPerTab
*/
public void setTextStyle
(String fontFamily, int fontSize, int charsPerTab) {

Font font = new Font(fontFamily, Font.PLAIN, fontSize);
this.setFont(font);
StyleConstants.setFontFamily(textattributes, font.getFamily());
StyleConstants.setFontSize(textattributes, font.getSize());

FontMetrics fm = getFontMetrics(font);
int charWidth = fm.charWidth('m');
int tabWidth = charWidth * charsPerTab;

TabStop[] tabs = new TabStop[100];
for (int j = 0; j < tabs.length; j++) {
int tab = j + 1;
tabs[j] = new TabStop(tab * tabWidth);
}
TabSet tabSet = new TabSet(tabs);
StyleConstants.setTabSet(textattributes, tabSet);
getStyledDocument().setParagraphAttributes(0,
getDocument().getLength(), textattributes, true);
}

}



--
Wired Earp
Wunderbyte
.



Relevant Pages

  • Re: Sortable Java Tree Table
    ... I have never actually done this, but if I wanted to sort a JTree, ... private Listener listener = new Listener; ... public Object getChild(Object parent, int index) { ... public void valueForPathChanged{ ...
    (comp.lang.java.gui)
  • poker odds
    ... public static final int HIGH_CARD = 0; ... private static Logger logger; ... public Poker(int numCard, Card deck) ... public void maxSimulation ...
    (comp.lang.java.programmer)
  • Re: NotSerializable object issue...
    ... private static final NoopOutputStream DUMMY_OUTPUT_STREAM = new ... public SerializableCheckerthrows IOException { ... public void writeObjectthrows IOException { ... private int counter; ...
    (comp.lang.java.programmer)
  • Re: Im needing help with compile errors GameOfWar new compile errors under 2judith
    ... public static int[] randomize ... private Rank ... public void paintComponent ... class WinningsPanel extends JPanel implements ItemListener ...
    (comp.lang.java.gui)
  • Re: Im needing help with compile errors for GUI enviroment GameOfWar
    ... public static int[] randomize ... private Rank ... public void paintComponent ... class WinningsPanel extends JPanel implements ItemListener ...
    (comp.lang.java.gui)