United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6306218 : JEditorPane is unable to do reasonably spaced indentation in complex HTML tables

Details
Type:
Bug
Submit Date:
2005-08-04
Status:
Resolved
Updated Date:
2010-07-29
Project Name:
JDK
Resolved Date:
2006-05-31
Component:
client-libs
OS:
solaris_8
Sub-Component:
javax.swing
CPU:
sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.3.1_16,1.4.2_10
Fixed Versions:

Related Reports
Backport:
Backport:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
JEditorPane is unable to do reasonably spaced indentation. The indentation distance
is much too long. The problem gets even worse with 1.4.2 and 1.5.0.

The problem is strictly reproducible:

1. Testcase
-----------
Please find entire testcase attached:

% more Test.java
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class Test extends JFrame
{
  JEditorPane txt;
  HTMLEditorKit c;
  HTMLDocument doc;

  class WindowClose extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
  }

  public Test()
  {
    super("Test");
    setSize(500,300);
    addWindowListener(new WindowClose());
    JEditorPane jep = new JEditorPane();
    jep.setEditable(false);
    HTMLEditorKit c= new HTMLEditorKit();
    jep.setEditorKit(c);
    try {
      jep.setPage(getClass().getResource("D-KA-0008170.html"));
    } catch (Exception e) {}
    HTMLDocument doc=(HTMLDocument)jep.getDocument();
    getContentPane().add(new JScrollPane(jep));
    setVisible(true);
  }

  public static void main(String argv[])
  {
    new Test();
  }
}

2. Compile and run
------------------
% make 
/j2sdk1_3_1_16/bin/javac Test.java 
% make run
/j2sdk1_3_1_16/bin/java -version
java version "1.3.1_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_16-b06)
Java HotSpot(TM) Client VM (build 1.3.1_16-b06, mixed mode)
/j2sdk1_3_1_16/bin/java Test
[ application window will appear ... ]

 Please note that the indentaion is correct however the indentation offset of
 all dashed items is much too long.

3. Display html in browser like mozilla and compare

                                    

Comments
EVALUATION

Here is stripped down version of the test html file:
--
<TABLE CLASS='LIST' BORDER=1 CELLPADDING=0 CELLSPACING=0 border=1>
                <TR>
                <TD></TD>
                <TD style='width:25px;'>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;width:1%;'>
                  <DIV CLASS='pitem'><NOBR><IMG BORDER="0" SRC="_triangle.gif"></NOBR>
                  </DIV>
                </TD>
                <TD valign=top COLSPAN=2>
                  <DIV CLASS='pitem'>
                    Mit den Funktionen des 'Vertriebsmanagements' binden Sie alle vertrieblichen Aspekte in ein umfassendes Management ein. Sie erh&ouml;hen die Effizienz in allen Phasen$
                  </DIV>
                </TD>
                </TR>

                <TR>
                <TD>
                </TD>
                <TD style='width:25px;'>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;width:1%;'><DIV CLASS='pitem'><NOBR></NOBR></DIV>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;width:1%;'><DIV CLASS='pitem'><NOBR><IMG BORDER="0" SRC="_dash.gif"></NOBR></DIV>
                </TD>
                <TD valign=top COLSPAN=1><DIV CLASS='pitem'>das Definieren von Vorlagen f&uuml;r Aktivit&auml;ten, Anl&auml;sse und Kundenbenachrichtigungen,</DIV></TD>
                </TR>
</TABLE>
--

As a workaround I can suggest to fix html a bit.
remove width:1% from the style for <td> 
add width=99% or style  width:99% to the <td> with the content.

