RSS
 

Archive for janvier, 2007

Grid Eclipse Nebula Widget

31 jan

The Eclipse Nebula sub-project present the Grid widget, an alpha version which works great, i use it in my application to administrate reservation of swimming course. The JFace layer is not implemented yet but it’s on rails. But I don’t know if a GridViewer will be very useful because the needs of a spreadsheet are very large.

This is an example of Grid with header of columns and rows, column grouping, expand/collapse event of group column. The objective is to show the schedules in columns and the week days in rows, each column is composed of 3 sub-columns showing the total capacity, the availability and the sold place. The total capacity column can be desactivated :

public Grid createGrid(List in_schedules, Composite in_composite) {
        // Grid creation
        Grid l_grid = new Grid(in_composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        // show column header
        l_grid.setHeaderVisible(true);
        // show row header
        l_grid.setRowHeaderVisible(true);
        // enable cell selection
        l_grid.setCellSelectionEnabled(true);
        GC l_gc = new GC(l_grid);
        // list of swimming course schedules
        for (ScheduleType l_scheduleType : in_schedules) {
            // create column group with dynamic column (TOGGLE)
            GridColumnGroup l_scheduleColumn = new GridColumnGroup(l_grid, SWT.TOGGLE);
            // column group header name
            l_scheduleColumn.setText(l_scheduleType.getLabel());
            final int l_colWidth = l_gc.stringExtent(l_scheduleType.getLabel() + " <<").x + 6;
            // initialize state (collapse)
            l_scheduleColumn.setExpanded(false);
            // listen expand event
            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);
                    }
                }
            });
            // listen collapse event
            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;
            }
            // create columns group
            GridColumn l_capacity = new GridColumn(l_scheduleColumn, SWT.CENTER);
            l_capacity.setText("C");
            l_capacity.setWidth(20);
            l_capacity.setCellSelectionEnabled(false);
            // collapsed ? no
            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);
            // collapsed ? yes
            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;
    }

The Grid binding is realise via the GridItem object

// GridItem creation
l_gridItem = new GridItem(l_grid, SWT.CENTER);
// row header name
l_gridItem.setHeaderText(l_headerText);
// set value by index column
l_gridItem.setText(, );

It possible to merge cell of a same line e.g.:
e.g.:

l_gridItem.setColumnSpan(0, in_grid.getColumnCount());

And to get the selection :

Point[] l_selections = l_grid.getCellSelection();
for (Point l_selection : l_selections) {
	// get GridItem
	l_grid.getItem(l_selection.y);
	// get GridColumn
	l_grid.getColumn(l_selection.x)
}

  • Share/Bookmark
 
2 Comments

Posted in Eclipse

 

Grid Eclipse Nebula widget

31 jan

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(List in_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)
}

  • Share/Bookmark
 
Commentaires fermés

Posted in Eclipse

 

RIA en mode déconnecté

17 jan

Dans cet article David Van Couvering présente une solution pour développer une application RIA en mode déconnecté, l’idée est de stocker les évènements dans une base locale en mode déconnecté et synchroniser le tout lorsque l’application repasse en mode connecté. J’ai étudié cela mais mon approche était différente et se concentrait plus sur le mode de synchronisation avec des structures de bases différentes pour des applications d’entreprises. L’approche présentée dans l’article convient pour des petites applications personnelles (PIM), mais pour des applications plus complexes il faut aller plus loin.

  • Share/Bookmark
 
Commentaires fermés

Posted in RIA-RDA-RWA

 

Disconnected RIA

17 jan

In this article David Van Couvering present a solution to develop a disconnected Rich Internet Application, the idea is to record events in a local storage in the disconnected mode and synchronize all when application come back in the connected mode. I study this but my approach was different and more concentrated on the synchronisation between heterogeneous database structure for enterprise application. The presented approach in the article is correct for PIM application but for more sophisticated application it need improvements.

  • Share/Bookmark
 
Commentaires fermés

Posted in RIA-RDA-RWA

 

Desktop framework

16 jan

