2009-03-17 6 views
0

J'utilise GlazedLists pour générer automatiquement un EventTableModel à partir d'une EventList, pour une utilisation avec un JTable dans un JScrollbarPane. J'utilise la EventList comme FIFO, un tas d'éléments sont ajoutés à la fin, puis un tas d'éléments sont parfois supprimés du début. Lorsque les éléments sont supprimés, la sélection fonctionne exactement comme je l'espère: même si l'index de la sélection a changé, les mêmes éléments sont sélectionnés (ou au moins ceux qui sont encore dans la table). C'est bien.garder la sélection JTable dans viewport

De toute évidence, si les objets changent d'index en raison de la suppression d'éléments au début, il est impossible de conserver à la fenêtre une plage fixe d'objets et une plage d'index fixe. Le comportement par défaut semble être de garder la fenêtre d'affichage identique.

Si je voulais conserver les objets sélectionnés au même endroit dans la fenêtre, y a-t-il un moyen de le faire? (par exemple, configurer un écouteur d'événement sur le EventTableModel ou le JScrollbarPane ou quelque chose, et calculer le réglage de la barre de défilement droite de sorte que lorsque je supprime des éléments, la fenêtre se déplace avec les objets?)

Répondre

1

une méthode sur JComponent qui est utilisé par JViewport qui fait le défilement réel lorsque vous utilisez les arrowkeys dans un jtable

public void scrollRectToVisible(Rectangle aRect) 

cette façon, vous auriez pas besoin d'ajuster les barres de défilement, mais vous pouvez spécifiquement indiquer ce rect devrait être visible. Pourrait inclure un calcul basé sur le nombre de lignes et la hauteur en pixels d'une seule ligne. Vous pouvez également mettre un point d'arrêt dans cette méthode et vérifier comment cela fonctionne lorsque vous déplacez avec les touches fléchées via un Jtable

0

Une autre façon d'afficher la première ligne sélectionnée dans une JTable à l'intérieur d'un ScrollPane est de définir manuellement ce que la barre de défilement verticale montre:

Donc d'abord, obtenez la première rangée sélectionnée dans le tableau. Si plusieurs lignes sont sélectionnées, la première ligne sera tout de même sélectionnée.

int firstSelectedRow = table.getSelectedRow(); 

Ensuite, obtenez où (la coordonnée y) la ligne sélectionnée est située dans la table.

Rectangle cellLocation = table.getCellRect(firstSelectedRow, 0, false); 

Enfin, nous pouvons dire à la barre de défilement verticale où être.

scrollPane.getVerticalScrollBar().setValue(cellLocation.y); 

De plus, s'il n'y a pas de lignes sélectionnées, cela aura la fenêtre affiche le haut de la table.

Je préfère utiliser la méthode scrollRectToVisible(), mais pour une raison quelconque, cela ne fonctionnait pas pour moi et cela semble fonctionner à chaque fois.

0

Voici une autre solution ne dépendant que de la table. Cette solution préserve également la position y de la ligne sélectionnée dans la nouvelle vue.

D'abord, nous voulons conserver la vue pré-mise à jour et rectangles sélection

Rectangle preUpdateViewRect = table.getVisibleRect(); 
Rectangle preUpdateSelectedCellRect = table.getCellRect(table.getSelectedRow(), 1, true); 

Après la mise à jour, vérifiez si notre sélection était dans la vue. Cette vérification vérifie que si un utilisateur sélectionne une ligne et commence à défiler, nous n'allumons pas la vue à la sélection.Si la sélection était à notre avis, faites quelques calculs simples pour créer le rectangle qui a la sélection au même endroit dans notre vue.

if(preUpdateViewRect != null && preUpdateViewRect.contains(preUpdateSelectedCellRect)) 
{ 
    Rectangle postUpadteSelectedCellRect = table.getCellRect(table.getSelectedRow(), 1, true); 
    int newViewPortY = postUpdateSelectedCellRect.y - (preUpdateSelectedCellRect.y - preUpdateViewRect.y); 
    Rectangle newViewRect = new Rectangle(preUpdateViewRect.x, newViewPortY , preUpdateViewRect.width, preUpdateViewRect.height); 
    table.scrollRectToVisible(newViewRect); 
}