E' possibile mostrare l'ultima riga senza tutte le volte prendere in mano il mouse i tirare giù a mano lo scrollpane ?

A me interessa vedere l'ultima riga che sta in basso e purtroppo per vederla deve mettere la mano sul mouse e tutte le volte tirare GIU' la barra dello scrollpane.

Purtroppo l'applicazione viene avviata spesso e tutte le volte c'è 'sta storia di muovere a mano lo scroll per vedere l'ultima riga, invece le altre righe sopra non mi interessano mai.
(mi era venuto quasi un crampo al braccio).


Possibile mai che non c'è un comando per spostare GIU' in automatico quel cavolo di barra ?

Posto un codice di esempio.

codice:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;

public class frame1 extends JFrame {
    private JTable griglia1 = new JTable();
    private String[] testata = new String[10];
    private Object[][] oggetti = new Object[0][0];
    private JCheckBox CheckDebugTable1 = new JCheckBox("debug table 1", false);
    
    public frame1() {

        byte b1=(byte)testata.length;
        testata[0]="ID riga";
        for (byte bb=1;bb<b1;bb++) {
            testata[bb]="num "+Byte.toString(bb);
        } // next bb
        
        oggetti = new Object[Byte.MAX_VALUE][b1];
        for (byte riga=0;riga<oggetti.length;riga++) {
            byte ID=(byte)(riga+1);
            oggetti[riga][0] = Byte.toString(ID);
            for (byte colonna=1;colonna<testata.length;colonna++) {    
                oggetti[riga][colonna] = Byte.toString(colonna);
            } // next cc
        }

        griglia1=new JTable(new modello_1());
        griglia1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane barre1 = new JScrollPane(griglia1);
        barre1.setPreferredSize(new Dimension(560, 250));

        boolean AutoResize=false;
        if (AutoResize) {
            griglia1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);        
            griglia1.getColumnModel().getColumn(0).setPreferredWidth(80); // ID
            int n1=50;
            for (byte colonna=1;colonna<testata.length;colonna++) {
                griglia1.getColumnModel().getColumn(colonna).setPreferredWidth(n1);
            }
        }
    
        int NumRows=griglia1.getRowCount();
        if (NumRows > 0) {
            int TheRow=NumRows-1;
            griglia1.setRowSelectionInterval(TheRow,TheRow); //seleziona l'ultima riga ma non la mostra
        }
        
        //--- inizio qui scrivere il codice per mostrare l'ultima riga ---
        
        //--- fine qui scrivere il codice per mostrare l'ultima riga ---
        
        
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(BorderLayout.CENTER, barre1);
        this.pack();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setTitle("test JTable");
        this.setVisible(true);
    }

    
    class modello_1 extends AbstractTableModel {


        public int getColumnCount() {
            return testata.length;
        }

        public int getRowCount() {
            return oggetti.length;
        }

        public String getColumnName(int col) {
            return testata[col];
        }

        public Object getValueAt(int row, int col) {
            return oggetti[row][col];
        }

        //JTable uses this method to determine the default renderer/
        //editor for each cell.  If we didn't implement this method,
        //then the last column would contain text ("true"/"false"),
        //rather than a check box.
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        // Don't need to implement this method unless your table's
        // editable.
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            //if (col < 2) {
                return false;
            //} else {
                //return true;
            //}
        }

        // Don't need to implement this method unless your table's
        // data can change.
        public void setValueAt(Object value, int row, int col) {
            boolean sw1=CheckDebugTable1.isSelected();
            String msg="";
            if (sw1) {
                msg="Setting value at " + row + ",";
                msg=msg+col+ " to " + value;
                msg=msg+" (an instance of "+ value.getClass() + ")";
                JOptionPane.showMessageDialog(null, msg, "extends AbstractTableModel", JOptionPane.INFORMATION_MESSAGE);
            }

            oggetti[row][col] = value;
            fireTableCellUpdated(row, col);

            if (sw1) {
                printDebugData();
            }
        }

        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();
            String msg="";

            msg="New value of data:";

            for (int bb=0;bb<numRows;bb++) {
                msg=msg+"row "+bb+":";

                for (int cc=0;cc<numCols;cc++) {
                    msg=msg+""+oggetti[bb][cc]+" \n";
                }
                msg=msg+" \n";
            }
            msg=msg+"--------------------------";
            JOptionPane.showMessageDialog(null, msg, "extends AbstractTableModel", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new frame1();
            }
        });
    }
    
}