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.
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);
}
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)));
Oùiest le dernier enregistrement ajouté.
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.
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.
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));
}