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

Attributes on last newline character cause undesirable extra spacing.

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 1.3.0, 1.4.0
    • Fix Version/s: None
    • Component/s: client-libs
    • Subcomponent:
    • Understanding:
      Fix Understood
    • CPU:
      generic, sparc
    • OS:
      generic, solaris_7

      Description

      When displaying text with font smaller than the default font, the last line contains extra spacing. This is a result of the last newline character being considered during layout.

      Original report:
      ------------------------------------

      Name: krT82822 Date: 10/13/99


      10/13/99 eval1127@eng -- reproducible in kestrel-RA. Am submitting reference bug #.

      Take my application, run it, zomm in a few times, select all,
      press button "smaller". You'll see that the line spacing
      between the last row and the on before the last row is not
      adapted.

      See the following code:

      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();

        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();
          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]);
          }
          
          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);
                  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);
                  activePane.revalidate();
                } catch (Exception ex) {
                  ex.printStackTrace();
                }
              }
            }
          };

          TextAction selAction = new TextAction("Smaller") {
            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 = 8;
                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);
              }
              start = selStart;
              end = selStart;
              while (end < selEnd) {
                Element element = sd.getParagraphElement(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 = 8;
                int newsize = (int)((float)newrefsize * zoom);
                newset.addAttribute(ORIG_SIZE, new Integer(newrefsize));
                newset.addAttribute(StyleConstants.FontConstants.Size, new Integer(newsize));

                sd.setParagraphAttributes(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("Smaller");
          button.setToolTipText("smaller");
        }

        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));
          }
        }

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

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                peterz Peter Zhelezniakov (Inactive)
                Reporter:
                kryansunw Kevin Ryan (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Imported:
                  Indexed: