web-dev-qa-db-fra.com

JTable Défilement vers un index de ligne spécifié

J'ai une table JTable dans un JScrollPane. Des lignes sont ajoutées à la table au moment de l'exécution en fonction des événements qui se produisent dans mon application. Je souhaite que le volet de défilement défile vers le bas du tableau lorsqu'une nouvelle ligne est ajoutée au tableau.

Pour JLists Il y a la [ensureIndexIsVisible][1]() qui force un index particulier de la liste à être visible. Je cherche la même chose mais pour un JTable. Il semble que je devrais peut-être déplacer manuellement la vue de défilement dans le volet de défilement, mais j’ai pensé qu’il devait exister un moyen plus simple.

45
Chris Dail

Voir cet exemple: http://www.exampledepot.com/egs/javax.swing.table/Vis.html

update: le lien est maintenant obsolète, voici le code (from http://smi-protege.stanford.edu/repos/protege/protege-core/trunk/src/edu/stanford/smi/protege/util/ ComponentUtilities.Java )

public static void scrollToVisible(JTable table, int rowIndex, int vColIndex) {
        if (!(table.getParent() instanceof JViewport)) {
            return;
        }
        JViewport viewport = (JViewport)table.getParent();

        // This rectangle is relative to the table where the
        // northwest corner of cell (0,0) is always (0,0).
        Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);

        // The location of the viewport relative to the table
        Point pt = viewport.getViewPosition();

        // Translate the cell location so that it is relative
        // to the view, assuming the northwest corner of the
        // view is (0,0)
        rect.setLocation(rect.x-pt.x, rect.y-pt.y);

        table.scrollRectToVisible(rect);

        // Scroll the area into view
        //viewport.scrollRectToVisible(rect);
    }
35
Pierre

C'est très facile, JTable a aussi la méthode scrollRectToVisible. Si vous le souhaitez, vous pouvez essayer quelque chose comme ceci pour que le panneau de défilement passe au bas de la page si un nouvel enregistrement est ajouté:

jTable1.getSelectionModel().setSelectionInterval(i, i);
jTable1.scrollRectToVisible(new Rectangle(jTable1.getCellRect(i, 0, true)));

iest le dernier enregistrement ajouté.

69
martinusadyh

JList en interne, utilisez scrollRectToVisible et spécifiez les coordonnées de défilement Je pense que vous devrez recoder une fonctionnalité similaire pour JTable.

5
Valentin Rocher

La première réponse fonctionne bien, mais la ligne sélectionnée se positionne au bas du tableau. J'ai donc créé cette version modifiée:

private void scrollToVisible(int rowIndex, int vColIndex ) {
        JTable table = getTablePanel().getTable();
        if (!(table.getParent() instanceof JViewport)) {
            return;
        }
        if (table.getRowCount()<1){
            return;
        }
        JViewport viewport = (JViewport)table.getParent();
        // view dimension
        Dimension dim = viewport.getExtentSize();
        // cell dimension
        Dimension dimOne = new Dimension(0,0);

        // This rectangle is relative to the table where the
        // northwest corner of cell (0,0) is always (0,0).
        Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
        Rectangle rectOne;
        if (rowIndex+1<table.getRowCount()) {
            if (vColIndex+1<table.getColumnCount())
                vColIndex++;
            rectOne = table.getCellRect(rowIndex+1, vColIndex, true);
            dimOne.width=rectOne.x-rect.x;
            dimOne.height=rectOne.y-rect.y;
        }

        // '+ veiw dimension - cell dimension' to set first selected row on the top

        rect.setLocation(rect.x+dim.width-dimOne.width, rect.y+dim.height-dimOne.height);

        table.scrollRectToVisible(rect);
    }

Maintenant, la ligne sélectionnée se positionne en haut de la table.

1
MGaidamak

Il me semble beaucoup plus facile de définir la position de la fenêtre d'affichage au lieu de faire défiler le tableau. Voici mon code.

public void scrollCellToView(int rowIndex, int vColIndex) {
    if (!(this.getParent() instanceof JViewport)) {
        return;
    }
    JViewport viewport = (JViewport) this.getParent();
    Rectangle rect = this.getCellRect(rowIndex, vColIndex, true);
    Rectangle viewRect = viewport.getViewRect();

    int x = viewRect.x;
    int y = viewRect.y;

    if (rect.x >= viewRect.x && rect.x <= (viewRect.x + viewRect.width - rect.width)){

    } else if (rect.x < viewRect.x){
        x = rect.x;
    } else if (rect.x > (viewRect.x + viewRect.width - rect.width)) {
        x = rect.x - viewRect.width + rect.width;
    }

    if (rect.y >= viewRect.y && rect.y <= (viewRect.y + viewRect.height - rect.height)){

    } else if (rect.y < viewRect.y){
        y = rect.y;
    } else if (rect.y > (viewRect.y + viewRect.height - rect.height)){
        y = rect.y - viewRect.height + rect.height;
    }

    viewport.setViewPosition(new Point(x,y));
}
0
user3015208