Article View: borland.public.jbuilder.java.swing
Article #8946Re: Redirecting System.in
From: Jeroen Zwartepoorte
Date: Wed, 14 Jun 2000 00:00
Date: Wed, 14 Jun 2000 00:00
105 lines
5236 bytes
5236 bytes
"John P. McGrath" <JPMcGrath@fast.net> wrote in message
news:MPG.13b0e12eea71f5b29899c5@forums.borland.com...
> On Tue, 13 Jun 2000 15:54:51 +0200, Jeroen Zwartepoorte wrote:
>
> > I'm trying to have System.in point to a JTextArea instead of
> > the command prompt. To accomplish this, i've written my own
> > InputStream class. The class works partly: System.in.read()
> > does return character typed in the JTextArea, but when i
> > use BufferedReader.readLine(), the method never returns
> > (System.in.read() DOES return '\n' characters).
>
> You do not show the code that points System.in to your input stream
> object or the code creates the buffered reader. My guess is that your
> problem is with this code. If you post it, I will take a look.
That code is very simple:
System.setOut(new Pl0PrintStream(textArea));
System.setIn(new Pl0InputStream(textArea));
BufferedReader creation is also trivial:
String sTest = new BufferedReader(new
InputStreamReader(System.in)).readLine();
> I have a few other comments:
>
> You use a stack to buffer the characters that have been read. If someone
> were to quickly type "ABC" before any of the characters were read, the
> input stream would return "C", "B", "A" in that order. I think you
> should be using a queue rather than a stack.
Hmm, i must have been sleeping while writing that code. Stack uses LIFO and
i want FIFO. Thanks!
> You synchronize the code that adds a character to your buffer, but not
> the code that removes a character from the buffer. I don't believe this
> will help if you do not do it in both places.
Why not? If i make sure that when i add something to the Queue, i'm the only
thread currently accessing that Object, then there is no reason to add
another synchronized in the read() method?!
> The synchronization will probably not cause a problem as written, since
> you are using a Stack, which extends Vector, which is synchronized. But
> if you change this to a queue of some kind, the synchronization will be
> important.
>
> Your code currently polls in the read() method, waiting for a character
> to be added to the buffer. A better approach would use wait() and
> notify(). Information on using wait/notify is available at the following
> URL. Note that the URL is too long to fit on a line, so clicking on it
> will not work.
>
> http://java.sun.com/docs/books/tutorial/essential/
> threads/waitAndNotify.html
I haven't read the document (yet), but the jdk docs state that read() should
block until there is something to return. That's why i've added the
Thread.sleep method. You do have a valid point about dead-locking: the
read() method is currently called from a non-AWT thread, so i'm safe here.
> Regardless of how you synchronize the threads, you will run into a
> problem if someone calls your read() method from the AWT event dispatch
> thread. If the buffer is empty, it will block waiting for a character to
> be added to the buffer, but that can only happen in your KeyListener,
> which will run on the event dispatch thread. So it cannot happen until
> your read returns. You would have a deadlock. You may want to add a
> safeguard like the following:
>
> if ( EventQueue.isDispatchThread() ) {
> throw new IOException(
> "Pl0InputStream.read() called from event dispatch thread" );
> }
>
> You require a JTextArea as the input component, but I do not see anything
> that would require that specific component. You could change this to a
> JTextComponent and make it a little more general.
>
> Have you considered how your component / input stream will behave if
> someone tries to back up using the arrow keys and edit the text in the
> text component. I am not sure how you will be using the text component,
> but my guess is that it will not behave as you would like. You may want
> to consider catching just the ENTER key, and then stuffing the current
> line into the input buffer. That would allow the user to edit the input
> and to repeat previous lines.
I thought about this, but the only solution that comes to mind is to write a
highly customized version of JTextArea (or write my own Document class)
which limits where you can input the text. Since it's only a small project,
i don't think this makes sense. Maybe i'll try some hack like you described
above, but for now i'm more interested in getting the InputStream to
actually work :)
> I hope this helps.
>
> --
> John P. McGrath
> <JPMcGrath@fast.net>
> <jpm@nscs.fast.net>
Thanks!
Jeroen
Technical Details
Message-ID:
<8i7tuh$msd7@bornews.borland.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<8i5dnc$j27@bornews.borland.com> <MPG.13b0e12eea71f5b29899c5@forums.borland.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,ed9d203ce9e9692c X-Google-Attributes: gid111d45,public From: "Jeroen Zwartepoorte" <Jeroen@xs4all.nl> Subject: Re: Redirecting System.in Date: 2000/06/14 Message-ID: <8i7tuh$msd7@bornews.borland.com> X-Deja-AN: 634412969 References: <8i5dnc$j27@bornews.borland.com> <MPG.13b0e12eea71f5b29899c5@forums.borland.com> X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 Organization: Another Netscape Collabra Server User X-MSMail-Priority: Normal Newsgroups: borland.public.jbuilder.java.swing