# JTable in JScrollPane - nach unten scrollen



## Guest (31. Jul 2008)

Hi,

ich hab hier eine JTable in einer JScrollPane:

```
JScrollPane scroll = new JScrollPane(myTable);
```

In der Tabelle stehen Werte.

Ich hätte es gerne, dass die Tabelle automatisch nach ganz unten scrollt. Nur wie mach ich das?

In SWT geht das glaub ich mit scrollbar.setvalue(scrollbar.getMaximum());

Aber mit Swing?


----------



## SlaterB (31. Jul 2008)

genauso, wenn du erstmal das JScrollPane nach einer Methode abgesucht hast, die die die ScrollBar zurückliefert


----------



## Gast (31. Jul 2008)

Ok, gefunden

```
scroll.getVerticalScrollBar().setValue(scroll.getVerticalScrollBar().getMaximum());
```

Leider funktioniert's nicht. D.h. es wird dennoch nicht nach unten gescrollt....


----------



## Guest (31. Jul 2008)

Demo die zeigt, dass es nicht funktioniert:


```
public class DemoFrame extends JFrame{
	public DemoFrame(){
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Object[][] o = new Object[][]{{"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"},
								  {"df","df","df","df","df","df"}};
		
		JTable table = new JTable(o, new Object[]{"Spalte 1","Spalte 2"});
		
		JScrollPane scroll = new JScrollPane(table);
		scroll.getVerticalScrollBar().setValue(scroll.getVerticalScrollBar().getMaximum());
		
		this.add(scroll,BorderLayout.CENTER);
		this.pack();
		this.setSize(600, 300);
		this.setVisible(true);
	}

	public static void main(String[] args) {	
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				new DemoFrame();
			}
		});
	}
}
```


----------



## SlaterB (31. Jul 2008)

ja, leider dauert es teilweise eine Weile bis die ScrollBar überhaupt die Änderung des Inhalts mitbekommt oder ähnliches,

bei folgendem funktioniert es bei mir z.B. nie, recht ähnlich deinem:

```
public class TestGUI
    extends JFrame
{

    public TestGUI()
        throws Exception
    {
        final JScrollPane sp = new JScrollPane();
        final JScrollBar sb = sp.getVerticalScrollBar();
        add(sp);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(100, 300);
        setVisible(true);

        Thread.sleep(500);
        final JPanel p = new JPanel();
        p.setPreferredSize(new Dimension(100, 1000));
        SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    sp.setViewportView(p);
                    System.out.println(sb.getMaximum());
                    sb.setValue(sb.getMaximum());
                }
            });

    }

    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }

}
```



dagegen funktioniert

```
SwingUtilities.invokeAndWait(new Runnable()
            {
                public void run()
                {
                    sp.setViewportView(p);
                }
            });

        System.out.println(sb.getMaximum());
        sb.setValue(sb.getMaximum());
```
von der main aus immer (in einer Handvoll Tests), wenn auch mit dem unschönen Effekt, dass erst Scrollbar 0 zu sehen ist und dann auf das Maximum gesprungen wird,

wichtig ist aber dass invokeAndWait() nicht vom AWT-Thread aus, z.B. nicht von einem ActionListener aus aufgerufen werden darf, 
also erst ein separater Thread gestartet werden muss, der das dann aufruft,

wie man es ganz anders richtig macht weiß vielleicht wer anders


----------



## Guest (31. Jul 2008)

SlaterB hat gesagt.:
			
		

> wie man es ganz anders richtig macht weiß vielleicht wer anders



*Das wär interessant! Also falls jemand eine Idee hat wie man das macht, bitte melden*


----------



## Marco13 (31. Jul 2008)

Na, ihr seid ja humorig  :lol: 

```
JScrollPane scroll = new JScrollPane(table);
scroll.getVerticalScrollBar().setValue(scroll.getVerticalScrollBar().getMaximum());
```
Woher soll er denn wissen, wo er hinscrollen soll? Kann ja sein, dass das ganze in einen 100000x100000 großen Frame gepackt wird, dann ist nix mit scrollen (eher im Gegenteil ???:L :autsch: :wink: ) Also, das ganze muss wohl ... sichtbar ... oder zumindest "realized" sein, damit da was passieren kann. Vielleicht passt's ja so...

