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.
Kes.
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.setHorizontal ScrollBarP olicy(JScr ollPane.HO RIZONTAL_S CROLLBAR_N EVER);
jScrollPane1.setVerticalSc rollBarPol icy(JScrol lPane.VERT ICAL_SCROL LBAR_ALWAY S);
jScrollPane1.getViewport() .setBackgr ound(Color .white);
jScrollPane1.setAlignmentX ((float) 0.0);
jScrollPane1.setAlignmentY ((float) 0.0);
jScrollPane1.setDoubleBuff ered(true) ;
jScrollPane1.setBounds(new Rectangle(12, 12, 470, 374));
output.setForeground(Color .white);
output.setName("");
output.setOpaque(false);
output.setCaretColor(Color .white);
output.setSelectionColor(C olor.white );
output.setContentType("tex t/html");
output.addComponentListene r(new ChatApplet_output_componen tAdapter(t his));
output.setDoubleBuffered(t rue);
output.setCaretPosition(0) ;
output.setMargin(new Insets(3, 3, 3, 3));
output.setText("<html><hea d></head>< body></bod y></html>" );
jScrollPane1.getViewport() .add(outpu t, 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("</bo dy>") >= 0)
{
int insertAt_i = htmlText_ac.indexOf("</bod y>");
text_ac.insert(insertAt_i, buildHtmlMessage(I_Message _ac));
output.setText(text_ac.toS tring());
}
}
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.preferedIconNa me_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;
}
JScrollPane jScrollPane1 = new JScrollPane();
JEditorPane output = new JEditorPane();
jScrollPane1.setHorizontal
jScrollPane1.setVerticalSc
jScrollPane1.getViewport()
jScrollPane1.setAlignmentX
jScrollPane1.setAlignmentY
jScrollPane1.setDoubleBuff
jScrollPane1.setBounds(new
output.setForeground(Color
output.setName("");
output.setOpaque(false);
output.setCaretColor(Color
output.setSelectionColor(C
output.setContentType("tex
output.addComponentListene
output.setDoubleBuffered(t
output.setCaretPosition(0)
output.setMargin(new Insets(3, 3, 3, 3));
output.setText("<html><hea
jScrollPane1.getViewport()
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("</bo
{
int insertAt_i = htmlText_ac.indexOf("</bod
text_ac.insert(insertAt_i,
output.setText(text_ac.toS
}
}
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>
"width=438><tr> <td width = 45 align=center valign=top wrap>" +
"<img src=\"" + mUserData_t.preferedIconNa
"</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;
}
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()
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).
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.
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?
2) so you are saying that the problem is not related to the scrolling, purely the editorpane.
How would you fix it by subclassing?
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?
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?
ASKER
Hmmm, how do I do that exactly?
using EventQueue.invokeLater(), and invokeAndWait()
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.
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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...