1 7 package javax.swing.text; 8 9 import java.io.*; 10 import java.awt.*; 11 import java.awt.event.ActionEvent ; 12 import java.beans.PropertyChangeEvent ; 13 import java.beans.PropertyChangeListener ; 14 import javax.swing.event.*; 15 import javax.swing.Action ; 16 import javax.swing.JEditorPane ; 17 import javax.swing.KeyStroke ; 18 import javax.swing.UIManager ; 19 20 30 public class StyledEditorKit extends DefaultEditorKit { 31 32 35 public StyledEditorKit() { 36 createInputAttributeUpdated(); 37 createInputAttributes(); 38 } 39 40 51 public MutableAttributeSet getInputAttributes() { 52 return inputAttributes; 53 } 54 55 61 public Element getCharacterAttributeRun() { 62 return currentRun; 63 } 64 65 67 75 public Action [] getActions() { 76 return TextAction.augmentList(super.getActions(), this.defaultActions); 77 } 78 79 85 public Document createDefaultDocument() { 86 return new DefaultStyledDocument (); 87 } 88 89 95 public void install(JEditorPane c) { 96 c.addCaretListener(inputAttributeUpdater); 97 c.addPropertyChangeListener(inputAttributeUpdater); 98 Caret caret = c.getCaret(); 99 if (caret != null) { 100 inputAttributeUpdater.updateInputAttributes 101 (caret.getDot(), caret.getMark(), c); 102 } 103 } 104 105 112 public void deinstall(JEditorPane c) { 113 c.removeCaretListener(inputAttributeUpdater); 114 c.removePropertyChangeListener(inputAttributeUpdater); 115 116 currentRun = null; 118 currentParagraph = null; 119 } 120 121 136 public ViewFactory getViewFactory() { 137 return defaultFactory; 138 } 139 140 145 public Object clone() { 146 StyledEditorKit o = (StyledEditorKit )super.clone(); 147 o.currentRun = o.currentParagraph = null; 148 o.createInputAttributeUpdated(); 149 o.createInputAttributes(); 150 return o; 151 } 152 153 156 private void createInputAttributes() { 157 inputAttributes = new SimpleAttributeSet () { 158 public AttributeSet getResolveParent() { 159 return (currentParagraph != null) ? 160 currentParagraph.getAttributes() : null; 161 } 162 163 public Object clone() { 164 return new SimpleAttributeSet (this); 165 } 166 }; 167 } 168 169 172 private void createInputAttributeUpdated() { 173 inputAttributeUpdater = new AttributeTracker(); 174 } 175 176 177 private static final ViewFactory defaultFactory = new StyledViewFactory(); 178 179 Element currentRun; 180 Element currentParagraph; 181 182 186 MutableAttributeSet inputAttributes; 187 188 194 private AttributeTracker inputAttributeUpdater; 195 196 204 class AttributeTracker implements CaretListener, PropertyChangeListener , Serializable { 205 206 210 void updateInputAttributes(int dot, int mark, JTextComponent c) { 211 Document aDoc = c.getDocument(); 213 if (!(aDoc instanceof StyledDocument )) { 214 return ; 215 } 216 int start = Math.min(dot, mark); 217 StyledDocument doc = (StyledDocument )aDoc; 219 Element run; 223 currentParagraph = doc.getParagraphElement(start); 224 if (currentParagraph.getStartOffset() == start || dot != mark) { 225 run = doc.getCharacterElement(start); 228 } 229 else { 230 run = doc.getCharacterElement(Math.max(start-1, 0)); 231 } 232 if (run != currentRun) { 233 241 currentRun = run; 242 createInputAttributes(currentRun, getInputAttributes()); 243 } 244 } 245 246 public void propertyChange(PropertyChangeEvent evt) { 247 Object newValue = evt.getNewValue(); 248 Object source = evt.getSource(); 249 250 if ((source instanceof JTextComponent ) && 251 (newValue instanceof Document )) { 252 updateInputAttributes(0, 0, (JTextComponent )source); 254 } 255 } 256 257 public void caretUpdate(CaretEvent e) { 258 updateInputAttributes(e.getDot(), e.getMark(), 259 (JTextComponent )e.getSource()); 260 } 261 } 262 263 272 protected void createInputAttributes(Element element, 273 MutableAttributeSet set) { 274 if (element.getAttributes().getAttributeCount() > 0 275 || element.getEndOffset() - element.getStartOffset() > 1 276 || element.getEndOffset() < element.getDocument().getLength()) { 277 set.removeAttributes(set); 278 set.addAttributes(element.getAttributes()); 279 set.removeAttribute(StyleConstants.ComponentAttribute); 280 set.removeAttribute(StyleConstants.IconAttribute); 281 set.removeAttribute(AbstractDocument.ElementNameAttribute); 282 set.removeAttribute(StyleConstants.ComposedTextAttribute); 283 } 284 } 285 286 288 static class StyledViewFactory implements ViewFactory { 289 290 public View create(Element elem) { 291 String kind = elem.getName(); 292 if (kind != null) { 293 if (kind.equals(AbstractDocument.ContentElementName)) { 294 return new LabelView (elem); 295 } else if (kind.equals(AbstractDocument.ParagraphElementName)) { 296 return new ParagraphView (elem); 297 } else if (kind.equals(AbstractDocument.SectionElementName)) { 298 return new BoxView (elem, View.Y_AXIS); 299 } else if (kind.equals(StyleConstants.ComponentElementName)) { 300 return new ComponentView (elem); 301 } else if (kind.equals(StyleConstants.IconElementName)) { 302 return new IconView (elem); 303 } 304 } 305 306 return new LabelView (elem); 308 } 309 310 } 311 312 314 private static final Action [] defaultActions = { 315 new FontFamilyAction("font-family-SansSerif", "SansSerif"), 316 new FontFamilyAction("font-family-Monospaced", "Monospaced"), 317 new FontFamilyAction("font-family-Serif", "Serif"), 318 new FontSizeAction("font-size-8", 8), 319 new FontSizeAction("font-size-10", 10), 320 new FontSizeAction("font-size-12", 12), 321 new FontSizeAction("font-size-14", 14), 322 new FontSizeAction("font-size-16", 16), 323 new FontSizeAction("font-size-18", 18), 324 new FontSizeAction("font-size-24", 24), 325 new FontSizeAction("font-size-36", 36), 326 new FontSizeAction("font-size-48", 48), 327 new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT), 328 new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER), 329 new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT), 330 new BoldAction(), 331 new ItalicAction(), 332 new StyledInsertBreakAction(), 333 new UnderlineAction() 334 }; 335 336 361 public abstract static class StyledTextAction extends TextAction { 362 363 368 public StyledTextAction(String nm) { 369 super(nm); 370 } 371 372 378 protected final JEditorPane getEditor(ActionEvent e) { 379 JTextComponent tcomp = getTextComponent(e); 380 if (tcomp instanceof JEditorPane ) { 381 return (JEditorPane ) tcomp; 382 } 383 return null; 384 } 385 386 393 protected final StyledDocument getStyledDocument(JEditorPane e) { 394 Document d = e.getDocument(); 395 if (d instanceof StyledDocument ) { 396 return (StyledDocument ) d; 397 } 398 throw new IllegalArgumentException ("document must be StyledDocument"); 399 } 400 401 408 protected final StyledEditorKit getStyledEditorKit(JEditorPane e) { 409 EditorKit k = e.getEditorKit(); 410 if (k instanceof StyledEditorKit ) { 411 return (StyledEditorKit ) k; 412 } 413 throw new IllegalArgumentException ("EditorKit must be StyledEditorKit"); 414 } 415 416 428 protected final void setCharacterAttributes(JEditorPane editor, 429 AttributeSet attr, boolean replace) { 430 int p0 = editor.getSelectionStart(); 431 int p1 = editor.getSelectionEnd(); 432 if (p0 != p1) { 433 StyledDocument doc = getStyledDocument(editor); 434 doc.setCharacterAttributes(p0, p1 - p0, attr, replace); 435 } 436 StyledEditorKit k = getStyledEditorKit(editor); 437 MutableAttributeSet inputAttributes = k.getInputAttributes(); 438 if (replace) { 439 inputAttributes.removeAttributes(inputAttributes); 440 } 441 inputAttributes.addAttributes(attr); 442 } 443 444 455 protected final void setParagraphAttributes(JEditorPane editor, 456 AttributeSet attr, boolean replace) { 457 int p0 = editor.getSelectionStart(); 458 int p1 = editor.getSelectionEnd(); 459 StyledDocument doc = getStyledDocument(editor); 460 doc.setParagraphAttributes(p0, p1 - p0, attr, replace); 461 } 462 463 } 464 465 480 public static class FontFamilyAction extends StyledTextAction { 481 482 488 public FontFamilyAction(String nm, String family) { 489 super(nm); 490 this.family = family; 491 } 492 493 498 public void actionPerformed(ActionEvent e) { 499 JEditorPane editor = getEditor(e); 500 if (editor != null) { 501 String family = this.family; 502 if ((e != null) && (e.getSource() == editor)) { 503 String s = e.getActionCommand(); 504 if (s != null) { 505 family = s; 506 } 507 } 508 if (family != null) { 509 MutableAttributeSet attr = new SimpleAttributeSet (); 510 StyleConstants.setFontFamily(attr, family); 511 setCharacterAttributes(editor, attr, false); 512 } else { 513 UIManager.getLookAndFeel().provideErrorFeedback(editor); 514 } 515 } 516 } 517 518 private String family; 519 } 520 521 536 public static class FontSizeAction extends StyledTextAction { 537 538 544 public FontSizeAction(String nm, int size) { 545 super(nm); 546 this.size = size; 547 } 548 549 554 public void actionPerformed(ActionEvent e) { 555 JEditorPane editor = getEditor(e); 556 if (editor != null) { 557 int size = this.size; 558 if ((e != null) && (e.getSource() == editor)) { 559 String s = e.getActionCommand(); 560 try { 561 size = Integer.parseInt(s, 10); 562 } catch (NumberFormatException nfe) { 563 } 564 } 565 if (size != 0) { 566 MutableAttributeSet attr = new SimpleAttributeSet (); 567 StyleConstants.setFontSize(attr, size); 568 setCharacterAttributes(editor, attr, false); 569 } else { 570 UIManager.getLookAndFeel().provideErrorFeedback(editor); 571 } 572 } 573 } 574 575 private int size; 576 } 577 578 603 public static class ForegroundAction extends StyledTextAction { 604 605 611 public ForegroundAction(String nm, Color fg) { 612 super(nm); 613 this.fg = fg; 614 } 615 616 621 public void actionPerformed(ActionEvent e) { 622 JEditorPane editor = getEditor(e); 623 if (editor != null) { 624 Color fg = this.fg; 625 if ((e != null) && (e.getSource() == editor)) { 626 String s = e.getActionCommand(); 627 try { 628 fg = Color.decode(s); 629 } catch (NumberFormatException nfe) { 630 } 631 } 632 if (fg != null) { 633 MutableAttributeSet attr = new SimpleAttributeSet (); 634 StyleConstants.setForeground(attr, fg); 635 setCharacterAttributes(editor, attr, false); 636 } else { 637 UIManager.getLookAndFeel().provideErrorFeedback(editor); 638 } 639 } 640 } 641 642 private Color fg; 643 } 644 645 669 public static class AlignmentAction extends StyledTextAction { 670 671 677 public AlignmentAction(String nm, int a) { 678 super(nm); 679 this.a = a; 680 } 681 682 687 public void actionPerformed(ActionEvent e) { 688 JEditorPane editor = getEditor(e); 689 if (editor != null) { 690 int a = this.a; 691 if ((e != null) && (e.getSource() == editor)) { 692 String s = e.getActionCommand(); 693 try { 694 a = Integer.parseInt(s, 10); 695 } catch (NumberFormatException nfe) { 696 } 697 } 698 MutableAttributeSet attr = new SimpleAttributeSet (); 699 StyleConstants.setAlignment(attr, a); 700 setParagraphAttributes(editor, attr, false); 701 } 702 } 703 704 private int a; 705 } 706 707 719 public static class BoldAction extends StyledTextAction { 720 721 724 public BoldAction() { 725 super("font-bold"); 726 } 727 728 733 public void actionPerformed(ActionEvent e) { 734 JEditorPane editor = getEditor(e); 735 if (editor != null) { 736 StyledEditorKit kit = getStyledEditorKit(editor); 737 MutableAttributeSet attr = kit.getInputAttributes(); 738 boolean bold = (StyleConstants.isBold(attr)) ? false : true; 739 SimpleAttributeSet sas = new SimpleAttributeSet (); 740 StyleConstants.setBold(sas, bold); 741 setCharacterAttributes(editor, sas, false); 742 } 743 } 744 } 745 746 758 public static class ItalicAction extends StyledTextAction { 759 760 763 public ItalicAction() { 764 super("font-italic"); 765 } 766 767 772 public void actionPerformed(ActionEvent e) { 773 JEditorPane editor = getEditor(e); 774 if (editor != null) { 775 StyledEditorKit kit = getStyledEditorKit(editor); 776 MutableAttributeSet attr = kit.getInputAttributes(); 777 boolean italic = (StyleConstants.isItalic(attr)) ? false : true; 778 SimpleAttributeSet sas = new SimpleAttributeSet (); 779 StyleConstants.setItalic(sas, italic); 780 setCharacterAttributes(editor, sas, false); 781 } 782 } 783 } 784 785 797 public static class UnderlineAction extends StyledTextAction { 798 799 802 public UnderlineAction() { 803 super("font-underline"); 804 } 805 806 811 public void actionPerformed(ActionEvent e) { 812 JEditorPane editor = getEditor(e); 813 if (editor != null) { 814 StyledEditorKit kit = getStyledEditorKit(editor); 815 MutableAttributeSet attr = kit.getInputAttributes(); 816 boolean underline = (StyleConstants.isUnderline(attr)) ? false : true; 817 SimpleAttributeSet sas = new SimpleAttributeSet (); 818 StyleConstants.setUnderline(sas, underline); 819 setCharacterAttributes(editor, sas, false); 820 } 821 } 822 } 823 824 825 832 static class StyledInsertBreakAction extends StyledTextAction { 833 private SimpleAttributeSet tempSet; 834 835 StyledInsertBreakAction() { 836 super(insertBreakAction); 837 } 838 839 public void actionPerformed(ActionEvent e) { 840 JEditorPane target = getEditor(e); 841 842 if (target != null) { 843 if ((!target.isEditable()) || (!target.isEnabled())) { 844 UIManager.getLookAndFeel().provideErrorFeedback(target); 845 return; 846 } 847 StyledEditorKit sek = getStyledEditorKit(target); 848 849 if (tempSet != null) { 850 tempSet.removeAttributes(tempSet); 851 } 852 else { 853 tempSet = new SimpleAttributeSet (); 854 } 855 tempSet.addAttributes(sek.getInputAttributes()); 856 target.replaceSelection("\n"); 857 858 MutableAttributeSet ia = sek.getInputAttributes(); 859 860 ia.removeAttributes(ia); 861 ia.addAttributes(tempSet); 862 tempSet.removeAttributes(tempSet); 863 } 864 else { 865 JTextComponent text = getTextComponent(e); 867 868 if (text != null) { 869 if ((!text.isEditable()) || (!text.isEnabled())) { 870 UIManager.getLookAndFeel().provideErrorFeedback(target); 871 return; 872 } 873 text.replaceSelection("\n"); 874 } 875 } 876 } 877 } 878 } 879 | Popular Tags |