Le sous-projet Nebula d’Eclipse propose un composant tableur (Grid), pour une version alpha ce composant est déjà plutôt stable, je l’ai utilisé sans problèmes pour gérer les réservations de séances de cours de natation pour l’école de voile de La Flotte (CNPA). Il manque une couche JFace pour faciliter son utilisation et permettre une meilleure intégration avec le modèle, mais c’est en cours. Cependant je ne sais pas si un GridViewer sera trés utile car les besoins d’un tableur dans une application sont trés divers.
Ci-dessous un exemple de creation de Grid, avec entête de colonnes et de lignes, groupe de colonnes, gestion des évènements de réduction/extension des groupes de colonnes. Le but est d’afficher les horaires en colonne et les jours de la semaine en ligne. Chaque colonne est composée de 3 sous colonnes affichant la capacité totale de la séance, les places disponibles et les places vendues. La capacité totale étant la colonne désactivable :
public Grid createGrid(Listin_schedules, Composite in_composite) { // creation de la Grid Grid l_grid = new Grid(in_composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); // affichage de l'entête des colonnes l_grid.setHeaderVisible(true); // affichage de l'entête des lignes l_grid.setRowHeaderVisible(true); // activation de la sélection cellule par cellule l_grid.setCellSelectionEnabled(true); GC l_gc = new GC(l_grid); // parcours des horaires de natation for (ScheduleType l_scheduleType : in_schedules) { // creation d'un groupe de colonnes avec affichages dynamique des colonnes (TOGGLE) GridColumnGroup l_scheduleColumn = new GridColumnGroup(l_grid, SWT.TOGGLE); // nom de l'entete du groupe de colonne l_scheduleColumn.setText(l_scheduleType.getLabel()); final int l_colWidth = l_gc.stringExtent(l_scheduleType.getLabel() + " <<").x + 6; // initialisation de l'état de l'affichage (non étendu) l_scheduleColumn.setExpanded(false); // écoute de l'évènement d'extension l_scheduleColumn.addListener(SWT.Expand, new Listener() { public void handleEvent(Event event) { int l_width = l_colWidth / 3; if (l_width < 20) { l_width = 20; } for (GridColumn l_column : ((GridColumnGroup) event.widget).getColumns()) { l_column.setWidth(l_width); } } }); // écoute de l'évènement de reduction l_scheduleColumn.addListener(SWT.Collapse, new Listener() { public void handleEvent(Event event) { int l_width = l_colWidth / 2; if (l_width < 20) { l_width = 20; } for (GridColumn l_column : ((GridColumnGroup) event.widget).getColumns()) { if (l_column.isSummary()) { l_column.setWidth(l_width); } } } }); int l_width = l_colWidth / 2; if (l_width < 20) { l_width = 20; } // création des colonnes du groupe GridColumn l_capacity = new GridColumn(l_scheduleColumn, SWT.CENTER); l_capacity.setText("C"); l_capacity.setWidth(20); l_capacity.setCellSelectionEnabled(false); // affichage en mode réduit ? non l_capacity.setSummary(false); l_capacity = new GridColumn(l_scheduleColumn, SWT.CENTER); l_capacity.setText("V"); l_capacity.setWidth(l_width); l_capacity.setCellSelectionEnabled(false); // affichage en mode réduit ? oui l_capacity.setSummary(true); l_capacity = new GridColumn(l_scheduleColumn, SWT.CENTER); l_capacity.setText("L"); l_capacity.setWidth(l_width); l_capacity.setSummary(true); l_capacity.setData(l_scheduleType); } l_gc.dispose(); //l_grid.pack(true); return l_grid; }
Le peuplement de la Grid se fait en utilisant des GridItem
// création d'un GridItem l_gridItem = new GridItem(l_grid, SWT.CENTER); // nommage de l'entête de ligne l_gridItem.setHeaderText(l_headerText); // affectation d'une valeur à une colonne en utilisant l'index de celle-ci l_gridItem.setText(, );
Il est possible de fusionner les cellulles d'une même ligne
e.g.:
l_gridItem.setColumnSpan(0, in_grid.getColumnCount());
Et enfin pour récupérer la sélection :
Point[] l_selections = l_grid.getCellSelection();
for (Point l_selection : l_selections) {
// récupération du GridItem
l_grid.getItem(l_selection.y);
// récupération de la GridColumn
l_grid.getColumn(l_selection.x)
}

