History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/text/StyledEditorKit.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/text/StyledEditorKit.java+895−0
@@ -0,0 +1,895 @@
1+/*
2+ * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package javax.swing.text;
26+
27+import java.io.*;
28+import java.awt.*;
29+import java.awt.event.ActionEvent;
30+import java.beans.PropertyChangeEvent;
31+import java.beans.PropertyChangeListener;
32+import javax.swing.event.*;
33+import javax.swing.Action;
34+import javax.swing.JEditorPane;
35+import javax.swing.KeyStroke;
36+import javax.swing.UIManager;
37+
38+/**
39+ * This is the set of things needed by a text component
40+ * to be a reasonably functioning editor for some <em>type</em>
41+ * of text document. This implementation provides a default
42+ * implementation which treats text as styled text and
43+ * provides a minimal set of actions for editing styled text.
44+ *
45+ * @author Timothy Prinzing
46+ */
47+public class StyledEditorKit extends DefaultEditorKit {
48+
49+ /**
50+ * Creates a new EditorKit used for styled documents.
51+ */
52+ public StyledEditorKit() {
53+ createInputAttributeUpdated();
54+ createInputAttributes();
55+ }
56+
57+ /**
58+ * Gets the input attributes for the pane. When
59+ * the caret moves and there is no selection, the
60+ * input attributes are automatically mutated to
61+ * reflect the character attributes of the current
62+ * caret location. The styled editing actions
63+ * use the input attributes to carry out their
64+ * actions.
65+ *
66+ * @return the attribute set
67+ */
68+ public MutableAttributeSet getInputAttributes() {
69+ return inputAttributes;
70+ }
71+
72+ /**
73+ * Fetches the element representing the current
74+ * run of character attributes for the caret.
75+ *
76+ * @return the element
77+ */
78+ public Element getCharacterAttributeRun() {
79+ return currentRun;
80+ }
81+
82+ // --- EditorKit methods ---------------------------
83+
84+ /**
85+ * Fetches the command list for the editor. This is
86+ * the list of commands supported by the superclass
87+ * augmented by the collection of commands defined
88+ * locally for style operations.
89+ *
90+ * @return the command list
91+ */
92+ public Action[] getActions() {
93+ return TextAction.augmentList(super.getActions(), this.defaultActions);
94+ }
95+
96+ /**
97+ * Creates an uninitialized text storage model
98+ * that is appropriate for this type of editor.
99+ *
100+ * @return the model
101+ */
102+ public Document createDefaultDocument() {
103+ return new DefaultStyledDocument();
104+ }
105+
106+ /**
107+ * Called when the kit is being installed into
108+ * a JEditorPane.
109+ *
110+ * @param c the JEditorPane
111+ */
112+ public void install(JEditorPane c) {
113+ c.addCaretListener(inputAttributeUpdater);
114+ c.addPropertyChangeListener(inputAttributeUpdater);
115+ Caret caret = c.getCaret();
116+ if (caret != null) {
117+ inputAttributeUpdater.updateInputAttributes
118+ (caret.getDot(), caret.getMark(), c);
119+ }
120+ }
121+
122+ /**
123+ * Called when the kit is being removed from the
124+ * JEditorPane. This is used to unregister any
125+ * listeners that were attached.
126+ *
127+ * @param c the JEditorPane
128+ */
129+ public void deinstall(JEditorPane c) {
130+ c.removeCaretListener(inputAttributeUpdater);
131+ c.removePropertyChangeListener(inputAttributeUpdater);
132+
133+ // remove references to current document so it can be collected.
134+ currentRun = null;
135+ currentParagraph = null;
136+ }
137+
138+ /**
139+ * Fetches a factory that is suitable for producing
140+ * views of any models that are produced by this
141+ * kit. This is implemented to return View implementations
142+ * for the following kinds of elements:
143+ * <ul>
144+ * <li>AbstractDocument.ContentElementName
145+ * <li>AbstractDocument.ParagraphElementName
146+ * <li>AbstractDocument.SectionElementName
147+ * <li>StyleConstants.ComponentElementName
148+ * <li>StyleConstants.IconElementName
149+ * </ul>
150+ *
151+ * @return the factory
152+ */
153+ public ViewFactory getViewFactory() {
154+ return defaultFactory;
155+ }
156+
157+ /**
158+ * Creates a copy of the editor kit.
159+ *
160+ * @return the copy
161+ */
162+ public Object clone() {
163+ StyledEditorKit o = (StyledEditorKit)super.clone();
164+ o.currentRun = o.currentParagraph = null;
165+ o.createInputAttributeUpdated();
166+ o.createInputAttributes();
167+ return o;
168+ }
169+
170+ /**
171+ * Creates the AttributeSet used for the selection.
172+ */
173+ private void createInputAttributes() {
174+ inputAttributes = new SimpleAttributeSet() {
175+ public AttributeSet getResolveParent() {
176+ return (currentParagraph != null) ?
177+ currentParagraph.getAttributes() : null;
178+ }
179+
180+ public Object clone() {
181+ return new SimpleAttributeSet(this);
182+ }
183+ };
184+ }
185+
186+ /**
187+ * Creates a new <code>AttributeTracker</code>.
188+ */
189+ private void createInputAttributeUpdated() {
190+ inputAttributeUpdater = new AttributeTracker();
191+ }
192+
193+
194+ private static final ViewFactory defaultFactory = new StyledViewFactory();
195+
196+ Element currentRun;
197+ Element currentParagraph;
198+
199+ /**
200+ * This is the set of attributes used to store the
201+ * input attributes.
202+ */
203+ MutableAttributeSet inputAttributes;
204+
205+ /**
206+ * This listener will be attached to the caret of
207+ * the text component that the EditorKit gets installed
208+ * into. This should keep the input attributes updated
209+ * for use by the styled actions.
210+ */
211+ private AttributeTracker inputAttributeUpdater;
212+
213+ /**
214+ * Tracks caret movement and keeps the input attributes set
215+ * to reflect the current set of attribute definitions at the
216+ * caret position.
217+ * <p>This implements PropertyChangeListener to update the
218+ * input attributes when the Document changes, as if the Document
219+ * changes the attributes will almost certainly change.
220+ */
221+ class AttributeTracker implements CaretListener, PropertyChangeListener, Serializable {
222+
223+ /**
224+ * Updates the attributes. <code>dot</code> and <code>mark</code>
225+ * mark give the positions of the selection in <code>c</code>.
226+ */
227+ void updateInputAttributes(int dot, int mark, JTextComponent c) {
228+ // EditorKit might not have installed the StyledDocument yet.
229+ Document aDoc = c.getDocument();
230+ if (!(aDoc instanceof StyledDocument)) {
231+ return ;
232+ }
233+ int start = Math.min(dot, mark);
234+ // record current character attributes.
235+ StyledDocument doc = (StyledDocument)aDoc;
236+ // If nothing is selected, get the attributes from the character
237+ // before the start of the selection, otherwise get the attributes
238+ // from the character element at the start of the selection.
239+ Element run;
240+ currentParagraph = doc.getParagraphElement(start);
241+ if (currentParagraph.getStartOffset() == start || dot != mark) {
242+ // Get the attributes from the character at the selection
243+ // if in a different paragrah!
244+ run = doc.getCharacterElement(start);
245+ }
246+ else {
247+ run = doc.getCharacterElement(Math.max(start-1, 0));
248+ }
249+ if (run != currentRun) {
250+ /*
251+ * PENDING(prinz) All attributes that represent a single
252+ * glyph position and can't be inserted into should be
253+ * removed from the input attributes... this requires
254+ * mixing in an interface to indicate that condition.
255+ * When we can add things again this logic needs to be
256+ * improved!!
257+ */
258+ currentRun = run;
259+ createInputAttributes(currentRun, getInputAttributes());
260+ }
261+ }
262+
263+ public void propertyChange(PropertyChangeEvent evt) {
264+ Object newValue = evt.getNewValue();
265+ Object source = evt.getSource();
266+
267+ if ((source instanceof JTextComponent) &&
268+ (newValue instanceof Document)) {
269+ // New document will have changed selection to 0,0.
270+ updateInputAttributes(0, 0, (JTextComponent)source);
271+ }
272+ }
273+
274+ public void caretUpdate(CaretEvent e) {
275+ updateInputAttributes(e.getDot(), e.getMark(),
276+ (JTextComponent)e.getSource());
277+ }
278+ }
279+
280+ /**
281+ * Copies the key/values in <code>element</code>s AttributeSet into
282+ * <code>set</code>. This does not copy component, icon, or element
283+ * names attributes. Subclasses may wish to refine what is and what
284+ * isn't copied here. But be sure to first remove all the attributes that
285+ * are in <code>set</code>.<p>
286+ * This is called anytime the caret moves over a different location.
287+ *
288+ */
289+ protected void createInputAttributes(Element element,
290+ MutableAttributeSet set) {
291+ if (element.getAttributes().getAttributeCount() > 0
292+ || element.getEndOffset() - element.getStartOffset() > 1
293+ || element.getEndOffset() < element.getDocument().getLength()) {
294+ set.removeAttributes(set);
295+ set.addAttributes(element.getAttributes());
296+ set.removeAttribute(StyleConstants.ComponentAttribute);
297+ set.removeAttribute(StyleConstants.IconAttribute);
298+ set.removeAttribute(AbstractDocument.ElementNameAttribute);
299+ set.removeAttribute(StyleConstants.ComposedTextAttribute);
300+ }
301+ }
302+
303+ // ---- default ViewFactory implementation ---------------------
304+
305+ static class StyledViewFactory implements ViewFactory {
306+
307+ public View create(Element elem) {
308+ String kind = elem.getName();
309+ if (kind != null) {
310+ if (kind.equals(AbstractDocument.ContentElementName)) {
311+ return new LabelView(elem);
312+ } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
313+ return new ParagraphView(elem);
314+ } else if (kind.equals(AbstractDocument.SectionElementName)) {
315+ return new BoxView(elem, View.Y_AXIS);
316+ } else if (kind.equals(StyleConstants.ComponentElementName)) {
317+ return new ComponentView(elem);
318+ } else if (kind.equals(StyleConstants.IconElementName)) {
319+ return new IconView(elem);
320+ }
321+ }
322+
323+ // default to text display
324+ return new LabelView(elem);
325+ }
326+
327+ }
328+
329+ // --- Action implementations ---------------------------------
330+
331+ private static final Action[] defaultActions = {
332+ new FontFamilyAction("font-family-SansSerif", "SansSerif"),
333+ new FontFamilyAction("font-family-Monospaced", "Monospaced"),
334+ new FontFamilyAction("font-family-Serif", "Serif"),
335+ new FontSizeAction("font-size-8", 8),
336+ new FontSizeAction("font-size-10", 10),
337+ new FontSizeAction("font-size-12", 12),
338+ new FontSizeAction("font-size-14", 14),
339+ new FontSizeAction("font-size-16", 16),
340+ new FontSizeAction("font-size-18", 18),
341+ new FontSizeAction("font-size-24", 24),
342+ new FontSizeAction("font-size-36", 36),
343+ new FontSizeAction("font-size-48", 48),
344+ new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT),
345+ new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER),
346+ new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT),
347+ new BoldAction(),
348+ new ItalicAction(),
349+ new StyledInsertBreakAction(),
350+ new UnderlineAction()
351+ };
352+
353+ /**
354+ * An action that assumes it's being fired on a JEditorPane
355+ * with a StyledEditorKit (or subclass) installed. This has
356+ * some convenience methods for causing character or paragraph
357+ * level attribute changes. The convenience methods will
358+ * throw an IllegalArgumentException if the assumption of
359+ * a StyledDocument, a JEditorPane, or a StyledEditorKit
360+ * fail to be true.
361+ * <p>
362+ * The component that gets acted upon by the action
363+ * will be the source of the ActionEvent if the source
364+ * can be narrowed to a JEditorPane type. If the source
365+ * can't be narrowed, the most recently focused text
366+ * component is changed. If neither of these are the
367+ * case, the action cannot be performed.
368+ * <p>
369+ * <strong>Warning:</strong>
370+ * Serialized objects of this class will not be compatible with
371+ * future Swing releases. The current serialization support is
372+ * appropriate for short term storage or RMI between applications running
373+ * the same version of Swing. As of 1.4, support for long term storage
374+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
375+ * has been added to the <code>java.beans</code> package.
376+ * Please see {@link java.beans.XMLEncoder}.
377+ */
378+ public abstract static class StyledTextAction extends TextAction {
379+
380+ /**
381+ * Creates a new StyledTextAction from a string action name.
382+ *
383+ * @param nm the name of the action
384+ */
385+ public StyledTextAction(String nm) {
386+ super(nm);
387+ }
388+
389+ /**
390+ * Gets the target editor for an action.
391+ *
392+ * @param e the action event
393+ * @return the editor
394+ */
395+ protected final JEditorPane getEditor(ActionEvent e) {
396+ JTextComponent tcomp = getTextComponent(e);
397+ if (tcomp instanceof JEditorPane) {
398+ return (JEditorPane) tcomp;
399+ }
400+ return null;
401+ }
402+
403+ /**
404+ * Gets the document associated with an editor pane.
405+ *
406+ * @param e the editor
407+ * @return the document
408+ * @exception IllegalArgumentException for the wrong document type
409+ */
410+ protected final StyledDocument getStyledDocument(JEditorPane e) {
411+ Document d = e.getDocument();
412+ if (d instanceof StyledDocument) {
413+ return (StyledDocument) d;
414+ }
415+ throw new IllegalArgumentException("document must be StyledDocument");
416+ }
417+
418+ /**
419+ * Gets the editor kit associated with an editor pane.
420+ *
421+ * @param e the editor pane
422+ * @return the kit
423+ * @exception IllegalArgumentException for the wrong document type
424+ */
425+ protected final StyledEditorKit getStyledEditorKit(JEditorPane e) {
426+ EditorKit k = e.getEditorKit();
427+ if (k instanceof StyledEditorKit) {
428+ return (StyledEditorKit) k;
429+ }
430+ throw new IllegalArgumentException("EditorKit must be StyledEditorKit");
431+ }
432+
433+ /**
434+ * Applies the given attributes to character
435+ * content. If there is a selection, the attributes
436+ * are applied to the selection range. If there
437+ * is no selection, the attributes are applied to
438+ * the input attribute set which defines the attributes
439+ * for any new text that gets inserted.
440+ *
441+ * @param editor the editor
442+ * @param attr the attributes
443+ * @param replace if true, then replace the existing attributes first
444+ */
445+ protected final void setCharacterAttributes(JEditorPane editor,
446+ AttributeSet attr, boolean replace) {
447+ int p0 = editor.getSelectionStart();
448+ int p1 = editor.getSelectionEnd();
449+ if (p0 != p1) {
450+ StyledDocument doc = getStyledDocument(editor);
451+ doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
452+ }
453+ StyledEditorKit k = getStyledEditorKit(editor);
454+ MutableAttributeSet inputAttributes = k.getInputAttributes();
455+ if (replace) {
456+ inputAttributes.removeAttributes(inputAttributes);
457+ }
458+ inputAttributes.addAttributes(attr);
459+ }
460+
461+ /**
462+ * Applies the given attributes to paragraphs. If
463+ * there is a selection, the attributes are applied
464+ * to the paragraphs that intersect the selection.
465+ * if there is no selection, the attributes are applied
466+ * to the paragraph at the current caret position.
467+ *
468+ * @param editor the editor
469+ * @param attr the attributes
470+ * @param replace if true, replace the existing attributes first
471+ */
472+ protected final void setParagraphAttributes(JEditorPane editor,
473+ AttributeSet attr, boolean replace) {
474+ int p0 = editor.getSelectionStart();
475+ int p1 = editor.getSelectionEnd();
476+ StyledDocument doc = getStyledDocument(editor);
477+ doc.setParagraphAttributes(p0, p1 - p0, attr, replace);
478+ }
479+
480+ }
481+
482+ /**
483+ * An action to set the font family in the associated
484+ * JEditorPane. This will use the family specified as
485+ * the command string on the ActionEvent if there is one,
486+ * otherwise the family that was initialized with will be used.
487+ * <p>
488+ * <strong>Warning:</strong>
489+ * Serialized objects of this class will not be compatible with
490+ * future Swing releases. The current serialization support is
491+ * appropriate for short term storage or RMI between applications running
492+ * the same version of Swing. As of 1.4, support for long term storage
493+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
494+ * has been added to the <code>java.beans</code> package.
495+ * Please see {@link java.beans.XMLEncoder}.
496+ */
497+ public static class FontFamilyAction extends StyledTextAction {
498+
499+ /**
500+ * Creates a new FontFamilyAction.
501+ *
502+ * @param nm the action name
503+ * @param family the font family
504+ */
505+ public FontFamilyAction(String nm, String family) {
506+ super(nm);
507+ this.family = family;
508+ }
509+
510+ /**
511+ * Sets the font family.
512+ *
513+ * @param e the event
514+ */
515+ public void actionPerformed(ActionEvent e) {
516+ JEditorPane editor = getEditor(e);
517+ if (editor != null) {
518+ String family = this.family;
519+ if ((e != null) && (e.getSource() == editor)) {
520+ String s = e.getActionCommand();
521+ if (s != null) {
522+ family = s;
523+ }
524+ }
525+ if (family != null) {
526+ MutableAttributeSet attr = new SimpleAttributeSet();
527+ StyleConstants.setFontFamily(attr, family);
528+ setCharacterAttributes(editor, attr, false);
529+ } else {
530+ UIManager.getLookAndFeel().provideErrorFeedback(editor);
531+ }
532+ }
533+ }
534+
535+ private String family;
536+ }
537+
538+ /**
539+ * An action to set the font size in the associated
540+ * JEditorPane. This will use the size specified as
541+ * the command string on the ActionEvent if there is one,
542+ * otherwise the size that was initialized with will be used.
543+ * <p>
544+ * <strong>Warning:</strong>
545+ * Serialized objects of this class will not be compatible with
546+ * future Swing releases. The current serialization support is
547+ * appropriate for short term storage or RMI between applications running
548+ * the same version of Swing. As of 1.4, support for long term storage
549+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
550+ * has been added to the <code>java.beans</code> package.
551+ * Please see {@link java.beans.XMLEncoder}.
552+ */
553+ public static class FontSizeAction extends StyledTextAction {
554+
555+ /**
556+ * Creates a new FontSizeAction.
557+ *
558+ * @param nm the action name
559+ * @param size the font size
560+ */
561+ public FontSizeAction(String nm, int size) {
562+ super(nm);
563+ this.size = size;
564+ }
565+
566+ /**
567+ * Sets the font size.
568+ *
569+ * @param e the action event
570+ */
571+ public void actionPerformed(ActionEvent e) {
572+ JEditorPane editor = getEditor(e);
573+ if (editor != null) {
574+ int size = this.size;
575+ if ((e != null) && (e.getSource() == editor)) {
576+ String s = e.getActionCommand();
577+ try {
578+ size = Integer.parseInt(s, 10);
579+ } catch (NumberFormatException nfe) {
580+ }
581+ }
582+ if (size != 0) {
583+ MutableAttributeSet attr = new SimpleAttributeSet();
584+ StyleConstants.setFontSize(attr, size);
585+ setCharacterAttributes(editor, attr, false);
586+ } else {
587+ UIManager.getLookAndFeel().provideErrorFeedback(editor);
588+ }
589+ }
590+ }
591+
592+ private int size;
593+ }
594+
595+ /**
596+ * An action to set foreground color. This sets the
597+ * <code>StyleConstants.Foreground</code> attribute for the
598+ * currently selected range of the target JEditorPane.
599+ * This is done by calling
600+ * <code>StyledDocument.setCharacterAttributes</code>
601+ * on the styled document associated with the target
602+ * JEditorPane.
603+ * <p>
604+ * If the target text component is specified as the
605+ * source of the ActionEvent and there is a command string,
606+ * the command string will be interpreted as the foreground
607+ * color. It will be interpreted by called
608+ * <code>Color.decode</code>, and should therefore be
609+ * legal input for that method.
610+ * <p>
611+ * <strong>Warning:</strong>
612+ * Serialized objects of this class will not be compatible with
613+ * future Swing releases. The current serialization support is
614+ * appropriate for short term storage or RMI between applications running
615+ * the same version of Swing. As of 1.4, support for long term storage
616+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
617+ * has been added to the <code>java.beans</code> package.
618+ * Please see {@link java.beans.XMLEncoder}.
619+ */
620+ public static class ForegroundAction extends StyledTextAction {
621+
622+ /**
623+ * Creates a new ForegroundAction.
624+ *
625+ * @param nm the action name
626+ * @param fg the foreground color
627+ */
628+ public ForegroundAction(String nm, Color fg) {
629+ super(nm);
630+ this.fg = fg;
631+ }
632+
633+ /**
634+ * Sets the foreground color.
635+ *
636+ * @param e the action event
637+ */
638+ public void actionPerformed(ActionEvent e) {
639+ JEditorPane editor = getEditor(e);
640+ if (editor != null) {
641+ Color fg = this.fg;
642+ if ((e != null) && (e.getSource() == editor)) {
643+ String s = e.getActionCommand();
644+ try {
645+ fg = Color.decode(s);
646+ } catch (NumberFormatException nfe) {
647+ }
648+ }
649+ if (fg != null) {
650+ MutableAttributeSet attr = new SimpleAttributeSet();
651+ StyleConstants.setForeground(attr, fg);
652+ setCharacterAttributes(editor, attr, false);
653+ } else {
654+ UIManager.getLookAndFeel().provideErrorFeedback(editor);
655+ }
656+ }
657+ }
658+
659+ private Color fg;
660+ }
661+
662+ /**
663+ * An action to set paragraph alignment. This sets the
664+ * <code>StyleConstants.Alignment</code> attribute for the
665+ * currently selected range of the target JEditorPane.
666+ * This is done by calling
667+ * <code>StyledDocument.setParagraphAttributes</code>
668+ * on the styled document associated with the target
669+ * JEditorPane.
670+ * <p>
671+ * If the target text component is specified as the
672+ * source of the ActionEvent and there is a command string,
673+ * the command string will be interpreted as an integer
674+ * that should be one of the legal values for the
675+ * <code>StyleConstants.Alignment</code> attribute.
676+ * <p>
677+ * <strong>Warning:</strong>
678+ * Serialized objects of this class will not be compatible with
679+ * future Swing releases. The current serialization support is
680+ * appropriate for short term storage or RMI between applications running
681+ * the same version of Swing. As of 1.4, support for long term storage
682+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
683+ * has been added to the <code>java.beans</code> package.
684+ * Please see {@link java.beans.XMLEncoder}.
685+ */
686+ public static class AlignmentAction extends StyledTextAction {
687+
688+ /**
689+ * Creates a new AlignmentAction.
690+ *
691+ * @param nm the action name
692+ * @param a the alignment >= 0
693+ */
694+ public AlignmentAction(String nm, int a) {
695+ super(nm);
696+ this.a = a;
697+ }
698+
699+ /**
700+ * Sets the alignment.
701+ *
702+ * @param e the action event
703+ */
704+ public void actionPerformed(ActionEvent e) {
705+ JEditorPane editor = getEditor(e);
706+ if (editor != null) {
707+ int a = this.a;
708+ if ((e != null) && (e.getSource() == editor)) {
709+ String s = e.getActionCommand();
710+ try {
711+ a = Integer.parseInt(s, 10);
712+ } catch (NumberFormatException nfe) {
713+ }
714+ }
715+ MutableAttributeSet attr = new SimpleAttributeSet();
716+ StyleConstants.setAlignment(attr, a);
717+ setParagraphAttributes(editor, attr, false);
718+ }
719+ }
720+
721+ private int a;
722+ }
723+
724+ /**
725+ * An action to toggle the bold attribute.
726+ * <p>
727+ * <strong>Warning:</strong>
728+ * Serialized objects of this class will not be compatible with
729+ * future Swing releases. The current serialization support is
730+ * appropriate for short term storage or RMI between applications running
731+ * the same version of Swing. As of 1.4, support for long term storage
732+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
733+ * has been added to the <code>java.beans</code> package.
734+ * Please see {@link java.beans.XMLEncoder}.
735+ */
736+ public static class BoldAction extends StyledTextAction {
737+
738+ /**
739+ * Constructs a new BoldAction.
740+ */
741+ public BoldAction() {
742+ super("font-bold");
743+ }
744+
745+ /**
746+ * Toggles the bold attribute.
747+ *
748+ * @param e the action event
749+ */
750+ public void actionPerformed(ActionEvent e) {
751+ JEditorPane editor = getEditor(e);
752+ if (editor != null) {
753+ StyledEditorKit kit = getStyledEditorKit(editor);
754+ MutableAttributeSet attr = kit.getInputAttributes();
755+ boolean bold = (StyleConstants.isBold(attr)) ? false : true;
756+ SimpleAttributeSet sas = new SimpleAttributeSet();
757+ StyleConstants.setBold(sas, bold);
758+ setCharacterAttributes(editor, sas, false);
759+ }
760+ }
761+ }
762+
763+ /**
764+ * An action to toggle the italic attribute.
765+ * <p>
766+ * <strong>Warning:</strong>
767+ * Serialized objects of this class will not be compatible with
768+ * future Swing releases. The current serialization support is
769+ * appropriate for short term storage or RMI between applications running
770+ * the same version of Swing. As of 1.4, support for long term storage
771+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
772+ * has been added to the <code>java.beans</code> package.
773+ * Please see {@link java.beans.XMLEncoder}.
774+ */
775+ public static class ItalicAction extends StyledTextAction {
776+
777+ /**
778+ * Constructs a new ItalicAction.
779+ */
780+ public ItalicAction() {
781+ super("font-italic");
782+ }
783+
784+ /**
785+ * Toggles the italic attribute.
786+ *
787+ * @param e the action event
788+ */
789+ public void actionPerformed(ActionEvent e) {
790+ JEditorPane editor = getEditor(e);
791+ if (editor != null) {
792+ StyledEditorKit kit = getStyledEditorKit(editor);
793+ MutableAttributeSet attr = kit.getInputAttributes();
794+ boolean italic = (StyleConstants.isItalic(attr)) ? false : true;
795+ SimpleAttributeSet sas = new SimpleAttributeSet();
796+ StyleConstants.setItalic(sas, italic);
797+ setCharacterAttributes(editor, sas, false);
798+ }
799+ }
800+ }
801+
802+ /**
803+ * An action to toggle the underline attribute.
804+ * <p>
805+ * <strong>Warning:</strong>
806+ * Serialized objects of this class will not be compatible with
807+ * future Swing releases. The current serialization support is
808+ * appropriate for short term storage or RMI between applications running
809+ * the same version of Swing. As of 1.4, support for long term storage
810+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
811+ * has been added to the <code>java.beans</code> package.
812+ * Please see {@link java.beans.XMLEncoder}.
813+ */
814+ public static class UnderlineAction extends StyledTextAction {
815+
816+ /**
817+ * Constructs a new UnderlineAction.
818+ */
819+ public UnderlineAction() {
820+ super("font-underline");
821+ }
822+
823+ /**
824+ * Toggles the Underline attribute.
825+ *
826+ * @param e the action event
827+ */
828+ public void actionPerformed(ActionEvent e) {
829+ JEditorPane editor = getEditor(e);
830+ if (editor != null) {
831+ StyledEditorKit kit = getStyledEditorKit(editor);
832+ MutableAttributeSet attr = kit.getInputAttributes();
833+ boolean underline = (StyleConstants.isUnderline(attr)) ? false : true;
834+ SimpleAttributeSet sas = new SimpleAttributeSet();
835+ StyleConstants.setUnderline(sas, underline);
836+ setCharacterAttributes(editor, sas, false);
837+ }
838+ }
839+ }
840+
841+
842+ /**
843+ * StyledInsertBreakAction has similar behavior to that of
844+ * <code>DefaultEditorKit.InsertBreakAction</code>. That is when
845+ * its <code>actionPerformed</code> method is invoked, a newline
846+ * is inserted. Beyond that, this will reset the input attributes to
847+ * what they were before the newline was inserted.
848+ */
849+ static class StyledInsertBreakAction extends StyledTextAction {
850+ private SimpleAttributeSet tempSet;
851+
852+ StyledInsertBreakAction() {
853+ super(insertBreakAction);
854+ }
855+
856+ public void actionPerformed(ActionEvent e) {
857+ JEditorPane target = getEditor(e);
858+
859+ if (target != null) {
860+ if ((!target.isEditable()) || (!target.isEnabled())) {
861+ UIManager.getLookAndFeel().provideErrorFeedback(target);
862+ return;
863+ }
864+ StyledEditorKit sek = getStyledEditorKit(target);
865+
866+ if (tempSet != null) {
867+ tempSet.removeAttributes(tempSet);
868+ }
869+ else {
870+ tempSet = new SimpleAttributeSet();
871+ }
872+ tempSet.addAttributes(sek.getInputAttributes());
873+ target.replaceSelection("\n");
874+
875+ MutableAttributeSet ia = sek.getInputAttributes();
876+
877+ ia.removeAttributes(ia);
878+ ia.addAttributes(tempSet);
879+ tempSet.removeAttributes(tempSet);
880+ }
881+ else {
882+ // See if we are in a JTextComponent.
883+ JTextComponent text = getTextComponent(e);
884+
885+ if (text != null) {
886+ if ((!text.isEditable()) || (!text.isEnabled())) {
887+ UIManager.getLookAndFeel().provideErrorFeedback(target);
888+ return;
889+ }
890+ text.replaceSelection("\n");
891+ }
892+ }
893+ }
894+ }
895+}