[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Newsgroup Home]
|
[news.eclipse.newcomer] Re: Getting scroll pane to display bottom of text (using Swing)
|
In article <memo.20051026224403.3280A@xxxxxxxxxxxxxxxxxxxxx>,
eclipse@xxxxxxxxx (Peter Toye) wrote:
> *From:* eclipse@xxxxxxxxx (Peter Toye)
> *Date:* Wed, 26 Oct 2005 22:44 +0100 (BST)
>
> In article <memo.20051024144938.2600A@xxxxxxxxxxxxxxxxxxxxx>,
> eclipse@xxxxxxxxx (Peter Toye) wrote:
>
> > *From:* eclipse@xxxxxxxxx (Peter Toye)
> > *Date:* Mon, 24 Oct 2005 14:49 +0100 (BST)
> >
> > In article <djimkv$9c8$1@xxxxxxxxxxxxxxxx>, yaofahua@xxxxxxxxxxx
> > (JACK YAO) wrote:
> >
> > > *From:* JACK YAO <yaofahua@xxxxxxxxxxx>
> > > *Date:* Mon, 24 Oct 2005 21:12:59 +0800
> > >
> > > Peter Toye wrote:
> > > > In article <dj86ss$pj6$1@xxxxxxxxxxxxxxxx>, yaofahua@xxxxxxxxxxx
> > > > (JACK YAO) wrote:
> > > >
> > > >> public class test extends JFrame implements ActionListener {
> > > >> JTextArea ta = new JTextArea(10, 10);
> > > >> int i = 0;
> > > >> JPanel p = new JPanel();
> > > >> JScrollPane sp = new JScrollPane(ta);
> > > >> public test() {
> > > >> p.add(sp);
> > > >> JButton btn = new JButton("test");
> > > >> btn.addActionListener(this);
> > > >> p.add(btn, BorderLayout.NORTH);
> > > >> this.add(p);
> > > >> pack();
> > > >> setVisible(true);
> > > >> }
> > > >> public void actionPerformed(ActionEvent e) {
> > > >> new AddThread().start();
> > > >> }
> > > >> class AddThread extends Thread {
> > > >> public void run() {
> > > >> for (int i = 0; i < 100; i++) {
> > > >> ta.append("line :" + i + "\n");
> > > >> //JScrollBar sb = sp.getVerticalScrollBar();
> > > >> //sb.setValue(sb.getMaximum());
> > > >> try {
> > > >> Thread.sleep(100);
> > > >> } catch (InterruptedException e) {
> > > >> e.printStackTrace();
> > > >> }
> > > >> }
> > > >> }
> > > >> }
> > > >> public static void main(String[] args) {
> > > >> new test();
> > > >> }
> > > >> }
> > > > Jack,
> > > >
> > > > I've tried your program now, but modified it to append more than
> > > > one line. When you comment out the lines the slider bar stays at
> > > > the top. When you don't, last appended line isn't visible.
> > > >
> > > > I'm obviously going to have to experiment more with my program,
> > > > and learn about threading.
> > > >
> > > > On a wider point, this seems to be an issue which makes Swing
> > > > difficult to use - why isn't the obvious behaviour of the slider
> > > > bar on append made a default?
> > > >
> > > > Peter
> > > Peter, did you solve your problem ? I change the for loop to :
> > > //**************************************************************
> > > for(int i=0;i<100;i++) {
> > > System.out.println(sb.getMaximum());//1
> > >
> > > ta.append("line :" + i + "\n");
> > > sleep(500);
> > > System.out.println(sb.getMaximum());//2
> > >
> > > ta.append("line :" + i + "\n");
> > > sleep(500);
> > > System.out.println(sb.getMaximum());//3
> > >
> > > ta.append("line :" + i + "\n");
> > > sleep(500);
> > > System.out.println(sb.getMaximum());//4
> > > }
> > > //***************************************************************
> > > To my surprise, 3 4 which are the last two append are the same
> > > value. I think this test has no thread factor.
> > > --
> > >
> > > JACK YAO, Beijing, China
> > >
> > Jack,
> >
> > This is what I used for my test with threading. I found that the
> > slider doesn't go all the way down to the bottom after the multi-line
> > append. I think that I may bring this up as a Java bug report, but as
> > a newbie I wanted to be sure that it wasn't just me.
> >
> > Peter
> >
> > class AddThread extends Thread {
> > public void run() {
> > for (int i = 0; i < 10; i++) {
> > ta.append("Start of append\n");
> > ta.append("line :" + i + "\n");
> > ta.append("End of append\n");
> > JScrollBar sb = sp.getVerticalScrollBar();
> > sb.setValue(sb.getMaximum());
> > try {
> > Thread.sleep(1000);
> > } catch (InterruptedException e) {
> > e.printStackTrace();
> > }
> > }
> > }
> > }
> >
> >
> A further comment - if I put a delay before the sb.setValue statement
> it updates the scroll bar OK.
>
> I suspect the problem is that the screen updating (and calculation of
> the size of the scrollbar) is done on a separate thread from the
> program, and the program gets the old value. I shall experiment using
> the invokeLater swing call to see if it will single-thread the app and
> give the expected result. I still think it's a Java bug that it doesn't
> happen automatically.
>
> Peter
>
I now think I've worked it out. When you call a separate thread explicitly
the screen updating and program threads don't synchronise and it goes
wrong. If I put the loop into an invokeLater thread it works fine.
You have to be careful to make sure that this thread doesn't use any
variables which are likely to be changed by the main program, as there's
no synchronisation between the two (unless you program it in yourself).
The program below shows what happens if you don't get it right - the line
number is always 10 as the program goes through the loop before the
subthread is started.
Thanks a lot for all your help and advice.
Peter
int i;
public void actionPerformed(ActionEvent e) {
btn.setEnabled(false);
for (i=0; i<10; i++) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
ta.append("Start append\n");
ta.append("Continue append\n");
ta.append("line :" + i+ "\n");
ta.append("Keep on appending\n");
ta.append("End append\n");
// JScrollBar sb = sp.getVerticalScrollBar();
// sb.setValue(sb.getMaximum());
btn.setEnabled(true);
}
});
}
}