Quel framework pour le développement d’application orientée desktop ? c’est la question posée sur ce forum. Les réponses montrent la faible offre actuelle et aucun framework ne s’impose pour l’instant. Voici une première liste exhaustive avec quelques commentaires :

  • XUI : grande compatibilité (Swing, SWT, AWT, HTML) peut être trop, conception XML, data binding, on y trouve tous ce que l’on doit attendre d’un tel framework.
  • Wazaabi : déjà présenté
  • Monoi : orienté pour Eclipse RCP, axé dans un premier temps sur un data binding simple, devrait évoluer avec un format XML de conception et une bibliothèque de composants
  • Swing Application Framework et Beans Binding : les 2 JSR de Sun sur le sujet, on attend les premières implémentations
  • Genesis : plutôt orienté binding, pas de conception XML mais une appoche orientée aspect et annotations.

On voit déjà que se dégage 2 approches l’une ou XML est au centre l’autre avec les annotations. Ces framework se doivent d’offrir une API de binding, une bibliothèque de composants, une API de gestion de l’évenementiel, une conception XML de l’UI. Microsoft et Macromedia ont déjà misés sur cette approche de manière propriétaire. Microsoft avec XAML qui est au centre du processus de développement avec d’un coté les Expression tools pour les designer et de l’autre Visual Studio pour les dévelopeurs. Et de même Macromedia Flex avec MXML et Flex Builder pour le développement.

  • Share/Bookmark
 
 

Desktop framework

16 jan

What framework for desktop application development ? it’s this forum question. The answers show there’s not a lot of solutions and no leader framework. This is an exhaustive list :

  • XUI : big compatibility (Swing, SWT, AWT, HTML) maybe too much, XML conception, data binding, there’s what we need in such framewrk
  • Wazaabi : c.f. article
  • Monoi : for Eclipse RCP, axed in first time on data binding, should evolved with an XML format for GUI conception and a widgets library
  • Swing Application Framework et Beans Binding : the 2 JSR from Sun on this subject, we wait for the first implementations
  • Genesis : a binding framework, no XML conception but an approach with acpect and annotations concept

We already see 2 approach, in one hand with XML in another hand annotations. This frameworks must offer an API binding, a widget library, an event management library, an XML conception of the UI. Microsoft and Macromedia already use the XML concept in a proprieratary way. Microsoft with XAML in the center of the development process with Expression tools for designer and Visual Studio for developers. The same for Macromedia Flex with MXML and the Flex Builder development tool.

  • Share/Bookmark
 
Commentaires fermés

Posted in RIA-RDA-RWA

 

Cayenne in the Apache incubator

14 jan

Cayenne is now an Apache top level project. This ORM framework inspired of Apple EOF is a serious Hibernate concurrent and is best approach for desktop application. EOF architecture which is in Cayenne is robust, if the community grow this project could be the first Hibernate concurrent. The 3.0 implement the JPA specification.

  • Share/Bookmark
 
1 Comment

Posted in Java

 

Cayenne dans l’incubator d’Apache

14 jan

Cayenne devient un top level project d’Apache. Ce framework d’ORM inspiré d’EOF d’Apple n’a rien à envier à Hibernate et est surement mieux adapté pour les applications orientées desktop. L’architecture d’EOF que l’on retrouve dans Cayenne a déjà montré ses preuves, si la communauté s’agrandit ce framework peut devenir un serieux concurrent d’Hibernate. La version 3.0 actuellement en alpha implémentera JPA.

  • Share/Bookmark
 
4 Comments

Posted in Java

 

Remote editing

13 jan

A trick for remote file edition using RSE (Remote System Explorer) from DSDP (Device Software Development Platform Target Management) project.

  • Share/Bookmark
 
Commentaires fermés

Posted in Eclipse

 

Editer des fichiers à distance

13 jan

Une astuce pour éditer ses fichiers sur un serveur distant en utilisant RSE (Remote System Explorer) du projet DSDP (Device Software Development Platform Target Management).

  • Share/Bookmark
 
Commentaires fermés

Posted in Eclipse