```
import javax.swing.*;
import java.awt.*;

public class DemoFrame extends JFrame{

   JScrollPane scroll;

   public DemoFrame(){
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      Object[][] o = new Object[][]{{"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"},
                          {"df","df","df","df","df","df"}};

      JTable table = new JTable(o, new Object[]{"Spalte 1","Spalte 2"});

      scroll = new JScrollPane(table);

      this.add(scroll,BorderLayout.CENTER);
      this.pack();
      this.setSize(600, 300);
      this.setVisible(true);
   }

   public void doit()
   {
      scroll.getVerticalScrollBar().setValue(scroll.getVerticalScrollBar().getMaximum());
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable(){
         public void run(){
             DemoFrame df = new DemoFrame();
             df.doit();
         }
      });
   }
}
```


----------



## André Uhres (31. Jul 2008)

Oder die letzte Zeil selektieren:

```
package demo;
/*
 * TableSelectionDemo.java
 */
import javax.swing.*;
public class TableSelectionDemo extends JFrame {
    private JTable table;
    public TableSelectionDemo() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 300);
        setLocationRelativeTo(null);
        Object[][] o = new Object[25][];
        for (int row = 0; row < o.length; row++) {
            o[row] = new Object[]{"df", "df", "df", "df", "df", "df"};
        }
        table = new JTable(o, new Object[]{"Spalte 1", "Spalte 2"});
        add(new JScrollPane(table));
        table.changeSelection(table.getRowCount() - 1, 0, false, false);
    }
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableSelectionDemo().setVisible(true);
            }
        });
    }
}
```


----------



## SlaterB (31. Jul 2008)

das ist ja bisschen tricky ohne JScrollPane, wie siehts in meinem Beispiel mit einem einfachen JPanel aus? 


> Woher soll er denn wissen, wo er hinscrollen soll? Kann ja sein, dass das ganze in einen 100000x100000 großen Frame gepackt wird, dann ist nix mit scrollen 

und wo ist das Problem? dann soll ja auch nicht gescrollt werden, das läuft in jeder Auflösung perfekt, nur eben erst etwas später


----------



## André Uhres (31. Jul 2008)

SlaterB hat gesagt.:
			
		

> wie siehts in meinem Beispiel mit einem einfachen JPanel aus?


Passt nicht dazu:


			
				Anonymous hat gesagt.:
			
		

> JTable in JScrollPane - nach unten scrollen





			
				Anonymous hat gesagt.:
			
		

> ich hab hier eine JTable


----------



## Marco13 (31. Jul 2008)

Naja, ich finde das mit dem "Zeile selektieren" auch ein bißchen Fragwürdig - da wird ja der Effekt, dass eine JTable die ausgewählte Zeile sichtbar macht, irgendwie "mißbraucht" <edit>und es würde mich wundern, wennman den nicht auch irgnendwie ausschalten könnte</edit> ... wenn da schon ein SelectionListener dranhängt, macht der dann vielleicht irgendwas ungewolltes und so... also ... man muss sich schon GENAU überlegen, ob man das wirklich so machen will. 

Und @SlaterB: Es ging darum, dass "getVerticalScrollBar().getMaximum()" wohl kaum einen sinnvollen Wert liefern kann, solange man nicht die Größe der ViewportView UND die Größe der ScollPane kennt....


----------



## SlaterB (1. Aug 2008)

muss es ja auch nicht, es würde reichen, wenn es einen sinnvollen Wert liefern würde, nachdem diese Tatsachen bekannt sind,

das Problem ist aus meiner Sicht, dass die JScrollBar wie so oft in Swing  erst zeitversetzt geupdatet wird,
die Höhe des Views (getPreferredSize() ist bekannt, die des ScrollPanes sowieso (schon lange in der GUI angezeigt),

aber das ScrollPane weiß eine Weile lang nicht was es anzeigen soll oder muss durch internes Layout die bereits bekannte Höhe des Views an die ScrollBar weiterreichen und solange hat die Scrollbar den Bereich 0

edit: immer so ungenau von mir, 
ich denke auch noch, dass die Anzeige des ScrollPanes nicht so wichtig ist, es kann auch ruhig später seine Größe ändern, 
die Position der ScrollBar hängt nur von der Höhe des Views ab, die Position ist eine abstrakte Größe und wird dann zur Darstellung umgesetzt


----------