Tweaked html
--
<TABLE CLASS='LIST' BORDER=1 CELLPADDING=0 CELLSPACING=0 border=1>
                <TR>
                <TD></TD>
                <TD style='width:25px;'>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;'>
                  <DIV CLASS='pitem'><NOBR><IMG BORDER="0" SRC="_triangle.gif"></NOBR>
                  </DIV>
                </TD>
                <TD valign=top COLSPAN=2>
                  <DIV CLASS='pitem'>
                    Mit den Funktionen des 'Vertriebsmanagements' binden Sie alle vertrieblichen Aspekte in ein umfassendes Management ein. Sie erh&ouml;hen die Effizienz in allen Phasen$
                  </DIV>
                </TD>
                </TR>

                <TR>
                <TD>
                </TD>
                <TD style='width:25px;'>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;'><DIV CLASS='pitem'><NOBR></NOBR></DIV>
                </TD>
                <TD valign=top style='padding-top:0px;padding-left:5px;padding-right:5px;'><DIV CLASS='pitem'><NOBR><IMG BORDER="0" SRC="_dash.gif"></NOBR></DIV>
                </TD>
                <TD width=99% valign=top COLSPAN=1><DIV CLASS='pitem'>das Definieren von Vorlagen f&uuml;r Aktivit&auml;ten, Anl&auml;sse und Kundenbenachrichtigungen,</DIV></TD>
                </TR>

</TABLE>

--
                                     
2005-08-05
EVALUATION

There are a few unrelated problems with table implementation which cause this bug:
1. IE and Mozilla give percentage width preference over anything else.
In our implementation  for the column preferred width we use Math.max(percentages[col], columnRequirements[col].preferred);

To mimic what other renderers do we should use
Math.max(percentages[col], columnRequirements[col].minimum);

2. When there are images in the table we use default image for loading-image while images are getting loaded.
If the size of the actual image is different than the size of the default image the table should be updated to accommodate it when all images are loaded.
There is a bug in TableView.calculateColumnRequirements implementation. It does not clean old requirements when calculating the new ones.
The algorithm is implemented in such a way that it uses maximum of current values and the one it calculates. Because it does not clean the old requirements
the current values are the old ones. Because it uses maximum the values for the color requirements could not get smaller than the old ones. 
If the size of the actual image is smaller than the size of the default one the table column will not get smaller because of that error.

To fix it it we need to clean current columnRequirements in calculateColumnRequirements method.
                                     
2006-04-05
EVALUATION

There is one more problem with the bug.
Some times we wrap words on character boundaries when we should not.
There are two reasons for that :
1. InlineView returns calculateLonegestWordSpan as the smallest span possible.
It uses word BreakIterator for that. However the length of the longest word is not necessarily the smallest span possible for the InlineView.
For example for "&nbsp;test" calculateLonegestWordSpan returns width of word "test" instead of " test".
solution :
calculateLonegestWordSpan needs to use the same algorithm which is used in GlyphView to break it: spaces or line BreakIterator

2. PargraphView minimum span returns maximum of minimum spans for the views it contains.
That is wrong since we not necessarily break rows on the View boundaries.
For example :
<b>bold</b><i>italic</i>
The minimum width for this should be the width of 
<b>bold</b><i>italic</i> but not the 
max(width(<b>bold</b>), width(<i>italic</i>))
                                     
2006-05-02
EVALUATION

To partially address problem with ParagraphView
I suggest to change breakWeight for GlyphView and all descendants.
Breaking on the View boundary is better than splitting it. 

*** /tmp/geta27065	Mon May  8 22:29:38 2006
--- GlyphView.java	Mon May  8 20:06:05 2006
***************
*** 670,676 ****
                  return View.ExcellentBreakWeight;
              }
  	    // Nothing good to break on.
! 	    return View.GoodBreakWeight;
  	}
  	return super.getBreakWeight(axis, pos, len);
      }
--- 670,681 ----
                  return View.ExcellentBreakWeight;
              }
  	    // Nothing good to break on.
!             // breaking on the View boundary is better than splitting it
!             if (p1 == getEndOffset()) {
!                 return View.GoodBreakWeight;
!             } else {
!                 return View.GoodBreakWeight - 1;
!             }
  	}
  	return super.getBreakWeight(axis, pos, len);
      }

For example : <b>bold</b><i>italic</i>
After this change will be split only:
<b>bold</b>
<i>italic</i>

It is not correct since it should not be wrapped at all but it is much better
than splitting "bold" or "italic" across two rows.

New bug has been created to address ParagraphView minimum span problem:
6423287  [PargraphView returns wrong minimum span]
                                     
2006-05-09



Hardware and Software, Engineered to Work Together