Cocoa-Java: Modifying and scrolling NSTextView contents from another thread
Cocoa-Java: Modifying and scrolling NSTextView contents from another thread
- Subject: Cocoa-Java: Modifying and scrolling NSTextView contents from another thread
- From: Steve Klingsporn <email@hidden>
- Date: Fri, 25 Oct 2002 11:17:49 -0500
Hi -
I have a "Connection" java.lang.Thread subclass that blocks on a socket
read and then calls a method in my controller class via a
Messenger->MessageHandler mechanism that is almost exactly like
java.util.Observable->java.util.Observer.
In my "messageReceived" handler, I see if the message has the
identifier for a chat message, and if it does, I execute the following
code to update the contents of my chat conversation NSView, and scroll
the contents to the bottom.
NSTextStorage storage = mConversationView.textStorage();
storage.beginEditing();
storage.appendAttributedString(string);
storage.endEditing();
int length = storage.length();
mConversationView.scrollRangeToVisible(new NSRange(
length, 0);
Back in the day when things were simple, mConversationView (an
NSTextView) was the child of a plain NSView, which was the contentView
of an NSDrawer that was associated with my main window.
Now, mConversationView is the child of an NSTabView.
Everything runs fine when I'm manually typing, and the above code runs
from the main thread. When I get a bunch of chat messages in from the
Connection thread and click on the other tab in the tab view, things
often go awry. I've isolated it using the Java debugger to the last
line, where I call scrollRangeToVisible. If I comment out this code, I
never hang. If I don't, I get the lovely spinning beachball. I don't
like the beachball -- at all.
Occasionally, I get weird NSExceptions in the try block in my
inputReader.readLine() call. This code looks like this:
try
{
String line = null;
while (mSocket != null && ((line = mInput.readLine()) != null))
sendMessage(new Message(DATA_RECEIVED, line));
}
catch (IOException ignored) { }
finally
{
mSocket.close();
I end up on the first line of the finally clause in the debugger, and
"ignored" is set to the chat message (a java.lang.String) that came in,
not to any type of exception. So I know that these chat message
strings are triggering it, and that scrollRangeToVisible being called
from another thread is the culprit, and that it happens when I'm
switching tabs in the tab view.
If I bracket my call to scrollRangeToVisible with
mConversationView.lockFocus() and .unlockFocus(), I get an exception
that alerts me that the window is deferred, and there is no window
backing it. I'm assuming (falsely?) that this has something to do with
mConversationView possibly being removed from the view hierarchy when
the NSTabView is switched away, but that's just an undereducated guess
on my part.
If I do a canDraw() and then a conditional lockFocus() and
unlockFocus(), I run into problems as well.
Anyone have any ideas?
Thanks,
Steve
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.