Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4250847

bad repainting in JTextPane when Paragraph increas its height

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.2.2, 1.3.0, 1.3.0_02, 1.3.1, 1.4.0
    • client-libs
    • beta2
    • generic, x86, sparc
    • generic, solaris_2.5.1, solaris_7, windows_nt



      Name: vi73552 Date: 06/30/99


      Take my application, run it, zoom in one time, and write a lot
      of text in the top most paragraph. If there is enough text
      in the first paragraph, the following paragraphs are not
      correctly repainted.

      import javax.swing.*;
      import javax.swing.text.*;
      import javax.swing.event.*;
      import java.lang.*;
      import java.awt.*;
      import java.awt.event.*;
      import java.util.*;

      public class Test extends JFrame {
        public static final String ORIG_SIZE = "orig_size";
        StyleContext styles;
        float zoom = 1.0f;

        Hashtable actionTable = new Hashtable();

        class MyParagraphView extends ParagraphView {
          public MyParagraphView(Element element) {
            super(element);
          }

          public void paint(Graphics g, Shape a) {
            Graphics2D g2d = (Graphics2D)g;
            Element element, child;
            StyledDocument styled;
            Font eFont;

            try {
              super.paint(g2d, a);
              Rectangle r = a.getBounds();
              
              element = getElement();
              View row = getView(0);
              int cnt = row.getViewCount();
              int current, max = 0;
              for (int i = 0; i < cnt; i++) {
                View view = row.getView(i);
                child = view.getElement();
                styled = (StyledDocument)child.getDocument();
                eFont = styled.getFont(child.getAttributes());
                current = g2d.getFontMetrics(eFont).getAscent();
                if (current > max) {
                  max = current;
                }
              }

              Font font = ((StyledDocument)element.getDocument()).getFont(element.getAttributes());

              g2d.setColor(Color.black);
              g2d.setFont(font);
              g2d.drawString("-", r.x, r.y+max);
              g2d.setColor(Color.blue);
              g2d.drawRect(r.x, r.y, r.width, r.height);
            } catch (Exception ex) {
              ex.printStackTrace();
            }
          }
        }

        class MyStyledEditorKit extends StyledEditorKit implements ViewFactory {
          public MyStyledEditorKit() {
            super();
          }

          public void updateInputAttributes(Element element, MutableAttributeSet set) {
            createInputAttributes(element, set);
          }

          public ViewFactory getViewFactory() {
            return this;
          }
          
          public View create(Element element) {
            String kind = element.getName();
            if (kind != null) {
              if (kind.equals(AbstractDocument.ContentElementName)) {
                System.out.println("label");
                return new LabelView(element);
              } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
                System.out.println("paragraph");
                return new MyParagraphView(element);
              } else if (kind.equals(AbstractDocument.SectionElementName)) {
                System.out.println("box");
                return new BoxView(element, View.Y_AXIS);
              } else if (kind.equals(StyleConstants.ComponentElementName)) {
                System.out.println("component");
                return new ComponentView(element);
              } else if (kind.equals(StyleConstants.IconElementName)) {
                System.out.println("icon");
                return new IconView(element);
              }
            }
            System.out.println("label");
            return new LabelView(element);
          }
        }

        public Test() {
          styles = new StyleContext();
          Style def = styles.getStyle(StyleContext.DEFAULT_STYLE);
          def.addAttribute(ORIG_SIZE, new Integer(12));
          StyleConstants.setFontSize(def, 12);

          Style sty = styles.addStyle("normal", def);
          sty.addAttribute(ORIG_SIZE, new Integer(12));
          StyleConstants.setFontFamily(sty, "TimesRoman");

          updateStyles();

          JTextPane textPane = new JTextPane();
          textPane.setEditorKit(new MyStyledEditorKit());
          StyledDocument doc = textPane.getStyledDocument();

          Action[] actions = textPane.getActions();
          for (int i = 0; i < actions.length; i++) {
            actionTable.put(actions[i].getValue(Action.NAME), actions[i]);
            System.out.println(actions[i].getValue(Action.NAME));
          }
          
          textPane.setLogicalStyle(styles.getStyle("normal"));
         
          try {
            doc.insertString(0, "this\nis\nsome\ntext", styles.getStyle("normal"));
          } catch (Exception ex) {
            ex.printStackTrace();
          }

          JToolBar toolbar = new JToolBar();
          JButton button = null;
          
          Container contentPane = getContentPane();
          contentPane.add(toolbar, BorderLayout.NORTH);
          contentPane.add(textPane, BorderLayout.CENTER);

          TextAction inAction = new TextAction("In") {
            public void actionPerformed(ActionEvent e) {
              JTextPane activePane = (JTextPane)getTextComponent(e);
              if (activePane != null) {
                try {
                  zoom = zoom * 2.0f;
                  updateStyles();
                  updateFontSize(activePane);
                  MyStyledEditorKit kit = (MyStyledEditorKit)activePane.getEditorKit();
                  kit.updateInputAttributes(kit.getCharacterAttributeRun(), kit.getInputAttributes());
                  activePane.revalidate();
                } catch (Exception ex) {
                  ex.printStackTrace();
                }
              }
            }
          };

          TextAction outAction = new TextAction("Out") {
            public void actionPerformed(ActionEvent e) {
              JTextPane activePane = (JTextPane)getTextComponent(e);
              if (activePane != null) {
                try {
                  zoom = zoom * 0.5f;
                  updateStyles();
                  updateFontSize(activePane);
                  MyStyledEditorKit kit = (MyStyledEditorKit)activePane.getEditorKit();
                  kit.updateInputAttributes(kit.getCharacterAttributeRun(), kit.getInputAttributes());
                  activePane.revalidate();
                } catch (Exception ex) {
                  ex.printStackTrace();
                }
              }
            }
          };

          TextAction selAction = new TextAction("Bigger") {
            public void actionPerformed(ActionEvent e) {
              JTextPane activePane = (JTextPane)getTextComponent(e);
              StyledDocument sd = activePane.getStyledDocument();
              int selStart = activePane.getSelectionStart();
              int selEnd = activePane.getSelectionEnd();
              int start, end = selStart;
              while (end < selEnd) {
                Element element = sd.getCharacterElement(end);
                start = Math.max(selStart, element.getStartOffset());
                end = Math.min(selEnd, element.getEndOffset());
                AttributeSet oldset = element.getAttributes();
                MutableAttributeSet newset = new SimpleAttributeSet(oldset);

                newset.removeAttribute(ORIG_SIZE);
                newset.removeAttribute(StyleConstants.FontConstants.Size);
                int newrefsize = 18;
                int newsize = (int)((float)newrefsize * zoom);
                newset.addAttribute(ORIG_SIZE, new Integer(newrefsize));
                newset.addAttribute(StyleConstants.FontConstants.Size, new Integer(newsize));

                sd.setCharacterAttributes(start, end-start, newset, true);
              }
              activePane.revalidate();
            }
          };

          button = toolbar.add(inAction);
          button.setText("In");
          button.setToolTipText("in button");

          button = toolbar.add(outAction);
          button.setText("Out");
          button.setToolTipText("out button");

          button = toolbar.add(selAction);
          button.setText("Bigger");
          button.setToolTipText("bigger");

          button = toolbar.add((Action)actionTable.get("font-bold"));
          button.setText("Bold");
          button.setToolTipText("bold");

          button = toolbar.add((Action)actionTable.get("font-italic"));
          button.setText("Italic");
          button.setToolTipText("italic");
        }

        public void updateFontSize(JTextPane tp) {
          propagate(tp.getStyledDocument().getDefaultRootElement());
        }

        public void propagate(Element element) {
          Document document = element.getDocument();
          if (document instanceof StyledDocument) {
            StyledDocument styled = (StyledDocument)document;
            int start = element.getStartOffset();
            int end = element.getEndOffset();
            AttributeSet set = element.getAttributes();
            if (element.getElementCount() > 0) {
              AttributeSet as = styled.getParagraphElement(start).getAttributes();
              Enumeration enum = ((AbstractDocument.AbstractElement)element).children();
              while (enum.hasMoreElements()) {
                propagate((Element)enum.nextElement());
              }
            } else {
              styled.setCharacterAttributes(start, end-start, createAttributeSetFrom(set, zoom), true);
            }
          }
        }

        public AttributeSet createAttributeSetFrom(AttributeSet set, float zoom) {
          Object origSize = set.getAttribute(ORIG_SIZE);
          if (origSize != null) {
            int newSize = (int)((float)((Integer)origSize).intValue() * zoom);
            MutableAttributeSet newset = new SimpleAttributeSet(set);
            newset.addAttribute(StyleConstants.FontConstants.Size, new Integer(newSize));
            return (AttributeSet)newset;
          } else {
            return set;
          }
        }

        public void updateStyles() {
          Style sty, ref;
          Enumeration names = styles.getStyleNames();
          while (names.hasMoreElements()) {
            String name = (String)names.nextElement();
            sty = styles.getStyle(name);
            Object o = sty.getAttribute(ORIG_SIZE);
            int i = ((Integer)o).intValue();
            StyleConstants.setFontSize(sty, (int)((float)i * zoom));
            StyleConstants.setLeftIndent(sty, (int)((float)i * zoom));
          }
        }

        public static void main(String[] args) {
          Test test = new Test();
          test.pack();
          test.setSize(500, 500);
          test.show();
        }
      }
      (Review ID: 85015)
      ======================================================================

            shickeysunw Shannon Hickey (Inactive)
            vasya Vassili Igouchkine (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: