Link to home
Start Free TrialLog in
Avatar of kesea
kesea

asked on

Flickering of a JEditorPane in a JScrollPanel

Hi Experts, well I have a problem.  I have implemented an html JEditorPane in a JScrollPanel, and it works fine, but the problem is I am adding HTML code to this JEditorPane .  I have tried making it doublebuffered, playing with the Opaqueness, and even tried overloading paint, but that is only called when the JApplet is drawn or the screen is refreshed.  I get a problem when I post quickly to the JEditorPane the scrolling starts scrolling, but it flickers and I can see images from above in the middle of the screen, which is odd since they are only on the sides.  If I add things slowly, it still happens only occasionally.  Is there a way maybe to override the paint function of the JEditorPane?  Please help, thanks in advance.

Kes.
Avatar of keteracel
keteracel
Flag of United States of America image

you couldn't post the code for the pane please?

Offhand, it  sounds like it's either doing too much so it's taking too long, or the caret position is changing making the scroll move...

Without demoing it I don't know what exactly the symptoms are...
Avatar of kesea
kesea

ASKER

Ok I just grabbed the parts that are screwing up, I have an JEditorPane that is in a JScrollPane and when I post HTML data to it (images and text) it is ok sometimes, but intermittently it flickers.  It is annoying, especially if you start sending text quickly to the JEditorPane, any suggestions?


    JScrollPane jScrollPane1 = new JScrollPane();
    JEditorPane output = new JEditorPane();

    jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    jScrollPane1.getViewport().setBackground(Color.white);
    jScrollPane1.setAlignmentX((float) 0.0);
    jScrollPane1.setAlignmentY((float) 0.0);
    jScrollPane1.setDoubleBuffered(true);
    jScrollPane1.setBounds(new Rectangle(12, 12, 470, 374));
    output.setForeground(Color.white);
    output.setName("");
    output.setOpaque(false);
    output.setCaretColor(Color.white);
    output.setSelectionColor(Color.white);
    output.setContentType("text/html");
    output.addComponentListener(new ChatApplet_output_componentAdapter(this));
    output.setDoubleBuffered(true);
    output.setCaretPosition(0);
    output.setMargin(new Insets(3, 3, 3, 3));
    output.setText("<html><head></head><body></body></html>");
    jScrollPane1.getViewport().add(output, null);

  public void ShowReceivedMessage (String I_Message_ac)
  {
     String htmlText_ac;
     htmlText_ac = output.getText();
     StringBuffer text_ac = new StringBuffer();
     text_ac.append(htmlText_ac);
     if (htmlText_ac.indexOf("</body>") >= 0)
     {
        int insertAt_i = htmlText_ac.indexOf("</body>");
        text_ac.insert(insertAt_i, buildHtmlMessage(I_Message_ac));
        output.setText(text_ac.toString());
     }
  }

  String buildHtmlMessage(String I_message_ac)
  {
     String messageText_ac = new String();
     StringBuffer temp_ac = new StringBuffer(I_message_ac);

     messageText_ac = "<table border=0 bordercolor=white><tr><td><table border=0 bgcolor=\"dddddd\
                      "width=438><tr> <td width = 45 align=center valign=top wrap>" +
                      "<img src=\"" + mUserData_t.preferedIconName_ac + "\">" +
                      "</td><td wrap align=left width = 393 valign=top >" +
                      "<b>" + mUserData_t.userName_ac + " says:</b>" + "<br> " +
                      temp_ac.toString() +
                      "</td></tr></table> </tr></td></table>"; //+ mMessageBreakImage_ac;
     return messageText_ac;
  }

Avatar of Mick Barry
where is ShowRecievedMessage being called from ie. what thread?
it may be worth trying running it on the event dispatch thread. See EventQueue.invokeLater(), and invokeAndWait()
Another idea (if desperate) would to be detach the editor from the scroll pane before doing the update, then reattching it once done with the viewport set at the same position when detached (if that makes sense).
Avatar of kesea

ASKER

The ShowReceivedMessage is being called from a socket when it receives a message that way.  

Basically what I am trying to do is get a nice scrolling chat message box, is there a better way to do this?  I found the easiest way was to just put the html in a JEditorPane and have it scroll, but it is goofing up.  

I appreciate the help, I have a few questions for your responses:
1)How would putting this in the event dispatch thread help?  Would it only call the refresh for the scrolling JEditorPane once?  

2)So if I understand your 2nd idea, I would unattach the JEditorPane from the JScrollPane then update the JEditorPane (so it doesn't scroll), and then re-attach it to the JScrollPane and then move it to the bottom?  I actually tried not making the JEditorPane part of the JScrollPane and just watched it update, and the same kind of blips happened on it, then I thought it was due to the double buffering of the JEditorPane, that is why I was trying to just override the paint of the JEditorPane.  

Thanks for your help.

1) Swing is single threaded and as such not thread safe.

2) so you are saying that the problem is not related to the scrolling, purely the editorpane.
How would you fix it by subclassing?
Avatar of kesea

ASKER

1) Ok, so you think the posting of the new JEditorPane, because I am just adding onto it and reposting the whole Text would effect it?  

2) It looks like the problem is in the editorpane.  Yeah I guess I was a little off by thinking I could fix it by double buffering just the Editorpane.  Is there a better way to put images and text in a scrolling window?  I tried the JList, but it was really ugly.  The HTML gives me the flexibility to make it look really good.  But I need it to scroll.  Can you put HTML in a JLIST?  
have you tried moving the ShowRecievedMessage to the EDT?
Avatar of kesea

ASKER

Hmmm, how do I do that exactly?
using EventQueue.invokeLater(), and invokeAndWait()
Avatar of kesea

ASKER

Ok, it is the JEditPane flickering with an update of the HTML.  Is there another way to do this, can I use a JList with HTML?  Would that solve my problem?
I think thats because you effectively replace the entire page, so the whole thing gets re-rendered.
Instead try inserting the html into the existing document, using HTMLEditorKit and/or HTMLDocument classes.

As far as using a different component goes, it depends what it is you are trying to achieve.
Avatar of kesea

ASKER

How can you do that?  I was just looking up how to do that, just to insert the HTML into the existing document.  Do you just do an add to the document?  I was always getting the whole page, finding the </body> tag and inserting my html ahead of that.  Can I just add <html><body>my stuff</body><html> into the JEditorPane?  There doesn't seem to be much info on this on the web.
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial