Java/Swing JFC/TextPane
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 A custom caret class
- 2 An example of highlighting multiple, discontiguous regions of a text component.
- 3 An example of several text components including password fields and formatted fields.
- 4 An implementation of HighlightPainter that underlines text with a thick line
- 5 Appending TextPane
- 6 A separation of a data from the visual representation. In a JTextPane component, we have a StyledDocument for setting the style of the text data.
- 7 A style can have multiple attributes; this one makes text bold and italic
- 8 A TabSet in a JTextPane
- 9 Background color
- 10 Bi-Directional Text
- 11 Bold style
- 12 Brower based on JEditorPane
- 13 Change the Font size of JTextPane
- 14 Create a tab set from the tab stops
- 15 Customizing Tab Stops in a JTextPane Component
- 16 Determine if the attribute is a color or a font-related attribute.
- 17 Determining If a Style Attribute Applies to a Character or the Paragraph
- 18 Duplicate style
- 19 Enumerating the Paragraphs of a JTextPane Component
- 20 Extension of JTextPane that allows the user to easily append colored text to the document
- 21 Font family
- 22 Foreground color
- 23 Get Leading White Space
- 24 Get Leading White Space Width
- 25 Get logical style and restore it after new paragraph style
- 26 Get Max Fitting FontSize
- 27 Inserting a Component into a JTextPane Component
- 28 Inserting an Image into a JTextPane Component
- 29 Inserting Styled Text in a JTextPane Component
- 30 Italicize the entire paragraph containing the position 12
- 31 JEditorPane Replace Reader
- 32 JTextPane demo with various format and html loading and rendering
- 33 JTextPane Extended Paragraph Example
- 34 JTextPane Highlight Example
- 35 JTextPane Styles Example 1
- 36 JTextPane Styles Example 2
- 37 JTextPane Styles Example 3
- 38 JTextPane Styles Example 4
- 39 JTextPane Styles Example 5
- 40 JTextPane Styles Example 6
- 41 JTextPane Styles Example 7
- 42 JTextPane Styles Example 8
- 43 List HTML Values
- 44 Listing the Attributes in a Style
- 45 Listing the Styles Associated with a JTextPane
- 46 Parentheses matcher
- 47 Reads a AttributedString object that has been serialised by the SerialUtilities.writeAttributedString(AttributedString, ObjectOutputStream)} method.
- 48 Replace style
- 49 Set logical style; replaces paragraph style"s parent
- 50 Sharing Styles Between JTextPanes
- 51 Show how Icons, Components, and text can be added to a JTextPane
- 52 Show HTML Document
- 53 Show HTML Views
- 54 Styled Text
- 55 Tests two attributed strings for equality.
- 56 Text Component Display
- 57 TextPane: DocumentEvent
- 58 TextPane Elements
- 59 TextPane Sample
- 60 TextPane Views 2
A custom caret class
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// CornerCaret.java
//A custom caret class.
//
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;
public class CornerCaret extends DefaultCaret {
public CornerCaret() {
setBlinkRate(500); // half a second
}
protected synchronized void damage(Rectangle r) {
if (r == null)
return;
// give values to x,y,width,height (inherited from java.awt.Rectangle)
x = r.x;
y = r.y + (r.height * 4 / 5 - 3);
width = 5;
height = 5;
repaint(); // calls getComponent().repaint(x, y, width, height)
}
public void paint(Graphics g) {
JTextComponent comp = getComponent();
if (comp == null)
return;
int dot = getDot();
Rectangle r = null;
try {
r = comp.modelToView(dot);
} catch (BadLocationException e) {
return;
}
if (r == null)
return;
int dist = r.height * 4 / 5 - 3; // will be distance from r.y to top
if ((x != r.x) || (y != r.y + dist)) {
// paint() has been called directly, without a previous call to
// damage(), so do some cleanup. (This happens, for example, when
// the
// text component is resized.)
repaint(); // erase previous location of caret
x = r.x; // set new values for x,y,width,height
y = r.y + dist;
width = 5;
height = 5;
}
if (isVisible()) {
g.setColor(comp.getCaretColor());
g.drawLine(r.x, r.y + dist, r.x, r.y + dist + 4); // 5 vertical
// pixels
g.drawLine(r.x, r.y + dist + 4, r.x + 4, r.y + dist + 4); // 5 horiz
// px
}
}
public static void main(String args[]) {
JFrame frame = new JFrame("CornerCaret demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextArea area = new JTextArea(8, 32);
area.setCaret(new CornerCaret());
area
.setText("This is the story\nof the hare who\nlost his spectacles.");
frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
An example of highlighting multiple, discontiguous regions of a text component.
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// MultiHighlight.java
//An example of highlighting multiple, discontiguous regions of a text
//component.
//
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
public class MultiHighlight implements ActionListener {
private JTextComponent comp;
private String charsToHighlight;
public MultiHighlight(JTextComponent c, String chars) {
comp = c;
charsToHighlight = chars;
}
public void actionPerformed(ActionEvent e) {
// highlight all characters that appear in charsToHighlight
Highlighter h = comp.getHighlighter();
h.removeAllHighlights();
String text = comp.getText().toUpperCase();
for (int j = 0; j < text.length(); j += 1) {
char ch = text.charAt(j);
if (charsToHighlight.indexOf(ch) >= 0)
try {
h.addHighlight(j, j + 1, DefaultHighlighter.DefaultPainter);
} catch (BadLocationException ble) {
}
}
}
public static void main(String args[]) {
JFrame frame = new JFrame("MultiHighlight");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextArea area = new JTextArea(5, 20);
area
.setText("This is the story\nof the hare who\nlost his spectacles.");
frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
JButton b = new JButton("Highlight All Vowels");
b.addActionListener(new MultiHighlight(area, "aeiouAEIOU"));
frame.getContentPane().add(b, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
An example of several text components including password fields and formatted fields.
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// TextComponentSampler.java
//An example of several text components including password fields and
//formatted fields.
//
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.border.TitledBorder;
import javax.swing.text.MaskFormatter;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class TextComponentSampler extends JFrame {
public static String word = "portmeiron";
public static String markup = "Questions are <font size=\"+1\" color=\"blue\">a burden</font> to others,\n"
+ "answers <font size=\"+2\" color=\"red\">a prison</font> for oneself.";
public TextComponentSampler() {
super("TextComponentSampler");
JTextField tf = new JTextField(word, 12);
JPasswordField pf = new JPasswordField(word, 12);
MaskFormatter formatter = null;
try {
formatter = new MaskFormatter("UUUUU");
} catch (java.text.ParseException ex) {
}
JFormattedTextField ftf = new JFormattedTextField(formatter);
ftf.setColumns(12);
ftf.setValue(word);
JTextArea ta1 = new JTextArea(markup);
JScrollPane scroll1 = new JScrollPane(ta1);
JTextArea ta2 = new JTextArea(markup);
ta2.setLineWrap(true);
ta2.setWrapStyleWord(true);
JScrollPane scroll2 = new JScrollPane(ta2);
JTextPane tp = new JTextPane();
tp.setText(markup);
// Create an AttributeSet with which to change color and font.
SimpleAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setForeground(attrs, Color.blue);
StyleConstants.setFontFamily(attrs, "Serif");
// Apply the AttributeSet to a few blocks of text.
StyledDocument sdoc = tp.getStyledDocument();
sdoc.setCharacterAttributes(14, 29, attrs, false);
sdoc.setCharacterAttributes(51, 7, attrs, false);
sdoc.setCharacterAttributes(78, 28, attrs, false);
sdoc.setCharacterAttributes(114, 7, attrs, false);
JScrollPane scroll3 = new JScrollPane(tp);
JEditorPane ep1 = new JEditorPane("text/plain", markup);
JScrollPane scroll4 = new JScrollPane(ep1);
JEditorPane ep2 = new JEditorPane("text/html", markup);
JScrollPane scroll5 = new JScrollPane(ep2);
// Done creating text components; now lay them out and make them pretty.
JPanel panel_tf = new JPanel();
JPanel panel_pf = new JPanel();
JPanel panel_ftf = new JPanel();
panel_tf.add(tf);
panel_pf.add(pf);
panel_ftf.add(ftf);
panel_tf.setBorder(new TitledBorder("JTextField"));
panel_pf.setBorder(new TitledBorder("JPasswordField"));
panel_ftf.setBorder(new TitledBorder("JFormattedTextField"));
scroll1.setBorder(new TitledBorder("JTextArea (line wrap off)"));
scroll2.setBorder(new TitledBorder("JTextArea (line wrap on)"));
scroll3.setBorder(new TitledBorder("JTextPane"));
scroll4.setBorder(new TitledBorder("JEditorPane (text/plain)"));
scroll5.setBorder(new TitledBorder("JEditorPane (text/html)"));
JPanel pan = new JPanel(new FlowLayout(FlowLayout.LEFT));
pan.add(panel_tf);
pan.add(panel_pf);
pan.add(panel_ftf);
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(2, 3, 8, 8));
contentPane.add(pan);
contentPane.add(scroll1);
contentPane.add(scroll2);
contentPane.add(scroll3);
contentPane.add(scroll4);
contentPane.add(scroll5);
}
public static void main(String args[]) {
JFrame frame = new TextComponentSampler();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 450);
frame.setVisible(true);
}
}
An implementation of HighlightPainter that underlines text with a thick line
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// LineHighlightPainter.java
//An implementation of HighlightPainter that underlines text with a thick line.
//
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
public class LineHighlightPainter implements Highlighter.HighlightPainter {
// paint a thick line under one line of text, from r extending rightward to
// x2
private void paintLine(Graphics g, Rectangle r, int x2) {
int ytop = r.y + r.height - 3;
g.fillRect(r.x, ytop, x2 - r.x, 3);
}
// paint thick lines under a block of text
public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
Rectangle r0 = null, r1 = null, rbounds = bounds.getBounds();
int xmax = rbounds.x + rbounds.width; // x coordinate of right edge
try { // convert positions to pixel coordinates
r0 = c.modelToView(p0);
r1 = c.modelToView(p1);
} catch (BadLocationException ex) {
return;
}
if ((r0 == null) || (r1 == null))
return;
g.setColor(c.getSelectionColor());
// special case if p0 and p1 are on the same line
if (r0.y == r1.y) {
paintLine(g, r0, r1.x);
return;
}
// first line, from p1 to end-of-line
paintLine(g, r0, xmax);
// all the full lines in between, if any (assumes that all lines have
// the same height--not a good assumption with JEditorPane/JTextPane)
r0.y += r0.height; // move r0 to next line
r0.x = rbounds.x; // move r0 to left edge
while (r0.y < r1.y) {
paintLine(g, r0, xmax);
r0.y += r0.height; // move r0 to next line
}
// last line, from beginning-of-line to p1
paintLine(g, r0, r1.x);
}
public static void main(String args[]) {
// extend DefaultCaret as an anonymous inner class
Caret lineHighlightPainterCaret = new DefaultCaret() {
private Highlighter.HighlightPainter lhp = new LineHighlightPainter();
// override getSelectionPainter to return the LineHighlightPainter
protected Highlighter.HighlightPainter getSelectionPainter() {
return lhp;
}
};
JFrame frame = new JFrame("LineHighlightPainter demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextArea area = new JTextArea(9, 45);
area.setCaret(lineHighlightPainterCaret);
area.setLineWrap(true);
area.setWrapStyleWord(true);
area
.setText("This is the story\nof the hare who\nlost his spectacles.");
frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
Appending TextPane
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.StyledDocument;
public class AppendingTextPane extends JTextPane {
public AppendingTextPane() {
super();
}
public AppendingTextPane(StyledDocument doc) {
super(doc);
}
// Appends text to the document and ensure that it is visible
public void appendText(String text) {
try {
Document doc = getDocument();
// Move the insertion point to the end
setCaretPosition(doc.getLength());
// Insert the text
replaceSelection(text);
// Convert the new end location
// to view co-ordinates
Rectangle r = modelToView(doc.getLength());
// Finally, scroll so that the new text is visible
if (r != null) {
scrollRectToVisible(r);
}
} catch (BadLocationException e) {
System.out.println("Failed to append text: " + e);
}
}
// Testing method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Text Pane with Scrolling Append");
final AppendingTextPane atp = new AppendingTextPane();
f.getContentPane().add(new JScrollPane(atp));
f.setSize(200, 200);
f.setVisible(true);
// Add some text every second
Timer t = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String timeString = fmt.format(new Date());
atp.appendText(timeString + "\n");
}
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
});
t.start();
}
}
A separation of a data from the visual representation. In a JTextPane component, we have a StyledDocument for setting the style of the text data.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class DocumentModel {
public static void main(String[] args) {
final StyledDocument doc;
final JTextPane textpane;
JFrame f = new JFrame();
f.setTitle("Document Model");
JToolBar toolbar = new JToolBar();
JButton boldb = new JButton("bold");
JButton italb = new JButton("italic");
JButton strib = new JButton("strike");
JButton undeb = new JButton("underline");
toolbar.add(boldb);
toolbar.add(italb);
toolbar.add(strib);
toolbar.add(undeb);
f.add(toolbar, BorderLayout.NORTH);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JScrollPane pane = new JScrollPane();
textpane = new JTextPane();
textpane.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
doc = textpane.getStyledDocument();
Style style = textpane.addStyle("Bold", null);
StyleConstants.setBold(style, true);
style = textpane.addStyle("Italic", null);
StyleConstants.setItalic(style, true);
style = textpane.addStyle("Underline", null);
StyleConstants.setUnderline(style, true);
style = textpane.addStyle("Strike", null);
StyleConstants.setStrikeThrough(style, true);
boldb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doc.setCharacterAttributes(textpane.getSelectionStart(), textpane.getSelectionEnd()
- textpane.getSelectionStart(), textpane.getStyle("Bold"), false);
}
});
italb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doc.setCharacterAttributes(textpane.getSelectionStart(), textpane.getSelectionEnd()
- textpane.getSelectionStart(), textpane.getStyle("Italic"), false);
}
});
strib.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doc.setCharacterAttributes(textpane.getSelectionStart(), textpane.getSelectionEnd()
- textpane.getSelectionStart(), textpane.getStyle("Strike"), false);
}
});
undeb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doc.setCharacterAttributes(textpane.getSelectionStart(), textpane.getSelectionEnd()
- textpane.getSelectionStart(), textpane.getStyle("Underline"), false);
}
});
pane.getViewport().add(textpane);
panel.add(pane);
f.add(panel);
f.setSize(new Dimension(380, 320));
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
A style can have multiple attributes; this one makes text bold and italic
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
// A style can have multiple attributes; this one makes text bold and italic
Style style = textPane.addStyle("Bold Italic", null);
StyleConstants.setBold(style, true);
StyleConstants.setItalic(style, true);
}
}
A TabSet in a JTextPane
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// TabExample.java
//Demonstrate a TabSet in a JTextPane.
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;
public class TabExample {
public static void main(String[] args) {
JTextPane pane = new JTextPane();
TabStop[] tabs = new TabStop[4];
tabs[0] = new TabStop(60, TabStop.ALIGN_RIGHT, TabStop.LEAD_NONE);
tabs[1] = new TabStop(100, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
tabs[2] = new TabStop(200, TabStop.ALIGN_CENTER, TabStop.LEAD_NONE);
tabs[3] = new TabStop(300, TabStop.ALIGN_DECIMAL, TabStop.LEAD_NONE);
TabSet tabset = new TabSet(tabs);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.TabSet, tabset);
pane.setParagraphAttributes(aset, false);
pane.setText("\tright\tleft\tcenter\tdecimal\n" + "\t1\t1\t1\t1.0\n"
+ "\t200.002\t200.002\t200.002\t200.002\n"
+ "\t.33\t.33\t.33\t.33\n");
JFrame frame = new JFrame("TabExample");
frame.setContentPane(new JScrollPane(pane));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(360, 120);
frame.setVisible(true);
}
}
Background color
public class Main{
public static void main(String[] argv){
// Get the text pane"s document
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument)textPane.getDocument();
// Create a style object and then set the style attributes
Style style = doc.addStyle("StyleName", null);
StyleConstants.setBackground(style, Color.blue);
// Append to document
doc.insertString(doc.getLength(), "Some Text", style);
} }
Bi-Directional Text
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
/*
Bi-Directional Text. Model Order and Visual Order. Caret Position and the Selection.
How Bi-Directional Text Is Handled in the Swing Text Components.
*/
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.io.PrintStream;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;
public class BidiTextExample {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Bi-directional Text");
final JTextPane tp = new JTextPane();
if (args.length > 0 && args[0].equalsIgnoreCase("Arabic")) {
GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
System.out.println("Using physical font");
Font font = new Font("Lucida Sans Regular", Font.PLAIN, 32);
tp.setFont(font);
} else {
Font font = new Font("Serif", Font.PLAIN, 32);
tp.setFont(font);
}
String s = new String(new char[] { (char) "A", (char) 0xFE76,
(char) 0xFE77, (char) 0xFE78, (char) "Z" });
final AbstractDocument doc = (AbstractDocument) tp.getDocument();
System.out.println("i18n property is " + doc.getProperty("i18n"));
// Turn on bi-directional text
doc.putProperty("i18n", Boolean.TRUE);
try {
doc.insertString(0, s, null);
} catch (Exception e) {
}
f.getContentPane().add(new JScrollPane(tp));
f.setSize(300, 300);
f.setVisible(true);
tp.addCaretListener(new CaretListener() {
public void caretUpdate(CaretEvent evt) {
System.out.println("Caret position is " + evt.getDot());
}
});
try {
Thread.sleep(10000);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Dump the model
doc.dump(System.out);
// Show the views
ViewDisplayer.displayViews(tp, System.out);
}
});
} catch (Exception e) {
}
}
}
class ViewDisplayer {
public static void displayViews(JTextComponent comp, PrintStream out) {
View rootView = comp.getUI().getRootView(comp);
displayView(rootView, 0, comp.getDocument(), out);
}
public static void displayView(View view, int indent, Document doc,
PrintStream out) {
String name = view.getClass().getName();
for (int i = 0; i < indent; i++) {
out.print("\t");
}
int start = view.getStartOffset();
int end = view.getEndOffset();
out.println(name + "; offsets [" + start + ", " + end + "]");
int viewCount = view.getViewCount();
if (viewCount == 0) {
int length = Math.min(32, end - start);
try {
String txt = doc.getText(start, length);
for (int i = 0; i < indent + 1; i++) {
out.print("\t");
}
out.println("[" + txt + "]");
} catch (BadLocationException e) {
}
} else {
for (int i = 0; i < viewCount; i++) {
displayView(view.getView(i), indent + 1, doc, out);
}
}
}
}
Bold style
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setBold(style, true);
doc.insertString(doc.getLength(), "Some Text", style);
}
}
Brower based on JEditorPane
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.URL;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ruboBoxModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
public class Browser extends JFrame {
protected JEditorPane m_browser;
protected MemComboBox m_locator = new MemComboBox();
public Browser() {
super("HTML Browser");
setSize(500, 300);
getContentPane().setLayout(new BorderLayout());
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
p.add(new JLabel("Address"));
m_locator.load("addresses.dat");
BrowserListener lst = new BrowserListener();
m_locator.addActionListener(lst);
MemComboAgent agent = new MemComboAgent(m_locator);
p.add(m_locator);
getContentPane().add(p, BorderLayout.NORTH);
m_browser = new JEditorPane();
m_browser.setEditable(false);
m_browser.addHyperlinkListener(lst);
JScrollPane sp = new JScrollPane();
sp.getViewport().add(m_browser);
getContentPane().add(sp, BorderLayout.CENTER);
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
m_locator.save("addresses.dat");
System.exit(0);
}
};
addWindowListener(wndCloser);
setVisible(true);
m_locator.grabFocus();
}
class BrowserListener implements ActionListener, HyperlinkListener {
public void actionPerformed(ActionEvent evt) {
String sUrl = (String) m_locator.getSelectedItem();
if (sUrl == null || sUrl.length() == 0 )
return;
BrowserLoader loader = new BrowserLoader(sUrl);
loader.start();
}
public void hyperlinkUpdate(HyperlinkEvent e) {
URL url = e.getURL();
if (url == null )
return;
BrowserLoader loader = new BrowserLoader(url.toString());
loader.start();
}
}
class BrowserLoader extends Thread {
protected String m_sUrl;
public BrowserLoader(String sUrl) {
m_sUrl = sUrl;
}
public void run() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
URL source = new URL(m_sUrl);
m_browser.setPage(source);
m_locator.add(m_sUrl);
} catch (Exception e) {
JOptionPane.showMessageDialog(Browser.this, "Error: "
+ e.toString(), "Warning", JOptionPane.WARNING_MESSAGE);
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
public static void main(String argv[]) {
new Browser();
}
}
class MemComboAgent extends KeyAdapter {
protected JComboBox m_comboBox;
protected JTextField m_editor;
public MemComboAgent(JComboBox comboBox) {
m_comboBox = comboBox;
m_editor = (JTextField) comboBox.getEditor().getEditorComponent();
m_editor.addKeyListener(this);
}
public void keyReleased(KeyEvent e) {
char ch = e.getKeyChar();
if (ch == KeyEvent.CHAR_UNDEFINED || Character.isISOControl(ch))
return;
int pos = m_editor.getCaretPosition();
String str = m_editor.getText();
if (str.length() == 0)
return;
for (int k = 0; k < m_comboBox.getItemCount(); k++) {
String item = m_comboBox.getItemAt(k).toString();
if (item.startsWith(str)) {
m_editor.setText(item);
m_editor.setCaretPosition(item.length());
m_editor.moveCaretPosition(pos);
break;
}
}
}
}
class MemComboBox extends JComboBox {
public static final int MAX_MEM_LEN = 30;
public MemComboBox() {
super();
setEditable(true);
}
public void add(String item) {
removeItem(item);
insertItemAt(item, 0);
setSelectedItem(item);
if (getItemCount() > MAX_MEM_LEN)
removeItemAt(getItemCount() - 1);
}
public void load(String fName) {
try {
if (getItemCount() > 0)
removeAllItems();
File f = new File(fName);
if (!f.exists())
return;
FileInputStream fStream = new FileInputStream(f);
ObjectInput stream = new ObjectInputStream(fStream);
Object obj = stream.readObject();
if (obj instanceof ComboBoxModel)
setModel((ComboBoxModel) obj);
stream.close();
fStream.close();
} catch (Exception e) {
System.err.println("Serialization error: " + e.toString());
}
}
public void save(String fName) {
try {
FileOutputStream fStream = new FileOutputStream(fName);
ObjectOutput stream = new ObjectOutputStream(fStream);
stream.writeObject(getModel());
stream.flush();
stream.close();
fStream.close();
} catch (Exception e) {
System.err.println("Serialization error: " + e.toString());
}
}
}
Change the Font size of JTextPane
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception{
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
// Create a style object and then set the style attributes
Style style = doc.addStyle("StyleName", null);
StyleConstants.setFontSize(style, 30);
doc.insertString(doc.getLength(), "Some Text", style);
}
}
Create a tab set from the tab stops
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;
public class Main {
public static void main(String[] argv) {
JTextPane textPane = new JTextPane();
List list = new ArrayList();
TabStop[] tstops = (TabStop[]) list.toArray(new TabStop[0]);
TabSet tabs = new TabSet(tstops);
Style style = textPane.getLogicalStyle();
StyleConstants.setTabSet(style, tabs);
textPane.setLogicalStyle(style);
}
}
Customizing Tab Stops in a JTextPane Component
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextPane;
import javax.swing.text.TabStop;
public class Main {
public static void main(String[] argv) {
List list = new ArrayList();
// Create a left-aligned tab stop at 100 pixels from the left margin
float pos = 100;
int align = TabStop.ALIGN_LEFT;
int leader = TabStop.LEAD_NONE;
TabStop tstop = new TabStop(pos, align, leader);
list.add(tstop);
}
}
import javax.swing.text.AttributeSet;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) {
// Check if color-based attribute
boolean b = StyleConstants.Foreground instanceof AttributeSet.ColorAttribute;
b = StyleConstants.Italic instanceof AttributeSet.ColorAttribute;
// Check if font-based attribute
b = StyleConstants.Italic instanceof AttributeSet.FontAttribute;
b = StyleConstants.Foreground instanceof AttributeSet.FontAttribute;
}
}
Determining If a Style Attribute Applies to a Character or the Paragraph
import javax.swing.text.AttributeSet;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) {
// Check if character-based attribute
boolean b = StyleConstants.Italic instanceof AttributeSet.CharacterAttribute;
b = StyleConstants.LineSpacing instanceof AttributeSet.CharacterAttribute;
// Check if paragraph-based attribute
b = StyleConstants.LineSpacing instanceof AttributeSet.ParagraphAttribute;
b = StyleConstants.Italic instanceof AttributeSet.ParagraphAttribute;
}
}
Duplicate style
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
// Set text in the range [5, 7) red
doc.setCharacterAttributes(5, 2, textPane.getStyle("Red"), true);
}
}
Enumerating the Paragraphs of a JTextPane Component
import javax.swing.JTextPane;
import javax.swing.text.Element;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
Element section = textPane.getDocument().getDefaultRootElement();
int paraCount = section.getElementCount();
for (int i = 0; i < paraCount; i++) {
Element e = section.getElement(i);
int rangeStart = e.getStartOffset();
int rangeEnd = e.getEndOffset();
String para = textPane.getText(rangeStart, rangeEnd - rangeStart);
System.out.println(para);
}
}
}
Extension of JTextPane that allows the user to easily append colored text to the document
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// ColorPane.java
//A simple extension of JTextPane that allows the user to easily append
//colored text to the document.
//
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
public class ColorPane extends JTextPane {
public void appendNaive(Color c, String s) { // naive implementation
// bad: instiantiates a new AttributeSet object on each call
SimpleAttributeSet aset = new SimpleAttributeSet();
StyleConstants.setForeground(aset, c);
int len = getText().length();
setCaretPosition(len); // place caret at the end (with no selection)
setCharacterAttributes(aset, false);
replaceSelection(s); // there is no selection, so inserts at caret
}
public void append(Color c, String s) { // better implementation--uses
// StyleContext
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, c);
int len = getDocument().getLength(); // same value as
// getText().length();
setCaretPosition(len); // place caret at the end (with no selection)
setCharacterAttributes(aset, false);
replaceSelection(s); // there is no selection, so inserts at caret
}
public static void main(String argv[]) {
ColorPane pane = new ColorPane();
for (int n = 1; n <= 400; n += 1) {
if (isPrime(n)) {
pane.append(Color.red, String.valueOf(n) + " ");
} else if (isPerfectSquare(n)) {
pane.append(Color.blue, String.valueOf(n) + " ");
} else {
pane.append(Color.black, String.valueOf(n) + " ");
}
}
JFrame f = new JFrame("ColorPane example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new JScrollPane(pane));
f.setSize(600, 400);
f.setVisible(true);
}
public static boolean isPrime(int n) {
if (n < 2)
return false;
double max = Math.sqrt(n);
for (int j = 2; j <= max; j += 1)
if (n % j == 0)
return false; // j is a factor
return true;
}
public static boolean isPerfectSquare(int n) {
int j = 1;
while (j * j < n && j * j > 0)
j += 1;
return (j * j == n);
}
}
Font family
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setFontFamily(style, "SansSerif");
// Append to document
doc.insertString(doc.getLength(), "Some Text", style);
}
}
Foreground color
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception{
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
// Create a style object and then set the style attributes
Style style = doc.addStyle("StyleName", null);
StyleConstants.setForeground(style, Color.white);
// Append to document
doc.insertString(doc.getLength(), "Some Text", style);
}
}
Get Leading White Space
/*
* StandardUtilities.java - Various miscallaneous utility functions
* :tabSize=8:indentSize=8:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 1999, 2006 Matthieu Casanova, Slava Pestov
* Portions copyright (C) 2000 Richard S. Hall
* Portions copyright (C) 2001 Dirk Moebius
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//{{{ Imports
import javax.swing.text.Segment;
import java.util.ruparator;
import java.util.Stack;
//}}}
/**
* Several tools that depends on JDK only.
*
* @author Matthieu Casanova
* @version $Id: StandardUtilities.java 12884 2008-06-23 18:17:08Z kpouer $
* @since 4.3pre5
*/
public class StandardUtilities
{
//{{{ getLeadingWhiteSpace() method
/**
* Returns the number of leading white space characters in the
* specified string.
*
* @param str The string
*/
public static int getLeadingWhiteSpace(String str)
{
return getLeadingWhiteSpace((CharSequence)str);
} //}}}
//{{{ getLeadingWhiteSpace() method
/**
* Returns the number of leading white space characters in the
* specified string.
*
* @param str The string
* @since jEdit 4.3pre15
*/
public static int getLeadingWhiteSpace(CharSequence str)
{
int whitespace = 0;
loop: for(;whitespace < str.length();)
{
switch(str.charAt(whitespace))
{
case " ":
case "\t":
whitespace++;
break;
default:
break loop;
}
}
return whitespace;
} //}}}
}
Get Leading White Space Width
/*
* StandardUtilities.java - Various miscallaneous utility functions
* :tabSize=8:indentSize=8:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 1999, 2006 Matthieu Casanova, Slava Pestov
* Portions copyright (C) 2000 Richard S. Hall
* Portions copyright (C) 2001 Dirk Moebius
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//{{{ Imports
import javax.swing.text.Segment;
import java.util.ruparator;
import java.util.Stack;
//}}}
/**
* Several tools that depends on JDK only.
*
* @author Matthieu Casanova
* @version $Id: StandardUtilities.java 12884 2008-06-23 18:17:08Z kpouer $
* @since 4.3pre5
*/
public class StandardUtilities
{
//{{{ getLeadingWhiteSpaceWidth() method
/**
* Returns the width of the leading white space in the specified
* string.
* @param str The string
* @param tabSize The tab size
*/
public static int getLeadingWhiteSpaceWidth(String str, int tabSize)
{
return getLeadingWhiteSpaceWidth((CharSequence)str, tabSize);
} //}}}
//{{{ getLeadingWhiteSpaceWidth() method
/**
* Returns the width of the leading white space in the specified
* string.
* @param str The string
* @param tabSize The tab size
* @since jEdit 4.3pre15
*/
public static int getLeadingWhiteSpaceWidth(CharSequence str, int tabSize)
{
int whitespace = 0;
loop: for(int i = 0; i < str.length(); i++)
{
switch(str.charAt(i))
{
case " ":
whitespace++;
break;
case "\t":
whitespace += tabSize -
whitespace % tabSize;
break;
default:
break loop;
}
}
return whitespace;
} //}}}
}
Get logical style and restore it after new paragraph style
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
Style style = textPane.addStyle(null, null);
StyleConstants.setForeground(style, Color.red);
textPane.setLogicalStyle(style);
Style logicalStyle = textPane.getLogicalStyle();
style = textPane.addStyle(null, null);
StyleConstants.setBold(style, true);
textPane.setParagraphAttributes(style, true);
textPane.setLogicalStyle(logicalStyle);
}
}
Get Max Fitting FontSize
/**
* The utillib library.
* More information is available at http://www.jinchess.ru/.
* Copyright (C) 2002 Alexander Maryanovsky.
* All rights reserved.
*
* The utillib library is free software; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The utillib library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with utillib library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.awt.*;
/**
* Provides graphics related utilities.
*/
public class GraphicsUtilities{
/**
* Calculates the largest size of the given font for which the given string
* will fit into the given size. This method uses the default toolkit.
*/
public static int getMaxFittingFontSize(Graphics g, Font font, String string, Dimension size){
return getMaxFittingFontSize(g, font, string, size.width, size.height);
}
/**
* Calculates the largest size of the given font for which the given string
* will fit into the given size.
*/
public static int getMaxFittingFontSize(Graphics g, Font font, String string, int width, int height){
int minSize = 0;
int maxSize = 288;
int curSize = font.getSize();
while (maxSize - minSize > 2){
FontMetrics fm = g.getFontMetrics(new Font(font.getName(), font.getStyle(), curSize));
int fontWidth = fm.stringWidth(string);
int fontHeight = fm.getLeading() + fm.getMaxAscent() + fm.getMaxDescent();
if ((fontWidth > width) || (fontHeight > height)){
maxSize = curSize;
curSize = (maxSize + minSize) / 2;
}
else{
minSize = curSize;
curSize = (minSize + maxSize) / 2;
}
}
return curSize;
}
/**
* Returns the <code>FontMetrics</code> for the specified <code>Font</code>.
*/
public static FontMetrics getFontMetrics(Font font){
return Toolkit.getDefaultToolkit().getFontMetrics(font); // DEPRECATED
}
/**
* Returns <code>true</code> if the first rectangle completely contains the
* second one. Returns <code>false</code> otherwise. This method is needed
* because there is no Rectangle.contains(Rectangle) method in JDK 1.1
* (unlike claimed in the 1.2 documentation).
*/
public static boolean contains(Rectangle rect1, Rectangle rect2){
return (rect2.x >= rect1.x) &&
(rect2.y >= rect1.y) &&
(rect2.x+rect2.width <= rect1.x+rect1.width) &&
(rect2.y+rect2.height <= rect1.y+rect1.height);
}
/**
* Returns true if the two specified rectangles intersect. Two rectangles
* intersect if their intersection is nonempty. This method is not really
* needed because Rectangle.intersects(Rectangle) exists in JDK1.1, but I
* still like having it here for symmetry.
*/
public static boolean intersect(Rectangle rect1, Rectangle rect2){
return rect1.intersects(rect2);
}
}
Inserting a Component into a JTextPane Component
import javax.swing.JButton;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setComponent(style, new JButton("OK"));
doc.insertString(doc.getLength(), "ignored text", style);
}
}
Inserting an Image into a JTextPane Component
import javax.swing.ImageIcon;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception{
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, new ImageIcon("imagefile"));
doc.insertString(doc.getLength(), "ignored text", style);
}
}
Inserting Styled Text in a JTextPane Component
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception{
JTextPane textPane = new JTextPane();
StyledDocument doc = (StyledDocument) textPane.getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setItalic(style, true);
doc.insertString(doc.getLength(), "Some Text", style);
}
}
Italicize the entire paragraph containing the position 12
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
// Italicize the entire paragraph containing the position 12
doc.setParagraphAttributes(12, 1, textPane.getStyle("Italic"), true);
}
}
JEditorPane Replace Reader
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.io.FileReader;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
public class ReplaceReader {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("JEditorPane with Custom Reader");
JEditorPane ep = new JEditorPane();
f.getContentPane().add(new JScrollPane(ep));
f.setSize(400, 300);
f.setVisible(true);
HTMLEditorKit kit = new HTMLEditorKit() {
public Document createDefaultDocument() {
HTMLDocument doc = new CustomHTMLDocument(getStyleSheet());
doc.setAsynchronousLoadPriority(4);
doc.setTokenThreshold(100);
return doc;
}
};
ep.setEditorKit(kit);
try {
Document doc = ep.getDocument();
doc.putProperty("IgnoreCharsetDirective", new Boolean(true));
kit.read(new FileReader(args[0]), doc, 0);
} catch (Exception e) {
System.out.println("Exception while reading HTML " + e);
}
}
}
class CustomHTMLDocument extends HTMLDocument {
CustomHTMLDocument(StyleSheet styles) {
super(styles);
}
public HTMLEditorKit.ParserCallback getReader(int pos) {
return new CustomReader(pos);
}
class CustomReader extends HTMLDocument.HTMLReader {
public CustomReader(int pos) {
super(pos);
}
public void flush() throws BadLocationException {
System.out.println("flush called");
super.flush();
}
public void handleText(char[] data, int pos) {
indent();
System.out.println("handleText <" + new String(data) + ">, pos " + pos);
super.handleText(data, pos);
}
public void handleComment(char[] data, int pos) {
indent();
System.out.println("handleComment <" + new String(data) + ">, pos " + pos);
super.handleComment(data, pos);
}
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
indent();
System.out.println("handleStartTag <" + t + ">, pos " + pos);
indent();
System.out.println("Attributes: " + a);
tagLevel++;
super.handleStartTag(t, a, pos);
}
public void handleEndTag(HTML.Tag t, int pos) {
tagLevel--;
indent();
System.out.println("handleEndTag <" + t + ">, pos " + pos);
super.handleEndTag(t, pos);
}
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
indent();
System.out.println("handleSimpleTag <" + t + ">, pos " + pos);
indent();
System.out.println("Attributes: " + a);
super.handleSimpleTag(t, a, pos);
}
public void handleError(String errorMsg, int pos){
indent();
System.out.println("handleError <" + errorMsg + ">, pos " + pos);
super.handleError(errorMsg, pos);
}
protected void indent() {
for (int i = 0; i < tagLevel; i++) {
System.out.print(" ");
}
}
int tagLevel;
}
}
JTextPane demo with various format and html loading and rendering
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
public class JTextPaneDemo extends JFrame {
static SimpleAttributeSet ITALIC_GRAY = new SimpleAttributeSet();
static SimpleAttributeSet BOLD_BLACK = new SimpleAttributeSet();
static SimpleAttributeSet BLACK = new SimpleAttributeSet();
JTextPane textPane = new JTextPane();
// Best to reuse attribute sets as much as possible.
static {
StyleConstants.setForeground(ITALIC_GRAY, Color.gray);
StyleConstants.setItalic(ITALIC_GRAY, true);
StyleConstants.setFontFamily(ITALIC_GRAY, "Helvetica");
StyleConstants.setFontSize(ITALIC_GRAY, 14);
StyleConstants.setForeground(BOLD_BLACK, Color.black);
StyleConstants.setBold(BOLD_BLACK, true);
StyleConstants.setFontFamily(BOLD_BLACK, "Helvetica");
StyleConstants.setFontSize(BOLD_BLACK, 14);
StyleConstants.setForeground(BLACK, Color.black);
StyleConstants.setFontFamily(BLACK, "Helvetica");
StyleConstants.setFontSize(BLACK, 14);
}
public JTextPaneDemo() {
super("JTextPane Demo");
JScrollPane scrollPane = new JScrollPane(textPane);
getContentPane().add(scrollPane, BorderLayout.CENTER);
setEndSelection();
textPane.insertIcon(new ImageIcon("jexpLogo.GIF"));
insertText("\nWebsite for: www.jexp.ru \n\n", BOLD_BLACK);
setEndSelection();
insertText(" ", BLACK);
setEndSelection();
insertText("\n Java "
+ " " + "Source\n\n",
ITALIC_GRAY);
insertText(" and Support. \n", BLACK);
setEndSelection();
JButton manningButton = new JButton("Load the web site for www.jexp.ru");
manningButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textPane.setEditable(false);
try {
textPane.setPage("http://www.jexp.ru");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
textPane.insertComponent(manningButton);
setSize(500, 450);
setVisible(true);
}
protected void insertText(String text, AttributeSet set) {
try {
textPane.getDocument().insertString(
textPane.getDocument().getLength(), text, set);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
// Needed for inserting icons in the right places
protected void setEndSelection() {
textPane.setSelectionStart(textPane.getDocument().getLength());
textPane.setSelectionEnd(textPane.getDocument().getLength());
}
public static void main(String argv[]) {
new JTextPaneDemo();
}
}
JTextPane Extended Paragraph Example
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.ParagraphView;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
public class ExtendedParagraphExample {
public static void createDocumentStyles(StyleContext sc) {
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
// Create and add the main document style
Style mainStyle = sc.addStyle(mainStyleName, defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
Style cwStyle = sc.addStyle(charStyleName, null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.white);
// Create and add the heading style
Style heading2Style = sc.addStyle(heading2StyleName, null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
// Create and add the extended para styles
Style paraStyle = sc.addStyle(paraStyleName, null);
Color bgColor = Color.gray;
ExtendedStyleConstants.setParagraphBackground(paraStyle, bgColor);
ExtendedStyleConstants.setParagraphBorder(paraStyle, BorderFactory
.createCompoundBorder(BorderFactory.createEmptyBorder(2, 2, 2,
2), BorderFactory.createCompoundBorder(BorderFactory
.createEtchedBorder(bgColor.brighter(), bgColor
.darker()), BorderFactory.createEmptyBorder(4,
4, 4, 4))));
}
public static void addText(JTextPane pane, StyleContext sc,
Style logicalStyle, Paragraph[] content) {
// The outer loop adds paragraphs, while the
// inner loop adds character runs.
int paragraphs = content.length;
for (int i = 0; i < paragraphs; i++) {
Run[] runs = content[i].content;
for (int j = 0; j < runs.length; j++) {
pane.setCharacterAttributes(
runs[j].styleName == null ? SimpleAttributeSet.EMPTY
: sc.getStyle(runs[j].styleName), true);
pane.replaceSelection(runs[j].content);
}
// At the end of the paragraph, add the logical style and
// any overriding paragraph style and then terminate the
// paragraph with a newline.
pane.setParagraphAttributes(SimpleAttributeSet.EMPTY, true);
if (logicalStyle != null) {
pane.setLogicalStyle(logicalStyle);
}
if (content[i].styleName != null) {
pane.setParagraphAttributes(sc.getStyle(content[i].styleName),
false);
}
if (i != paragraphs - 1) {
pane.replaceSelection("\n");
}
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Extended Paragraph Example");
// Create the StyleContext, the document and the pane
final StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
pane.setEditorKit(new ExtendedStyledEditorKit());
try {
// Add the text and apply the styles
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
// Build the styles
createDocumentStyles(sc);
// Add the text
addText(pane, sc, sc.getStyle(mainStyleName), content);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
// Style names
public static final String mainStyleName = "MainStyle";
public static final String heading2StyleName = "Heading2";
public static final String charStyleName = "ConstantWidth";
public static final String paraStyleName = "ExtendedPara";
// Inner classes used to define paragraph structure
public static class Run {
public Run(String styleName, String content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public String content;
}
public static class Paragraph {
public Paragraph(String styleName, Run[] content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public Run[] content;
}
public static final Paragraph[] content = new Paragraph[] {
new Paragraph(heading2StyleName, new Run[] { new Run(null,
"Attributes, Styles and Style Contexts") }),
new Paragraph(
paraStyleName,
new Run[] {
new Run(null, "The simple "),
new Run(charStyleName, "PlainDocument"),
new Run(
null,
" class that you saw in the previous "
+ "chapter is only capable of holding text. "
+ "The more complex text components use a more "
+ "sophisticated model that implements the "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " interface. "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " is a sub-interface of "),
new Run(charStyleName, "Document"),
new Run(
null,
" that contains methods for manipulating attributes "
+ "that control the way in which the text in the "
+ "document is displayed. The Swing text package "
+ "contains a concrete implementation of "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " called "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null,
" that is used as the default model for "),
new Run(charStyleName, "JTextPane"),
new Run(
null,
" and is also the base class from which "
+ "more specific models, such as the "),
new Run(charStyleName, "HTMLDocument"),
new Run(
null,
" class that handles input in HTML format, can be "
+ "created. In order to make use of "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " and "),
new Run(charStyleName, "JTextPane"),
new Run(null,
" you need to understand how Swing represents "
+ "and uses attributes.") }) };
}
class ExtendedStyleConstants {
public ExtendedStyleConstants(String name) {
this.name = name;
}
public String toString() {
return name;
}
/**
* The border to be used for a paragraph. Type is javax.swing.border.Border
*/
public static final Object ParagraphBorder = ExtendedParagraphConstants.ParagraphBorder;
/**
* The background to be used for a paragraph. Type is java.awt.Color
*/
public static final Object ParagraphBackground = ExtendedParagraphConstants.ParagraphBackground;
/* Adds the border attribute */
public static void setParagraphBorder(MutableAttributeSet a, Border b) {
a.addAttribute(ParagraphBorder, b);
}
/* Gets the border attribute */
public static Border getParagraphBorder(AttributeSet a) {
return (Border) a.getAttribute(ParagraphBorder);
}
/* Adds the paragraph background attribute */
public static void setParagraphBackground(MutableAttributeSet a, Color c) {
a.addAttribute(ParagraphBackground, c);
}
/* Gets the paragraph background attribute */
public static Color getParagraphBackground(AttributeSet a) {
return (Color) a.getAttribute(ParagraphBackground);
}
/* A typesafe collection of extended paragraph attributes */
public static class ExtendedParagraphConstants extends
ExtendedStyleConstants implements AttributeSet.ParagraphAttribute {
/**
* The paragraph border attribute.
*/
public static final Object ParagraphBorder = new ExtendedParagraphConstants(
"ParagraphBorder");
/**
* The paragraph background attribute.
*/
public static final Object ParagraphBackground = new ExtendedParagraphConstants(
"ParagraphBackground");
private ExtendedParagraphConstants(String name) {
super(name);
}
}
protected String name; // Name of an attribute
}
class ExtendedStyledEditorKit extends StyledEditorKit {
public Object clone() {
return new ExtendedStyledEditorKit();
}
public ViewFactory getViewFactory() {
return defaultFactory;
}
/* The extended view factory */
static class ExtendedStyledViewFactory implements ViewFactory {
public View create(Element elem) {
String elementName = elem.getName();
if (elementName != null) {
if (elementName.equals(AbstractDocument.ParagraphElementName)) {
return new ExtendedParagraphView(elem);
}
}
// Delegate others to StyledEditorKit
return styledEditorKitFactory.create(elem);
}
}
private static final ViewFactory styledEditorKitFactory = (new StyledEditorKit())
.getViewFactory();
private static final ViewFactory defaultFactory = new ExtendedStyledViewFactory();
}
class ExtendedParagraphView extends ParagraphView {
public ExtendedParagraphView(Element elem) {
super(elem);
}
// Override ParagraphView methods
protected void setPropertiesFromAttributes() {
AttributeSet attr = getAttributes();
if (attr != null) {
super.setPropertiesFromAttributes();
paraInsets = new Insets(getTopInset(), getLeftInset(),
getBottomInset(), getRightInset());
border = ExtendedStyleConstants.getParagraphBorder(attr);
bgColor = ExtendedStyleConstants.getParagraphBackground(attr);
if (bgColor != null && border == null) {
// Provide a small margin if the background
// is being filled and there is no border
border = smallBorder;
}
if (border != null) {
Insets borderInsets = border.getBorderInsets(getContainer());
setInsets((short) (paraInsets.top + borderInsets.top),
(short) (paraInsets.left + borderInsets.left),
(short) (paraInsets.bottom + borderInsets.bottom),
(short) (paraInsets.right + borderInsets.right));
}
}
}
public void paint(Graphics g, Shape a) {
Container comp = getContainer();
Rectangle alloc = new Rectangle(a.getBounds());
alloc.x += paraInsets.left;
alloc.y += paraInsets.top;
alloc.width -= paraInsets.left + paraInsets.right;
alloc.height -= paraInsets.top + paraInsets.bottom;
if (bgColor != null) {
Color origColor = g.getColor();
g.setColor(bgColor);
g.fillRect(alloc.x, alloc.y, alloc.width, alloc.height);
g.setColor(origColor);
}
if (border != null) {
// Paint the border
border.paintBorder(comp, g, alloc.x, alloc.y, alloc.width,
alloc.height);
}
super.paint(g, a); // Note: pass ORIGINAL allocation
}
// Attribute cache
protected Color bgColor; // Background color, or null for transparent.
protected Border border; // Border, or null for no border
protected Insets paraInsets; // Original paragraph insets
protected static final Border smallBorder = BorderFactory
.createEmptyBorder(2, 2, 2, 2);
}
JTextPane Highlight Example
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileReader;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.LayeredHighlighter;
import javax.swing.text.Position;
import javax.swing.text.View;
public class HighlightExample {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Highlight example");
final JTextPane textPane = new JTextPane();
textPane.setHighlighter(highlighter);
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(new JLabel("Enter word: "), "West");
final JTextField tf = new JTextField();
pane.add(tf, "Center");
f.getContentPane().add(pane, "South");
f.getContentPane().add(new JScrollPane(textPane), "Center");
try {
textPane.read(new FileReader("links1.html"), null);
} catch (Exception e) {
System.out.println("Failed to load file " + args[0]);
System.out.println(e);
}
final WordSearcher searcher = new WordSearcher(textPane);
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
word = tf.getText().trim();
int offset = searcher.search(word);
if (offset != -1) {
try {
textPane.scrollRectToVisible(textPane
.modelToView(offset));
} catch (BadLocationException e) {
}
}
}
});
textPane.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent evt) {
searcher.search(word);
}
public void removeUpdate(DocumentEvent evt) {
searcher.search(word);
}
public void changedUpdate(DocumentEvent evt) {
}
});
f.setSize(400, 400);
f.setVisible(true);
}
public static String word;
public static Highlighter highlighter = new UnderlineHighlighter(null);
}
// A simple class that searches for a word in
// a document and highlights occurrences of that word
class WordSearcher {
public WordSearcher(JTextComponent comp) {
this.rup = comp;
this.painter = new UnderlineHighlighter.UnderlineHighlightPainter(
Color.red);
}
// Search for a word and return the offset of the
// first occurrence. Highlights are added for all
// occurrences found.
public int search(String word) {
int firstOffset = -1;
Highlighter highlighter = comp.getHighlighter();
// Remove any existing highlights for last word
Highlighter.Highlight[] highlights = highlighter.getHighlights();
for (int i = 0; i < highlights.length; i++) {
Highlighter.Highlight h = highlights[i];
if (h.getPainter() instanceof UnderlineHighlighter.UnderlineHighlightPainter) {
highlighter.removeHighlight(h);
}
}
if (word == null || word.equals("")) {
return -1;
}
// Look for the word we are given - insensitive search
String content = null;
try {
Document d = comp.getDocument();
content = d.getText(0, d.getLength()).toLowerCase();
} catch (BadLocationException e) {
// Cannot happen
return -1;
}
word = word.toLowerCase();
int lastIndex = 0;
int wordSize = word.length();
while ((lastIndex = content.indexOf(word, lastIndex)) != -1) {
int endIndex = lastIndex + wordSize;
try {
highlighter.addHighlight(lastIndex, endIndex, painter);
} catch (BadLocationException e) {
// Nothing to do
}
if (firstOffset == -1) {
firstOffset = lastIndex;
}
lastIndex = endIndex;
}
return firstOffset;
}
protected JTextComponent comp;
protected Highlighter.HighlightPainter painter;
}
class UnderlineHighlighter extends DefaultHighlighter {
public UnderlineHighlighter(Color c) {
painter = (c == null ? sharedPainter : new UnderlineHighlightPainter(c));
}
// Convenience method to add a highlight with
// the default painter.
public Object addHighlight(int p0, int p1) throws BadLocationException {
return addHighlight(p0, p1, painter);
}
public void setDrawsLayeredHighlights(boolean newValue) {
// Illegal if false - we only support layered highlights
if (newValue == false) {
throw new IllegalArgumentException(
"UnderlineHighlighter only draws layered highlights");
}
super.setDrawsLayeredHighlights(true);
}
// Painter for underlined highlights
public static class UnderlineHighlightPainter extends
LayeredHighlighter.LayerPainter {
public UnderlineHighlightPainter(Color c) {
color = c;
}
public void paint(Graphics g, int offs0, int offs1, Shape bounds,
JTextComponent c) {
// Do nothing: this method will never be called
}
public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds,
JTextComponent c, View view) {
g.setColor(color == null ? c.getSelectionColor() : color);
Rectangle alloc = null;
if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) {
if (bounds instanceof Rectangle) {
alloc = (Rectangle) bounds;
} else {
alloc = bounds.getBounds();
}
} else {
try {
Shape shape = view.modelToView(offs0,
Position.Bias.Forward, offs1,
Position.Bias.Backward, bounds);
alloc = (shape instanceof Rectangle) ? (Rectangle) shape
: shape.getBounds();
} catch (BadLocationException e) {
return null;
}
}
FontMetrics fm = c.getFontMetrics(c.getFont());
int baseline = alloc.y + alloc.height - fm.getDescent() + 1;
g.drawLine(alloc.x, baseline, alloc.x + alloc.width, baseline);
g.drawLine(alloc.x, baseline + 1, alloc.x + alloc.width,
baseline + 1);
return alloc;
}
protected Color color; // The color for the underline
}
// Shared painter used for default highlighting
protected static final Highlighter.HighlightPainter sharedPainter = new UnderlineHighlightPainter(
null);
// Painter used for this highlighter
protected Highlighter.HighlightPainter painter;
}
JTextPane Styles Example 1
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample1 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 1");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
JTextPane pane = new JTextPane(doc);
// Create and add the style
final Style heading2Style = sc.addStyle("Heading2", null);
heading2Style.addAttribute(StyleConstants.Foreground, Color.red);
heading2Style.addAttribute(StyleConstants.FontSize, new Integer(16));
heading2Style.addAttribute(StyleConstants.FontFamily, "serif");
heading2Style.addAttribute(StyleConstants.Bold, new Boolean(true));
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Add the text to the document
doc.insertString(0, text, null);
// Finally, apply the style to the heading
doc.setParagraphAttributes(0, 1, heading2Style, false);
} catch (BadLocationException e) {
}
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text = "Attributes, Styles and Style Contexts\n"
+ "The simple PlainDocument class that you saw in the previous "
+ "chapter is only capable of holding text. The more complex text "
+ "components use a more sophisticated model that implements the "
+ "StyledDocument interface. StyledDocument is a sub-interface of "
+ "Document that contains methods for manipulating attributes that "
+ "control the way in which the text in the document is displayed. "
+ "The Swing text package contains a concrete implementation of "
+ "StyledDocument called DefaultStyledDocument that is used as the "
+ "default model for JTextPane and is also the base class from which "
+ "more specific models, such as the HTMLDocument class that handles "
+ "input in HTML format, can be created. In order to make use of "
+ "DefaultStyledDocument and JTextPane, you need to understand how "
+ "Swing represents and uses attributes.\n";
}
JTextPane Styles Example 2
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample2 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 2");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
JTextPane pane = new JTextPane(doc);
// Create and add the main document style
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
final Style mainStyle = sc.addStyle("MainStyle", defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
final Style cwStyle = sc.addStyle("ConstantWidth", null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
final Style heading2Style = sc.addStyle("Heading2", null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Set the logical style
doc.setLogicalStyle(0, mainStyle);
// Add the text to the document
doc.insertString(0, text, null);
// Apply the character attributes
doc.setCharacterAttributes(49, 13, cwStyle, false);
doc.setCharacterAttributes(223, 14, cwStyle, false);
doc.setCharacterAttributes(249, 14, cwStyle, false);
doc.setCharacterAttributes(286, 8, cwStyle, false);
doc.setCharacterAttributes(475, 14, cwStyle, false);
doc.setCharacterAttributes(497, 21, cwStyle, false);
doc.setCharacterAttributes(557, 9, cwStyle, false);
doc.setCharacterAttributes(639, 12, cwStyle, false);
doc.setCharacterAttributes(733, 21, cwStyle, false);
doc.setCharacterAttributes(759, 9, cwStyle, false);
// Finally, apply the style to the heading
doc.setParagraphAttributes(0, 1, heading2Style, false);
} catch (BadLocationException e) {
}
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text =
"Attributes, Styles and Style Contexts\n" +
"The simple PlainDocument class that you saw in the previous " +
"chapter is only capable of holding text. The more complex text " +
"components use a more sophisticated model that implements the " +
"StyledDocument interface. StyledDocument is a sub-interface of " +
"Document that contains methods for manipulating attributes that " +
"control the way in which the text in the document is displayed. " +
"The Swing text package contains a concrete implementation of " +
"StyledDocument called DefaultStyledDocument that is used as the " +
"default model for JTextPane and is also the base class from which " +
"more specific models, such as the HTMLDocument class that handles " +
"input in HTML format, can be created. In order to make use of " +
"DefaultStyledDocument and JTextPane, you need to understand how " +
"Swing represents and uses attributes.\n";
}
JTextPane Styles Example 3
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample3 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 3");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
JTextPane pane = new JTextPane(doc);
// Create and add the main document style
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
final Style mainStyle = sc.addStyle("MainStyle", defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Set the logical style
doc.setLogicalStyle(0, mainStyle);
// Add the text to the document
doc.insertString(0, text, null);
} catch (BadLocationException e) {
}
doc.dump(System.out);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text =
"Attributes, Styles and Style Contexts\n" +
"The simple PlainDocument class that you saw in the previous " +
"chapter is only capable of holding text. The more complex text " +
"components use a more sophisticated model that implements the " +
"StyledDocument interface. StyledDocument is a sub-interface of " +
"Document that contains methods for manipulating attributes that " +
"control the way in which the text in the document is displayed. " +
"The Swing text package contains a concrete implementation of " +
"StyledDocument called DefaultStyledDocument that is used as the " +
"default model for JTextPane and is also the base class from which " +
"more specific models, such as the HTMLDocument class that handles " +
"input in HTML format, can be created. In order to make use of " +
"DefaultStyledDocument and JTextPane, you need to understand how " +
"Swing represents and uses attributes.\n";
}
JTextPane Styles Example 4
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample4 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 4");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
JTextPane pane = new JTextPane(doc);
// Create and add the main document style
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
final Style mainStyle = sc.addStyle("MainStyle", defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Add the text to the document
doc.insertString(0, text, null);
// Set the logical style
doc.setLogicalStyle(0, mainStyle);
} catch (BadLocationException e) {
}
doc.dump(System.out);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text =
"Attributes, Styles and Style Contexts\n" +
"The simple PlainDocument class that you saw in the previous " +
"chapter is only capable of holding text. The more complex text " +
"components use a more sophisticated model that implements the " +
"StyledDocument interface. StyledDocument is a sub-interface of " +
"Document that contains methods for manipulating attributes that " +
"control the way in which the text in the document is displayed. " +
"The Swing text package contains a concrete implementation of " +
"StyledDocument called DefaultStyledDocument that is used as the " +
"default model for JTextPane and is also the base class from which " +
"more specific models, such as the HTMLDocument class that handles " +
"input in HTML format, can be created. In order to make use of " +
"DefaultStyledDocument and JTextPane, you need to understand how " +
"Swing represents and uses attributes.\n";
}
JTextPane Styles Example 5
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample5 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 5");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Create and add the style
final Style heading2Style = sc.addStyle("Heading2", null);
heading2Style.addAttribute(StyleConstants.Foreground, Color.red);
heading2Style.addAttribute(StyleConstants.FontSize, new Integer(16));
heading2Style.addAttribute(StyleConstants.FontFamily, "serif");
heading2Style.addAttribute(StyleConstants.Bold, new Boolean(true));
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Add the text to the document
doc.insertString(0, text, null);
// Finally, apply the style to the heading
doc.setParagraphAttributes(0, 1, heading2Style, false);
// Set the foreground and font
pane.setForeground(Color.blue);
pane.setFont(new Font("serif", Font.PLAIN, 12));
} catch (BadLocationException e) {
}
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text =
"Attributes, Styles and Style Contexts\n" +
"The simple PlainDocument class that you saw in the previous " +
"chapter is only capable of holding text. The more complex text " +
"components use a more sophisticated model that implements the " +
"StyledDocument interface. StyledDocument is a sub-interface of " +
"Document that contains methods for manipulating attributes that " +
"control the way in which the text in the document is displayed. " +
"The Swing text package contains a concrete implementation of " +
"StyledDocument called DefaultStyledDocument that is used as the " +
"default model for JTextPane and is also the base class from which " +
"more specific models, such as the HTMLDocument class that handles " +
"input in HTML format, can be created. In order to make use of " +
"DefaultStyledDocument and JTextPane, you need to understand how " +
"Swing represents and uses attributes.\n";
}
JTextPane Styles Example 6
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample6 {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 6");
// Create the StyleContext, the document and the pane
StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Create and add the main document style
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
final Style mainStyle = sc.addStyle("MainStyle", defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
final Style cwStyle = sc.addStyle("ConstantWidth", null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
final Style heading2Style = sc.addStyle("Heading2", null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
// Set the logical style
doc.setLogicalStyle(0, mainStyle);
// Add the text to the document
doc.insertString(0, text, null);
// Apply the character attributes
doc.setCharacterAttributes(49, 13, cwStyle, false);
doc.setCharacterAttributes(223, 14, cwStyle, false);
doc.setCharacterAttributes(249, 14, cwStyle, false);
doc.setCharacterAttributes(286, 8, cwStyle, false);
doc.setCharacterAttributes(475, 14, cwStyle, false);
doc.setCharacterAttributes(497, 21, cwStyle, false);
doc.setCharacterAttributes(557, 9, cwStyle, false);
doc.setCharacterAttributes(639, 12, cwStyle, false);
doc.setCharacterAttributes(733, 21, cwStyle, false);
doc.setCharacterAttributes(759, 9, cwStyle, false);
// Finally, apply the style to the heading
doc.setParagraphAttributes(0, 1, heading2Style, false);
// Set the foreground color and change the font
pane.setForeground(Color.pink);
pane.setFont(new Font("Monospaced", Font.ITALIC, 24));
} catch (BadLocationException e) {
}
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
public static final String text =
"Attributes, Styles and Style Contexts\n" +
"The simple PlainDocument class that you saw in the previous " +
"chapter is only capable of holding text. The more complex text " +
"components use a more sophisticated model that implements the " +
"StyledDocument interface. StyledDocument is a sub-interface of " +
"Document that contains methods for manipulating attributes that " +
"control the way in which the text in the document is displayed. " +
"The Swing text package contains a concrete implementation of " +
"StyledDocument called DefaultStyledDocument that is used as the " +
"default model for JTextPane and is also the base class from which " +
"more specific models, such as the HTMLDocument class that handles " +
"input in HTML format, can be created. In order to make use of " +
"DefaultStyledDocument and JTextPane, you need to understand how " +
"Swing represents and uses attributes.\n";
}
JTextPane Styles Example 7
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class StylesExample7 {
public static void createDocumentStyles(StyleContext sc) {
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
// Create and add the main document style
Style mainStyle = sc.addStyle(mainStyleName, defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
Style cwStyle = sc.addStyle(charStyleName, null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
Style heading2Style = sc.addStyle(heading2StyleName, null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
}
public static void addText(JTextPane pane, StyleContext sc, Style logicalStyle,
Paragraph[] content) {
// The outer loop adds paragraphs, while the
// inner loop adds character runs.
int paragraphs = content.length;
for (int i = 0; i < paragraphs; i++) {
Run[] runs = content[i].content;
for (int j = 0; j < runs.length; j++) {
pane.setCharacterAttributes(
runs[j].styleName == null ? SimpleAttributeSet.EMPTY :
sc.getStyle(runs[j].styleName), true);
pane.replaceSelection(runs[j].content);
}
// At the end of the paragraph, add the logical style and
// any overriding paragraph style and then terminate the
// paragraph with a newline.
pane.setParagraphAttributes(SimpleAttributeSet.EMPTY, true);
if (logicalStyle != null) {
pane.setLogicalStyle(logicalStyle);
}
if (content[i].styleName != null) {
pane.setParagraphAttributes(sc.getStyle(content[i].styleName), false);
}
pane.replaceSelection("\n");
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 7");
// Create the StyleContext, the document and the pane
final StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Build the styles
createDocumentStyles(sc);
try {
// Add the text and apply the styles
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
// Add the text
addText(pane, sc, sc.getStyle(mainStyleName), content);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(400, 300);
f.setVisible(true);
}
// Style names
public static final String mainStyleName = "MainStyle";
public static final String heading2StyleName = "Heading2";
public static final String charStyleName = "ConstantWidth";
// Inner classes used to define paragraph structure
public static class Run {
public Run(String styleName, String content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public String content;
}
public static class Paragraph {
public Paragraph(String styleName, Run[] content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public Run[] content;
}
public static final Paragraph[] content = new Paragraph[] {
new Paragraph(heading2StyleName, new Run[] {
new Run(null, "Attributes, Styles and Style Contexts")
}),
new Paragraph(null, new Run[] {
new Run(null, "The simple "),
new Run(charStyleName, "PlainDocument"),
new Run(null, " class that you saw in the previous " +
"chapter is only capable of holding text. " +
"The more complex text components use a more " +
"sophisticated model that implements the "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " interface. "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " is a sub-interface of "),
new Run(charStyleName, "Document"),
new Run(null, " that contains methods for manipulating attributes " +
"that control the way in which the text in the " +
"document is displayed. The Swing text package " +
"contains a concrete implementation of "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " called "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " that is used as the default model for "),
new Run(charStyleName, "JTextPane"),
new Run(null, " and is also the base class from which " +
"more specific models, such as the "),
new Run(charStyleName, "HTMLDocument"),
new Run(null, " class that handles input in HTML format, can be " +
"created. In order to make use of "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " and "),
new Run(charStyleName, "JTextPane"),
new Run(null, " you need to understand how Swing represents " +
"and uses attributes.")
})
};
}
JTextPane Styles Example 8
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.net.URL;
public class StylesExample8 {
public static void createDocumentStyles(StyleContext sc) {
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
// Create and add the main document style
Style mainStyle = sc.addStyle(mainStyleName, defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
Style cwStyle = sc.addStyle(charStyleName, null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
Style heading2Style = sc.addStyle(heading2StyleName, null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
// Create and add the Component style
Class thisClass = StylesExample8.class;
URL url = thisClass.getResource("jexp.gif");
ImageIcon icon = new ImageIcon(url);
JLabel comp = new JLabel("Displaying text with attributes",
icon, JLabel.CENTER);
comp.setVerticalTextPosition(JLabel.BOTTOM);
comp.setHorizontalTextPosition(JLabel.CENTER);
comp.setFont(new Font("serif", Font.BOLD | Font.ITALIC, 14));
Style componentStyle = sc.addStyle(componentStyleName, null);
StyleConstants.setComponent(componentStyle, comp);
// The paragraph style for the component
Style compParagraphStyle = sc.addStyle(compParaName, null);
StyleConstants.setSpaceAbove(compParagraphStyle, (float)16.0);
}
public static void addText(JTextPane pane, StyleContext sc, Style logicalStyle,
Paragraph[] content) {
// The outer loop adds paragraphs, while the
// inner loop adds character runs.
int paragraphs = content.length;
for (int i = 0; i < paragraphs; i++) {
Run[] runs = content[i].content;
for (int j = 0; j < runs.length; j++) {
pane.setCharacterAttributes(
runs[j].styleName == null ? SimpleAttributeSet.EMPTY :
sc.getStyle(runs[j].styleName), true);
pane.replaceSelection(runs[j].content);
}
// At the end of the paragraph, add the logical style and
// any overriding paragraph style and then terminate the
// paragraph with a newline.
pane.setParagraphAttributes(SimpleAttributeSet.EMPTY, true);
if (logicalStyle != null) {
pane.setLogicalStyle(logicalStyle);
}
if (content[i].styleName != null) {
pane.setParagraphAttributes(sc.getStyle(content[i].styleName), false);
}
pane.replaceSelection("\n");
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Styles Example 8");
// Create the StyleContext, the document and the pane
final StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Build the styles
createDocumentStyles(sc);
try {
// Add the text and apply the styles
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
// Add the text
addText(pane, sc, sc.getStyle(mainStyleName), content);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(500, 300);
f.setVisible(true);
}
// Style names
public static final String mainStyleName = "MainStyle";
public static final String heading2StyleName = "Heading2";
public static final String charStyleName = "ConstantWidth";
public static final String componentStyleName = "Component";
public static final String compParaName = "CompPara";
// Inner classes used to define paragraph structure
public static class Run {
public Run(String styleName, String content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public String content;
}
public static class Paragraph {
public Paragraph(String styleName, Run[] content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public Run[] content;
}
public static final Paragraph[] content = new Paragraph[] {
new Paragraph(heading2StyleName, new Run[] {
new Run(null, "Attributes, Styles and Style Contexts")
}),
new Paragraph(null, new Run[] {
new Run(null, "The simple "),
new Run(charStyleName, "PlainDocument"),
new Run(null, " class that you saw in the previous " +
"chapter is only capable of holding text. " +
"The more complex text components use a more " +
"sophisticated model that implements the "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " interface. "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " is a sub-interface of "),
new Run(charStyleName, "Document"),
new Run(null, " that contains methods for manipulating attributes " +
"that control the way in which the text in the " +
"document is displayed. The Swing text package " +
"contains a concrete implementation of "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " called "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " that is used as the default model for "),
new Run(charStyleName, "JTextPane"),
new Run(null, " and is also the base class from which " +
"more specific models, such as the "),
new Run(charStyleName, "HTMLDocument"),
new Run(null, " class that handles input in HTML format, can be " +
"created. In order to make use of "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " and "),
new Run(charStyleName, "JTextPane"),
new Run(null, " you need to understand how Swing represents " +
"and uses attributes.")
}),
new Paragraph(compParaName, new Run[] {
new Run(componentStyleName, " ")
})
};
}
List HTML Values
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.text.html.HTML;
public class ListHTMLValues {
public static void main(String[] args) {
HTML.Tag[] tags = HTML.getAllTags();
HTML.Attribute[] attrs = HTML.getAllAttributeKeys();
System.out.println("HTML Tags:");
for (int i = 0; i < tags.length - 1; i++) {
System.out.print(tags[i] + ", ");
if ((i % 8) == 7) {
System.out.println("");
}
}
System.out.println(tags[tags.length - 1]);
System.out.println("\n\nHTML Attributes:");
for (int i = 0; i < attrs.length - 1; i++) {
System.out.print(attrs[i] + ", ");
if ((i % 8) == 7) {
System.out.println("");
}
}
System.out.println(attrs[attrs.length - 1]);
}
}
Listing the Attributes in a Style
import java.util.Enumeration;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
DefaultStyledDocument doc = (DefaultStyledDocument) textPane.getDocument();
Enumeration e1 = doc.getStyleNames();
while (e1.hasMoreElements()) {
String styleName = (String) e1.nextElement();
System.out.println(styleName);
Style style = doc.getStyle(styleName);
int count = style.getAttributeCount();
System.out.println(count);
Enumeration e = style.getAttributeNames();
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (o instanceof String) {
String attrName = (String) o;
Object attrValue = style.getAttribute(attrName);
System.out.println(attrValue);
} else if (o == StyleConstants.NameAttribute) {
styleName = (String) style.getAttribute(o);
System.out.println(styleName);
} else if (o == StyleConstants.ResolveAttribute) {
Style parent = (Style) style.getAttribute(o);
System.out.println(parent.getName());
} else {
String attrName = o.toString();
System.out.println(attrName);
Object attrValue = style.getAttribute(o);
System.out.println(attrValue);
}
}
}
}
}
Listing the Styles Associated with a JTextPane
import java.util.Enumeration;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
DefaultStyledDocument doc = (DefaultStyledDocument) textPane.getDocument();
Enumeration e = doc.getStyleNames();
while (e.hasMoreElements()) {
String styleName = (String) e.nextElement();
System.out.println(styleName);
Style style = doc.getStyle(styleName);
}
}
}
Parentheses matcher
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// ParenMatcher.java
//A simple parenthesis matcher.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class ParenMatcher extends JTextPane implements Runnable {
public static Color[] matchColor = { Color.blue, Color.magenta, Color.green };
public static Color badColor = Color.red;
private AttributeSet[] matchAttrSet;
private AttributeSet badAttrSet;
public ParenMatcher() {
// create an array of AttributeSets from the array of Colors
StyleContext sc = StyleContext.getDefaultStyleContext();
badAttrSet = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, badColor);
matchAttrSet = new AttributeSet[matchColor.length];
for (int j = 0; j < matchColor.length; j += 1)
matchAttrSet[j] = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, matchColor[j]);
}
// match and color the parens/brackets/braces
public void run() {
StyledDocument doc = getStyledDocument();
String text = "";
int len = doc.getLength();
try {
text = doc.getText(0, len);
} catch (BadLocationException ble) {
}
java.util.Stack stack = new java.util.Stack();
for (int j = 0; j < text.length(); j += 1) {
char ch = text.charAt(j);
if (ch == "(" || ch == "[" || ch == "{") {
int depth = stack.size();
stack.push("" + ch + j); // push a String containg the char and
// the offset
AttributeSet aset = matchAttrSet[depth % matchAttrSet.length];
doc.setCharacterAttributes(j, 1, aset, false);
}
if (ch == ")" || ch == "]" || ch == "}") {
String peek = stack.empty() ? "." : (String) stack.peek();
if (matches(peek.charAt(0), ch)) { // does it match?
stack.pop();
int depth = stack.size();
AttributeSet aset = matchAttrSet[depth
% matchAttrSet.length];
doc.setCharacterAttributes(j, 1, aset, false);
} else { // mismatch
doc.setCharacterAttributes(j, 1, badAttrSet, false);
}
}
}
while (!stack.empty()) { // anything left in the stack is a mismatch
String pop = (String) stack.pop();
int offset = Integer.parseInt(pop.substring(1));
doc.setCharacterAttributes(offset, 1, badAttrSet, false);
}
}
// unset the foreground color (if any) whenever the user enters text
// (if not for this, text entered after a paren would catch the paren"s
// color)
public void replaceSelection(String content) {
getInputAttributes().removeAttribute(StyleConstants.Foreground);
super.replaceSelection(content);
}
// return true if "left" and "right" are matching parens/brackets/braces
public static boolean matches(char left, char right) {
if (left == "(")
return (right == ")");
if (left == "[")
return (right == "]");
if (left == "{")
return (right == "}");
return false;
}
public static void main(String[] args) {
JFrame frame = new JFrame("ParenMatcher");
final ParenMatcher matcher = new ParenMatcher();
matcher.setText("int fact(int n) {\n" + " if (n <= 1) return 1;\n"
+ " return(n * fact(n-1));\n" + "}\n");
frame.getContentPane().add(new JScrollPane(matcher),
BorderLayout.CENTER);
JButton matchButton = new JButton("match parens");
matchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
matcher.run();
}
});
frame.getContentPane().add(matchButton, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 150);
frame.setVisible(true);
}
}
Reads a AttributedString object that has been serialised by the SerialUtilities.writeAttributedString(AttributedString, ObjectOutputStream)} method.
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.CharacterIterator;
import java.util.HashMap;
import java.util.Map;
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* IOUtils.java
* ------------
* (C)opyright 2002-2004, by Thomas Morgner and Contributors.
*
* Original Author: Thomas Morgner;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
*
* Changes
* -------
* 26-Jan-2003 : Initial version
* 23-Feb-2003 : Documentation
* 25-Feb-2003 : Fixed Checkstyle issues (DG);
* 29-Apr-2003 : Moved to jcommon
* 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
* added support for query strings within these urls (TM);
*/
public class Main {
/**
* Returns <code>true</code> if a class implements <code>Serializable</code>
* and <code>false</code> otherwise.
*
* @param c the class.
*
* @return A boolean.
*/
public static boolean isSerializable(final Class c) {
/**
final Class[] interfaces = c.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].equals(Serializable.class)) {
return true;
}
}
Class cc = c.getSuperclass();
if (cc != null) {
return isSerializable(cc);
}
*/
return (Serializable.class.isAssignableFrom(c));
}
/**
* Reads a <code>AttributedString</code> object that has been serialised by
* the {@link SerialUtilities#writeAttributedString(AttributedString,
* ObjectOutputStream)} method.
*
* @param stream the input stream (<code>null</code> not permitted).
*
* @return The attributed string object (possibly <code>null</code>).
*
* @throws IOException if there is an I/O problem.
* @throws ClassNotFoundException if there is a problem loading a class.
*/
public static AttributedString readAttributedString(
ObjectInputStream stream)
throws IOException, ClassNotFoundException {
if (stream == null) {
throw new IllegalArgumentException("Null "stream" argument.");
}
AttributedString result = null;
final boolean isNull = stream.readBoolean();
if (!isNull) {
// read string and attributes then create result
String plainStr = (String) stream.readObject();
result = new AttributedString(plainStr);
char c = stream.readChar();
int start = 0;
while (c != CharacterIterator.DONE) {
int limit = stream.readInt();
Map atts = (Map) stream.readObject();
result.addAttributes(atts, start, limit);
start = limit;
c = stream.readChar();
}
}
return result;
}
/**
* Serialises an <code>AttributedString</code> object.
*
* @param as the attributed string object (<code>null</code> permitted).
* @param stream the output stream (<code>null</code> not permitted).
*
* @throws IOException if there is an I/O error.
*/
public static void writeAttributedString(AttributedString as,
ObjectOutputStream stream) throws IOException {
if (stream == null) {
throw new IllegalArgumentException("Null "stream" argument.");
}
if (as != null) {
stream.writeBoolean(false);
AttributedCharacterIterator aci = as.getIterator();
// build a plain string from aci
// then write the string
StringBuffer plainStr = new StringBuffer();
char current = aci.first();
while (current != CharacterIterator.DONE) {
plainStr = plainStr.append(current);
current = aci.next();
}
stream.writeObject(plainStr.toString());
// then write the attributes and limits for each run
current = aci.first();
int begin = aci.getBeginIndex();
while (current != CharacterIterator.DONE) {
// write the current character - when the reader sees that this
// is not CharacterIterator.DONE, it will know to read the
// run limits and attributes
stream.writeChar(current);
// now write the limit, adjusted as if beginIndex is zero
int limit = aci.getRunLimit();
stream.writeInt(limit - begin);
// now write the attribute set
Map atts = new HashMap(aci.getAttributes());
stream.writeObject(atts);
current = aci.setIndex(limit);
}
// write a character that signals to the reader that all runs
// are done...
stream.writeChar(CharacterIterator.DONE);
}
else {
// write a flag that indicates a null
stream.writeBoolean(true);
}
}
}
Replace style
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
Style style = textPane.addStyle(null, null);
StyleConstants.setForeground(style, Color.red);
textPane.setLogicalStyle(style);
// Set paragraph style; removes logical style
style = textPane.addStyle(null, null);
StyleConstants.setUnderline(style, true);
textPane.setParagraphAttributes(style, true);
// paragraph is now underlined, not red
}
}
Set logical style; replaces paragraph style"s parent
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane textPane = new JTextPane();
Style style = textPane.addStyle(null, null);
StyleConstants.setForeground(style, Color.red);
textPane.setLogicalStyle(style);
style = textPane.addStyle(null, null);
StyleConstants.setForeground(style, Color.red);
textPane.setLogicalStyle(style);
}
}
Sharing Styles Between JTextPanes
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
public class Main {
public static void main(String[] argv) throws Exception {
JTextPane c1 = new JTextPane();
JTextPane c2 = new JTextPane();
StyleContext styleContext = new StyleContext();
c1.setDocument(new DefaultStyledDocument(styleContext));
c2.setDocument(new DefaultStyledDocument(styleContext));
Style style = c1.addStyle("style name", null);
StyleConstants.setForeground(style, Color.red);
style = c2.getStyle("style name");
StyleConstants.setBold(style, true);
}
}
Show how Icons, Components, and text can be added to a JTextPane
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// PaneInsertionMethods.java
//Show how Icons, Components, and text can be added to a JTextPane.
//
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
public class PaneInsertionMethods {
public static void main(String[] args) {
final JTextPane pane = new JTextPane();
// button to insert some text
JButton textButton = new JButton("Insert Text");
textButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
pane.replaceSelection("text");
}
});
// button to insert an icon
final ImageIcon icon = new ImageIcon("bluepaw.gif");
JButton iconButton = new JButton(icon);
iconButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
pane.insertIcon(icon);
}
});
// button to insert a button
JButton buttonButton = new JButton("Insert Button");
buttonButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
pane.insertComponent(new JButton("Click Me"));
}
});
// layout
JPanel buttons = new JPanel();
buttons.add(textButton);
buttons.add(iconButton);
buttons.add(buttonButton);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.getContentPane().add(buttons, BorderLayout.SOUTH);
frame.setSize(360, 180);
frame.setVisible(true);
}
}
Show HTML Document
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.PrintStream;
import java.util.Enumeration;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
public class ShowHTMLDocument {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
try {
JFrame f = new JFrame("HTMLDocument Structure");
final JEditorPane ep = new JEditorPane("links1.html");
ep.setEditable(false);
f.getContentPane().add(new JScrollPane(ep));
f.setSize(400, 300);
f.setVisible(true);
ep.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("page")) {
HTMLDocDisplay.displayModel(ep, System.out);
}
}
});
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
}
}
class HTMLDocDisplay {
public static void displayAttributes(AttributeSet a, int indent,
PrintStream out) {
if (a == null)
return;
a = a.copyAttributes();
Enumeration x = a.getAttributeNames();
for (int i = 0; i < indent; i++) {
out.print(" ");
}
if (x != null) {
out.println("ATTRIBUTES:");
while (x.hasMoreElements()) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
Object attr = x.nextElement();
out.println(" (" + attr + ", " + a.getAttribute(attr) + ")"
+ " [" + getShortClassName(attr.getClass()) + "/"
+ getShortClassName(a.getAttribute(attr).getClass())
+ "] ");
}
} else {
out.println("No attributes");
}
if (a.getResolveParent() != null) {
displayAttributes(a.getResolveParent().copyAttributes(),
indent + 1, out);
}
}
public static void displayModel(JTextComponent comp, PrintStream out) {
Document doc = comp.getDocument();
Element e = doc.getDefaultRootElement();
displayElement(doc, e, 0, out);
}
public static void displayElement(Document doc, Element e, int indent,
PrintStream out) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("===== Element Class: " + getShortClassName(e.getClass()));
for (int i = 0; i < indent; i++) {
out.print(" ");
}
int startOffset = e.getStartOffset();
int endOffset = e.getEndOffset();
out.println("Offsets [" + startOffset + ", " + endOffset + "]");
AttributeSet a = e.getAttributes();
Enumeration x = a.getAttributeNames();
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("ATTRIBUTES:");
while (x.hasMoreElements()) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
Object attr = x.nextElement();
out
.println(" ("
+ attr
+ ", "
+ a.getAttribute(attr)
+ ")"
+ " ["
+ getShortClassName(attr.getClass())
+ "/"
+ getShortClassName(a.getAttribute(attr).getClass())
+ "] ");
}
// Display the text for a leaf element
if (e.isLeaf()) {
try {
String str = doc.getText(startOffset, endOffset - startOffset);
if (str.length() > 40) {
str = str.substring(0, 40);
}
if (str.length() > 0) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("[" + str + "]");
}
} catch (BadLocationException ex) {
}
}
// Display child elements
int count = e.getElementCount();
for (int i = 0; i < count; i++) {
displayElement(doc, e.getElement(i), indent + 1, out);
}
}
public static String getShortClassName(Class clazz) {
String className = clazz.getName();
return className.substring(className.lastIndexOf(".") + 1);
}
}
Show HTML Views
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.PrintStream;
import java.util.Enumeration;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;
public class ShowHTMLViews {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
try {
JFrame f = new JFrame("HTML Document View Structure");
final JEditorPane ep = new JEditorPane(args[0]);
ep.setEditable(false);
f.getContentPane().add(new JScrollPane(ep));
f.setSize(400, 300);
f.setVisible(true);
ep.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("page")) {
System.out.println("Document:\n");
HTMLDocDisplay.displayModel(ep, System.out);
System.out.println("\n\nViews:\n");
HTMLViewDisplayer.displayViews(ep, System.out);
}
}
});
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
}
}
class HTMLDocDisplay {
public static void displayAttributes(AttributeSet a, int indent,
PrintStream out) {
if (a == null)
return;
a = a.copyAttributes();
Enumeration x = a.getAttributeNames();
for (int i = 0; i < indent; i++) {
out.print(" ");
}
if (x != null) {
out.println("ATTRIBUTES:");
while (x.hasMoreElements()) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
Object attr = x.nextElement();
out.println(" (" + attr + ", " + a.getAttribute(attr) + ")"
+ " [" + getShortClassName(attr.getClass()) + "/"
+ getShortClassName(a.getAttribute(attr).getClass())
+ "] ");
}
} else {
out.println("No attributes");
}
if (a.getResolveParent() != null) {
displayAttributes(a.getResolveParent().copyAttributes(),
indent + 1, out);
}
}
public static void displayModel(JTextComponent comp, PrintStream out) {
Document doc = comp.getDocument();
Element e = doc.getDefaultRootElement();
displayElement(doc, e, 0, out);
}
public static void displayElement(Document doc, Element e, int indent,
PrintStream out) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("===== Element Class: " + getShortClassName(e.getClass()));
for (int i = 0; i < indent; i++) {
out.print(" ");
}
int startOffset = e.getStartOffset();
int endOffset = e.getEndOffset();
out.println("Offsets [" + startOffset + ", " + endOffset + "]");
AttributeSet a = e.getAttributes();
Enumeration x = a.getAttributeNames();
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("ATTRIBUTES:");
while (x.hasMoreElements()) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
Object attr = x.nextElement();
out
.println(" ("
+ attr
+ ", "
+ a.getAttribute(attr)
+ ")"
+ " ["
+ getShortClassName(attr.getClass())
+ "/"
+ getShortClassName(a.getAttribute(attr).getClass())
+ "] ");
}
// Display the text for a leaf element
if (e.isLeaf()) {
try {
String str = doc.getText(startOffset, endOffset - startOffset);
if (str.length() > 40) {
str = str.substring(0, 40);
}
if (str.length() > 0) {
for (int i = 0; i < indent; i++) {
out.print(" ");
}
out.println("[" + str + "]");
}
} catch (BadLocationException ex) {
}
}
// Display child elements
int count = e.getElementCount();
for (int i = 0; i < count; i++) {
displayElement(doc, e.getElement(i), indent + 1, out);
}
}
public static String getShortClassName(Class clazz) {
String className = clazz.getName();
return className.substring(className.lastIndexOf(".") + 1);
}
}
class HTMLViewDisplayer {
public static void displayViews(JTextComponent comp, PrintStream out) {
View rootView = comp.getUI().getRootView(comp);
displayView(rootView, 0, comp.getDocument(), out);
}
public static void displayView(View view, int indent, Document doc,
PrintStream out) {
String name = view.getClass().getName();
for (int i = 0; i < indent; i++) {
out.print(" ");
}
int start = view.getStartOffset();
int end = view.getEndOffset();
out.println(name + "; offsets [" + start + ", " + end + "]");
for (int i = 0; i < indent; i++) {
out.print(" ");
}
HTMLDocDisplay.displayAttributes(view.getAttributes(), indent, out);
int viewCount = view.getViewCount();
if (viewCount == 0) {
int length = Math.min(32, end - start);
try {
String txt = doc.getText(start, length);
for (int i = 0; i < indent + 1; i++) {
out.print(" ");
}
out.println("[" + txt + "]");
} catch (BadLocationException e) {
}
} else {
for (int i = 0; i < viewCount; i++) {
displayView(view.getView(i), indent + 1, doc, out);
}
}
out.println("");
}
}
Styled Text
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class StyledText {
public static void main(String args[]) throws BadLocationException {
JFrame jf = new JFrame("StyledText");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = jf.getContentPane();
JTextPane pane = new JTextPane();
SimpleAttributeSet set = new SimpleAttributeSet();
StyleConstants.setBold(set, true);
// Set the attributes before adding text
pane.setCharacterAttributes(set, true);
pane.setText("Eine ");
set = new SimpleAttributeSet();
StyleConstants.setItalic(set, true);
StyleConstants.setForeground(set, Color.red);
StyleConstants.setBackground(set, Color.blue);
Document doc = pane.getStyledDocument();
doc.insertString(doc.getLength(), "Kleine ", set);
set = new SimpleAttributeSet();
StyleConstants.setFontSize(set, 24);
doc.insertString(doc.getLength(), "Nachtmusic", set);
JScrollPane scrollPane = new JScrollPane(pane);
cp.add(scrollPane, BorderLayout.CENTER);
jf.setSize(400, 300);
jf.setVisible(true);
}
}
Tests two attributed strings for equality.
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------------------------
* AttributedStringUtilities.java
* ------------------------------
* (C)opyright 2005, by Object Refinery Limited and Contributors.
*
* Original Author: David Gilbert (for Object Refinery Limited);
* Contributor(s): -;
*
* $Id: AttributedStringUtilities.java,v 1.2 2005/10/18 13:24:19 mungady Exp $
*
* Changes
* -------
* 29-Jul-2005 : Version 1(DG);
*
*/
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.CharacterIterator;
import java.util.Map;
/**
* Some utility methods for working with <code>AttributedString</code>
* objects.
*
* @author David Gilbert
*/
public class AttributedStringUtilities {
/**
* Tests two attributed strings for equality.
*
* @param s1
* string 1 (<code>null</code> permitted).
* @param s2
* string 2 (<code>null</code> permitted).
*
* @return <code>true</code> if <code>s1</code> and <code>s2</code> are
* equal or both <code>null</code>, and <code>false</code>
* otherwise.
*/
public static boolean equal(AttributedString s1, AttributedString s2) {
if (s1 == null) {
return (s2 == null);
}
if (s2 == null) {
return false;
}
AttributedCharacterIterator it1 = s1.getIterator();
AttributedCharacterIterator it2 = s2.getIterator();
char c1 = it1.first();
char c2 = it2.first();
int start = 0;
while (c1 != CharacterIterator.DONE) {
int limit1 = it1.getRunLimit();
int limit2 = it2.getRunLimit();
if (limit1 != limit2) {
return false;
}
// if maps aren"t equivalent, return false
Map m1 = it1.getAttributes();
Map m2 = it2.getAttributes();
if (!m1.equals(m2)) {
return false;
}
// now check characters in the run are the same
for (int i = start; i < limit1; i++) {
if (c1 != c2) {
return false;
}
c1 = it1.next();
c2 = it2.next();
}
start = limit1;
}
return c2 == CharacterIterator.DONE;
}
}
Text Component Display
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.UIManager;
import javax.swing.text.*;
import javax.swing.plaf.*;
import java.io.*;
public class TextComponentDisplay {
public static void displayModel(JTextComponent comp,
PrintStream out) {
Document doc = comp.getDocument();
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).dump(out);
}
}
public static void displayViews(JTextComponent comp,
PrintStream out) {
TextUI textUI = (TextUI)comp.getUI();
View rootView = textUI.getRootView(comp);
displayView(rootView, 0, out);
}
public static void displayView(View view, int tabs,
PrintStream out) {
// Print info about this view
for (int i = 0; i < tabs; i++) {
out.print("\t");
}
out.println(view.getClass().getName());
for (int i = 0; i < tabs; i++) {
out.print("\t");
}
out.println("Start: " + view.getStartOffset() +
"; end: " + view.getEndOffset());
// Display child views, if any.
int childViews = view.getViewCount();
for (int i = 0; i < childViews ; i++) {
View childView = view.getView(i);
displayView(childView, tabs + 1, out);
}
}
}
TextPane: DocumentEvent
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// LiveParenMatcher.java
//Like ParenMatcher but continuously colors as the user edits the document.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.Segment;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class LiveParenMatcher extends ParenMatcher implements DocumentListener {
public LiveParenMatcher() {
super();
getDocument().addDocumentListener(this);
}
public void changedUpdate(DocumentEvent de) {
// no insertion or deletion, so do nothing
}
public void insertUpdate(DocumentEvent de) {
SwingUtilities.invokeLater(this); // will call run()
}
public void removeUpdate(DocumentEvent de) {
SwingUtilities.invokeLater(this); // will call run()
}
public static void main(String[] args) {
JFrame frame = new JFrame("LiveParenMatcher");
frame.setContentPane(new JScrollPane(new LiveParenMatcher()));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
frame.setVisible(true);
}
// ---- finished example from "The DocumentListener Interface" ----
// ---- begin example from "The DocumentEvent Interface" ----
// (method renamed to insertUpdate_2)
public void insertUpdate_2(DocumentEvent de) {
Document doc = de.getDocument();
int offset = de.getOffset();
int length = de.getLength();
String inserted = "";
try {
inserted = doc.getText(offset, length);
} catch (BadLocationException ble) {
}
for (int j = 0; j < inserted.length(); j += 1) {
char ch = inserted.charAt(j);
if (ch == "(" || ch == "[" || ch == "{" || ch == ")" || ch == "]"
|| ch == "}") {
SwingUtilities.invokeLater(this); // will call run()
return; // no need to check further
}
}
}
// ---- begin example from "The Segment Class" ----
// (method renamed to insertUpdate_3)
public void insertUpdate_3(DocumentEvent de) {
Document doc = de.getDocument();
int offset = de.getOffset();
int length = de.getLength();
Segment seg = new Segment();
try {
doc.getText(offset, length, seg); // text placed in Segment
} catch (BadLocationException ble) {
}
// iterate through the Segment
for (char ch = seg.first(); ch != seg.DONE; ch = seg.next())
if (ch == "(" || ch == "[" || ch == "{" || ch == ")" || ch == "]"
|| ch == "}") {
SwingUtilities.invokeLater(this); // will call run()
return; // no need to check further
}
}
// ---- begin example from "The ElementIterator Class" ----
// (method renamed to removeUpdate_2)
public void removeUpdate_2(DocumentEvent de) {
// print some debugging information before matching the parens
ElementIterator iter = new ElementIterator(de.getDocument());
for (Element elem = iter.first(); elem != null; elem = iter.next()) {
DocumentEvent.ElementChange change = de.getChange(elem);
if (change != null) { // null means there was no change in elem
System.out.println("Element " + elem.getName() + " (depth "
+ iter.depth() + ") changed its children: "
+ change.getChildrenRemoved().length
+ " children removed, "
+ change.getChildrenAdded().length
+ " children added.\n");
}
}
SwingUtilities.invokeLater(this); // will call run()
}
}
class ParenMatcher extends JTextPane implements Runnable {
public static Color[] matchColor = { Color.blue, Color.magenta, Color.green };
public static Color badColor = Color.red;
private AttributeSet[] matchAttrSet;
private AttributeSet badAttrSet;
public ParenMatcher() {
// create an array of AttributeSets from the array of Colors
StyleContext sc = StyleContext.getDefaultStyleContext();
badAttrSet = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, badColor);
matchAttrSet = new AttributeSet[matchColor.length];
for (int j = 0; j < matchColor.length; j += 1)
matchAttrSet[j] = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, matchColor[j]);
}
// match and color the parens/brackets/braces
public void run() {
StyledDocument doc = getStyledDocument();
String text = "";
int len = doc.getLength();
try {
text = doc.getText(0, len);
} catch (BadLocationException ble) {
}
java.util.Stack stack = new java.util.Stack();
for (int j = 0; j < text.length(); j += 1) {
char ch = text.charAt(j);
if (ch == "(" || ch == "[" || ch == "{") {
int depth = stack.size();
stack.push("" + ch + j); // push a String containg the char and
// the offset
AttributeSet aset = matchAttrSet[depth % matchAttrSet.length];
doc.setCharacterAttributes(j, 1, aset, false);
}
if (ch == ")" || ch == "]" || ch == "}") {
String peek = stack.empty() ? "." : (String) stack.peek();
if (matches(peek.charAt(0), ch)) { // does it match?
stack.pop();
int depth = stack.size();
AttributeSet aset = matchAttrSet[depth
% matchAttrSet.length];
doc.setCharacterAttributes(j, 1, aset, false);
} else { // mismatch
doc.setCharacterAttributes(j, 1, badAttrSet, false);
}
}
}
while (!stack.empty()) { // anything left in the stack is a mismatch
String pop = (String) stack.pop();
int offset = Integer.parseInt(pop.substring(1));
doc.setCharacterAttributes(offset, 1, badAttrSet, false);
}
}
// unset the foreground color (if any) whenever the user enters text
// (if not for this, text entered after a paren would catch the paren"s
// color)
public void replaceSelection(String content) {
getInputAttributes().removeAttribute(StyleConstants.Foreground);
super.replaceSelection(content);
}
// return true if "left" and "right" are matching parens/brackets/braces
public static boolean matches(char left, char right) {
if (left == "(")
return (right == ")");
if (left == "[")
return (right == "]");
if (left == "{")
return (right == "}");
return false;
}
public static void main(String[] args) {
JFrame frame = new JFrame("ParenMatcher");
final ParenMatcher matcher = new ParenMatcher();
matcher.setText("int fact(int n) {\n" + " if (n <= 1) return 1;\n"
+ " return(n * fact(n-1));\n" + "}\n");
frame.getContentPane().add(new JScrollPane(matcher),
BorderLayout.CENTER);
JButton matchButton = new JButton("match parens");
matchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
matcher.run();
}
});
frame.getContentPane().add(matchButton, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 150);
frame.setVisible(true);
}
}
TextPane Elements
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.net.URL;
public class TextPaneElements {
public static void createDocumentStyles(StyleContext sc) {
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
// Create and add the main document style
Style mainStyle = sc.addStyle(mainStyleName, defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
Style cwStyle = sc.addStyle(charStyleName, null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
Style heading2Style = sc.addStyle(heading2StyleName, null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
// Create and add the Component style
Class thisClass = TextPaneElements.class;
URL url = thisClass.getResource("jexp.gif");
ImageIcon icon = new ImageIcon(url);
JLabel comp = new JLabel("Displaying text with attributes",
icon, JLabel.CENTER);
comp.setVerticalTextPosition(JLabel.BOTTOM);
comp.setHorizontalTextPosition(JLabel.CENTER);
comp.setFont(new Font("serif", Font.BOLD | Font.ITALIC, 14));
Style componentStyle = sc.addStyle(componentStyleName, null);
StyleConstants.setComponent(componentStyle, comp);
// The paragraph style for the component
Style compParagraphStyle = sc.addStyle(compParaName, null);
StyleConstants.setSpaceAbove(compParagraphStyle, (float)16.0);
}
public static void addText(JTextPane pane, StyleContext sc, Style logicalStyle,
Paragraph[] content) {
// The outer loop adds paragraphs, while the
// inner loop adds character runs.
int paragraphs = content.length;
for (int i = 0; i < paragraphs; i++) {
Run[] runs = content[i].content;
for (int j = 0; j < runs.length; j++) {
pane.setCharacterAttributes(
runs[j].styleName == null ? SimpleAttributeSet.EMPTY :
sc.getStyle(runs[j].styleName), true);
pane.replaceSelection(runs[j].content);
}
// At the end of the paragraph, add the logical style and
// any overriding paragraph style and then terminate the
// paragraph with a newline.
pane.setParagraphAttributes(SimpleAttributeSet.EMPTY, true);
if (logicalStyle != null) {
pane.setLogicalStyle(logicalStyle);
}
if (content[i].styleName != null) {
pane.setParagraphAttributes(sc.getStyle(content[i].styleName), false);
}
pane.replaceSelection("\n");
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Text Pane Elements");
// Create the StyleContext, the document and the pane
final StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Build the styles
createDocumentStyles(sc);
try {
// Add the text and apply the styles
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
// Add the text
addText(pane, sc, sc.getStyle(mainStyleName), content);
// Dump the element structure
((AbstractDocument)pane.getDocument()).dump(System.out);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(500, 300);
f.setVisible(true);
}
// Style names
public static final String mainStyleName = "MainStyle";
public static final String heading2StyleName = "Heading2";
public static final String charStyleName = "ConstantWidth";
public static final String componentStyleName = "Component";
public static final String compParaName = "CompPara";
// Inner classes used to define paragraph structure
public static class Run {
public Run(String styleName, String content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public String content;
}
public static class Paragraph {
public Paragraph(String styleName, Run[] content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public Run[] content;
}
public static final Paragraph[] content = new Paragraph[] {
new Paragraph(heading2StyleName, new Run[] {
new Run(null, "Attributes, Styles and Style Contexts")
}),
new Paragraph(null, new Run[] {
new Run(null, "The simple "),
new Run(charStyleName, "PlainDocument"),
new Run(null, " class that you saw in the previous " +
"chapter is only capable of holding text. " +
"The more complex text components use a more " +
"sophisticated model that implements the "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " interface. "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " is a sub-interface of "),
new Run(charStyleName, "Document"),
new Run(null, " that contains methods for manipulating attributes " +
"that control the way in which the text in the " +
"document is displayed. The Swing text package " +
"contains a concrete implementation of "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " called "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " that is used as the default model for "),
new Run(charStyleName, "JTextPane"),
new Run(null, " and is also the base class from which " +
"more specific models, such as the "),
new Run(charStyleName, "HTMLDocument"),
new Run(null, " class that handles input in HTML format, can be " +
"created. In order to make use of "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " and "),
new Run(charStyleName, "JTextPane"),
new Run(null, " you need to understand how Swing represents " +
"and uses attributes.")
}),
new Paragraph(compParaName, new Run[] {
new Run(componentStyleName, " ")
})
};
}
TextPane Sample
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class TextPaneSample {
private static String message = "In the beginning, there was COBOL, then there was FORTRAN, "
+ "then there was BASIC, ... and now there is Java.\n";
public static void main(String args[]) {
String title = (args.length == 0 ? "TextPane Example" : args[0]);
JFrame frame = new JFrame(title);
Container content = frame.getContentPane();
StyleContext context = new StyleContext();
StyledDocument document = new DefaultStyledDocument(context);
Style style = context.getStyle(StyleContext.DEFAULT_STYLE);
StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
StyleConstants.setFontSize(style, 14);
StyleConstants.setSpaceAbove(style, 4);
StyleConstants.setSpaceBelow(style, 4);
// Insert content
try {
document.insertString(document.getLength(), message, style);
} catch (BadLocationException badLocationException) {
System.err.println("Oops");
}
SimpleAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setBold(attributes, true);
StyleConstants.setItalic(attributes, true);
// Insert content
try {
document.insertString(document.getLength(), "Hello Java",
attributes);
} catch (BadLocationException badLocationException) {
System.err.println("Oops");
}
// Third style for icon/component
Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
Icon icon = new ImageIcon("Computer.gif");
JLabel label = new JLabel(icon);
StyleConstants.setComponent(labelStyle, label);
// Insert content
try {
document.insertString(document.getLength(), "Ignored", labelStyle);
} catch (BadLocationException badLocationException) {
System.err.println("Oops");
}
JTextPane textPane = new JTextPane(document);
textPane.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textPane);
content.add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
TextPane Views 2
/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.awt.Color;
import java.awt.Font;
import java.io.PrintStream;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.View;
public class TextPaneViews {
public static void createDocumentStyles(StyleContext sc) {
Style defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE);
// Create and add the main document style
Style mainStyle = sc.addStyle(mainStyleName, defaultStyle);
StyleConstants.setLeftIndent(mainStyle, 16);
StyleConstants.setRightIndent(mainStyle, 16);
StyleConstants.setFirstLineIndent(mainStyle, 16);
StyleConstants.setFontFamily(mainStyle, "serif");
StyleConstants.setFontSize(mainStyle, 12);
// Create and add the constant width style
Style cwStyle = sc.addStyle(charStyleName, null);
StyleConstants.setFontFamily(cwStyle, "monospaced");
StyleConstants.setForeground(cwStyle, Color.green);
// Create and add the heading style
Style heading2Style = sc.addStyle(heading2StyleName, null);
StyleConstants.setForeground(heading2Style, Color.red);
StyleConstants.setFontSize(heading2Style, 16);
StyleConstants.setFontFamily(heading2Style, "serif");
StyleConstants.setBold(heading2Style, true);
StyleConstants.setLeftIndent(heading2Style, 8);
StyleConstants.setFirstLineIndent(heading2Style, 0);
// Create and add the Component style
Class thisClass = TextPaneViews.class;
URL url = thisClass.getResource("jexp.gif");
ImageIcon icon = new ImageIcon(url);
JLabel comp = new JLabel("Displaying text with attributes", icon,
JLabel.CENTER);
comp.setVerticalTextPosition(JLabel.BOTTOM);
comp.setHorizontalTextPosition(JLabel.CENTER);
comp.setFont(new Font("serif", Font.BOLD | Font.ITALIC, 14));
Style componentStyle = sc.addStyle(componentStyleName, null);
StyleConstants.setComponent(componentStyle, comp);
// The paragraph style for the component
Style compParagraphStyle = sc.addStyle(compParaName, null);
StyleConstants.setSpaceAbove(compParagraphStyle, (float) 16.0);
}
public static void addText(JTextPane pane, StyleContext sc,
Style logicalStyle, Paragraph[] content) {
// The outer loop adds paragraphs, while the
// inner loop adds character runs.
int paragraphs = content.length;
for (int i = 0; i < paragraphs; i++) {
Run[] runs = content[i].content;
for (int j = 0; j < runs.length; j++) {
pane.setCharacterAttributes(
runs[j].styleName == null ? SimpleAttributeSet.EMPTY
: sc.getStyle(runs[j].styleName), true);
pane.replaceSelection(runs[j].content);
}
// At the end of the paragraph, add the logical style and
// any overriding paragraph style and then terminate the
// paragraph with a newline.
pane.setParagraphAttributes(SimpleAttributeSet.EMPTY, true);
if (logicalStyle != null) {
pane.setLogicalStyle(logicalStyle);
}
if (content[i].styleName != null) {
pane.setParagraphAttributes(sc.getStyle(content[i].styleName),
false);
}
pane.replaceSelection("\n");
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new JFrame("Text Pane Views");
// Create the StyleContext, the document and the pane
final StyleContext sc = new StyleContext();
final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
// Build the styles
createDocumentStyles(sc);
try {
// Add the text and apply the styles
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
// Add the text
addText(pane, sc, sc.getStyle(mainStyleName), content);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
System.exit(1);
}
f.getContentPane().add(new JScrollPane(pane));
f.setSize(500, 300);
f.setVisible(true);
try {
// Dump the view structure
Thread.sleep(30000);
ViewDisplayer.displayViews(pane, System.out);
} catch (InterruptedException e) {
}
System.out.flush();
System.exit(0);
}
// Style names
public static final String mainStyleName = "MainStyle";
public static final String heading2StyleName = "Heading2";
public static final String charStyleName = "ConstantWidth";
public static final String componentStyleName = "Component";
public static final String compParaName = "CompPara";
// Inner classes used to define paragraph structure
public static class Run {
public Run(String styleName, String content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public String content;
}
public static class Paragraph {
public Paragraph(String styleName, Run[] content) {
this.styleName = styleName;
this.content = content;
}
public String styleName;
public Run[] content;
}
public static final Paragraph[] content = new Paragraph[] {
new Paragraph(heading2StyleName, new Run[] { new Run(null,
"Attributes, Styles and Style Contexts") }),
new Paragraph(
null,
new Run[] {
new Run(null, "The simple "),
new Run(charStyleName, "PlainDocument"),
new Run(
null,
" class that you saw in the previous "
+ "chapter is only capable of holding text. "
+ "The more complex text components use a more "
+ "sophisticated model that implements the "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " interface. "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " is a sub-interface of "),
new Run(charStyleName, "Document"),
new Run(
null,
" that contains methods for manipulating attributes "
+ "that control the way in which the text in the "
+ "document is displayed. The Swing text package "
+ "contains a concrete implementation of "),
new Run(charStyleName, "StyledDocument"),
new Run(null, " called "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null,
" that is used as the default model for "),
new Run(charStyleName, "JTextPane"),
new Run(
null,
" and is also the base class from which "
+ "more specific models, such as the "),
new Run(charStyleName, "HTMLDocument"),
new Run(
null,
" class that handles input in HTML format, can be "
+ "created. In order to make use of "),
new Run(charStyleName, "DefaultStyledDocument"),
new Run(null, " and "),
new Run(charStyleName, "JTextPane"),
new Run(null,
" you need to understand how Swing represents "
+ "and uses attributes.") }),
new Paragraph(compParaName, new Run[] { new Run(componentStyleName,
" ") }) };
}
class ViewDisplayer {
public static void displayViews(JTextComponent comp, PrintStream out) {
View rootView = comp.getUI().getRootView(comp);
displayView(rootView, 0, comp.getDocument(), out);
}
public static void displayView(View view, int indent, Document doc,
PrintStream out) {
String name = view.getClass().getName();
for (int i = 0; i < indent; i++) {
out.print("\t");
}
int start = view.getStartOffset();
int end = view.getEndOffset();
out.println(name + "; offsets [" + start + ", " + end + "]");
int viewCount = view.getViewCount();
if (viewCount == 0) {
int length = Math.min(32, end - start);
try {
String txt = doc.getText(start, length);
for (int i = 0; i < indent + 1; i++) {
out.print("\t");
}
out.println("[" + txt + "]");
} catch (BadLocationException e) {
}
} else {
for (int i = 0; i < viewCount; i++) {
displayView(view.getView(i), indent + 1, doc, out);
}
}
}
}