Programmation Java Desktop à l'aide de SWT

1- Introduction

Ce document est basé sur:
  • Eclipse 4.6, 47 (NEON, OXYGEN)

Dans ce document, je vais vous présenter la programmation de l'application Desktop avec  SWT.

La question de savoir est que dans Java quel choix de technologie peuvent programmer l'application Desktop, ou quelles technogies ont capable de programmer une application web qui possède l'interface similaire de celle de l'application Desktop.

Voir plus à:

2- RCP (Rich Client Platform)

RCP (Rich Client Platform) - est une plate-forme (Platform) basée sur SWT, sert à programmer des applications Desktop et plus loin elle a contruit une plate- forme qui vous permet de développer des applications de style  Desktop comme  Workbench, comme  Eclipse IDE, ou ou les programmeurs peuvent intégrer le plugin à  Eclipse IDE.

Mais même si vous voulez utiliser SWT pour programmer, et ne voulez pas utiliser ce qui sont fournit par RCP vous pouvez également créer une application RCP.

SWT:

Workbench Application:

Afin de créer une application Desktop en utilisant SWT. Sur Eclipse nous pouvons créer un projet  RCP Plugin. Vous avez deux choix.
  • N'utilisez que les fonctions de SWT
  • L'utilisation la plate-forme fournite par l'application RCP afin de programmer RCP Workbench.
Dans ce document, je vais vous guider pour vous familiariser avec la programmation de base SWT, en utilisant WindowBuilder pour faire glisser et déposer des composants dans l'interface.

3- Les réglages requis avant le démarrage

Certains réglages requis avant de commencer:

Vous avez besoin de la dernière version d' Eclipse. Il existe actuellement Eclipse 4.7 (Codes OXYGEN).
À mon avis, vous devez télécharger le progiciel: " Eclipse IDE for Java EE Developers". Le seul nombre différent est le nombre de plugins, dans le but de différentes programmations. Vous pouvez installer des plugins supplémentaires à d'autres fins si vous le souhaitez.
L'installation du plugin Win. Il s'agit d'un plugin qui vous permet de concevoir des applications GUI SWT en utilisant la commodité de glisser-déposer.
Voir les instructions d'installation à l'adresse suivante:

4- Quelques concepts de SWT.

4.1- Display & Shell

La classe  Display et la classe  Shell sont des composants clés de l'application  SWT.

- org.eclipse.swt.widgets.Shell représet une fenêtre (Window)

- org.eclipse.swt.widgets.Display est responsable de gérer des boucles d'événements( event loops), des polices, des couleurs et pour contrôler la communication entre processus dans l'interface utilisateur (UI Thread) et d'autres processus (other Thread). Display est la base de toutes les capacités SWT.

Chaque application  SWT exige au moinss un  Display et un/ plusieurs objects  Sell​​​​​​​.
Exemple:
Display display = new Display();
Shell shell = new Shell(display);
shell.open();

// run the event loop as long as the window is open
while (!shell.isDisposed()) {
   // read the next OS event queue and transfer it to a SWT event
 if (!display.readAndDispatch())
  {
 // if there are currently no other OS event to process
 // sleep until the next OS event is available
   display.sleep();
  }
}

// disposes all associated windows and their components
display.dispose();

4.2- SWT Widgets

Les  SWT widget sont installés dans des progiciels  org.eclipse.swt.widgets et  org.eclipse.swt.custom. Ces  widget s'étendent de la classe  Widget ou  Control. Certains widget sont décrits dans le shéma ci- dessous.
Ce shéma est la capture de l'écran de  SWT widget homepage.

5- Créer le projet RCP Plugin Project

Dans Eclipse, sélectionnez :
  • File/New/Other...
  • Donc, il n'est pas nécessaire de créer une application Workbench, donc nous ne pouvons pas vous enregistrer (1) comme indiqué ci-dessous
  • ​​​​​​​Sélectionnez Yes dans la région (2) pour qu' Eclipse crée RCP Application (Exécuter sur Desktop), sinon elle créera une RAP application (Exécution sur le Web).
Le projet est créé:
Ajoutez la bibliothèque swt:  org.eclipse.swt

Si vous développez l'application RAP, la bibliothèque correspondante est org.eclipse.rap.rwt

6- Le premier exemple

C'est un exemple simple qui n'utilise pas les outils glisser- déplacer  WindowBuilder.
HelloSWT.java
package org.o7planning.tutorial.swt.helloswt;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class HelloSWT {

  public static void main(String[] args) {
      // Create Display
      Display display = new Display();
      // Create Shell (Window) from diplay
      Shell shell = new Shell(display);

      shell.open();

      while (!shell.isDisposed()) {
          if (!display.readAndDispatch())
              display.sleep();
      }
      display.dispose();
  }
}
Cliquez sur le bouton droit de la classe  HelloSWT.java et sélectionnez  Run As/Java Application.
Résutat de l'exécution de l'exemple:

7- L'utilisation WindowBuilder

Ensuite, nous allons créer un exemple de glisser et déplacer sur  WindowBuilder.
  • File/New/Other ..
C'est la fenêtre de la conception de WindowBuilder. Il vous permet de glisser et de déposer les Widgets facilement.
You can watch the video below:

8- SWT Widget

8.1- Vue ensemble

C'est la hiérarchie des  Widget disponibles dans  SWT.
Vous pouvez voir le démo (demo) des  Control dans le lien suivant, c'est  RWT Control,  mais ils sont essentiellement les mêmes que le  SWT control.

Demo:

8.2- Des Widget peuvent contenir d'autres Widget (Container)

8.3- Des Controls

9- SWT Layout

9.1- Qu'est ce que Layout?

Pour simplifier,  Layout est la manière d'arranger les composants sur l'interface.
Les  Layout standard de la bibliothèque  SWT sont:
  • FillLayout – Définit des Widgets de même taille dans une seule ligne ou colonne
  • RowLayout – Présente des Widgets dans une ligne ou des lignes, avec des options de remplissage (Fill), enveloppement (Wrap) et espacement (Espace).
  • GridLayout – Présente des Widgets dans une grille

9.2- Exemple en ligne

Ceci est un exemple en ligne, vous permettant de voir comment l'exercice de Layout.
  • TODO Link?

9.3- FillLayout

FillLayout est une classe  layout simple. Il met des widgets dans une seule ligne ou une seule colonne, ce qui les oblige à avoir la même taille. Initialement, les widgets seront tous aussi grands que les  widget les plus hauts, et aussi large que les plus larges. FillLayout ne s'enveloppe (wrap) pas, et vous ne pouvez pas spécifier de marges (margin) ou d'espacement (space).

FillLayout fillLayout = new FillLayout();
fillLayout.type = SWT.VERTICAL;
shell.setLayout(fillLayout);
                                                                                                                       Initial                                                              Après le redimensionnement                                   
fillLayout.type = SWT.HORIZONTAL
(par défaut)
fillLayout.type = SWT.VERTICAL
Video:
 
 
FillLayoutExample.java
package org.o7planning.tutorial.swt.layout;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class FillLayoutExample {

  public static void main(String[] args) {
      Display display = new Display();
      final Shell shell = new Shell(display);
      shell.setLayout(new FillLayout());

      //
      Composite parent = new Composite(shell, SWT.NONE);
     
      FillLayout fillLayout= new FillLayout();
      fillLayout.type= SWT.VERTICAL;
     
      parent.setLayout(fillLayout);

      Button b1 = new Button(parent, SWT.NONE);
      b1.setText("B1");

      Button b2 = new Button(parent, SWT.NONE);
      b2.setText("B2");

      Button button3 = new Button(parent, SWT.NONE);
      button3.setText("Button 3");
     
      // Windows back to natural size.
      shell.pack();
      //
      shell.open();
      while (!shell.isDisposed()) {
          if (!display.readAndDispatch())
              display.sleep();
      }
      // tear down the SWT window
      display.dispose();
  }
}
Résultat de l'exécution:

9.4- RowLayout

RowLayout est plus couramment utilisé que FillLayout en raison de sa capacité à envelopper( wrap), et parce qu'il fournit des margin et des spacing. RowLayout possède plusieurs champs (field) de configuration. En outre, la hauteur et la largeur de chaque widget dans un RowLayout peuvent être spécifiées en définissant un objet RowData dans le widget en utilisant setLayoutData.

The field configuration:

Wrap, Pack, Justify:

Initial Après le redimensionnement
wrap = true
pack = true
justify = false
 
(Par défaut)
wrap = false
 
(Découpe si pas assez d'espace)
pack = false
 
(Tous les widgets ont la même taille)
justify = true
 
(Les widgets sont répartis sur l'espace disponible)

MarginLeft, MarginTop, MarginRight, MarginBottom, Spacing:

Ces champs (field) contrôlent le nombre de pixels (Pixel) entre les widgets (space - espacement) et le nombre de pixels entre un widget et le côté de la Composite principale (margin - marge). Par défaut, RowLayouts laisse 3 pixels pour la marge (margin) et l'espacement (space). Les champs de marge et d'espacement sont affichés dans le diagramme suivant.
Video:
 

9.5- GridLayout

GridLayout est le plus utile et le plus puissant des Layout standard, mais c'est aussi le plus compliqué. Avec un GridLayout, les widgets d'un Composite sont disposés dans une grille. GridLayout possède un certain nombre de champs de configuration et, comme RowLayout, les widgets que RowLayout contient peuvent avoir un objet de données de mise en page associé, appelé GridData. Le pouvoir de GridLayout réside dans la capacité de configurer GridData pour chaque widget contrôlé par GridLayout.

Les configurations de GridLayout:

  • NumColumns
  • MakeColumnsEqualWidth

Video GridLayout:

9.6- StackLayout

Ce Layout empile tous les Widgets l'un sur l'autre et les redimensionne pour avoir la même taille et du même emplacement. Le contrôle spécifié dans topControl est visible et tous les autres contrôles ne sont pas visibles. Les utilisateurs doivent définir la valeur topControl puis appeller la méthode  layout() sur le composite qui contient StackLayout.

Video StackLayout:

 

9.7- Combiner des Layout

Au-dessus, nous nous sommes familiarisés avec des Layout standard. La combinaison entre des Layout différents et l'autres conteneurs ( Composite, TabFolder, SashForm, ...) créera l'interface souhaitée.
  • TODO

10- Écrire la classe étendue à partir du widget de SWT

Parfois, vous devez écrire une classe à partir de la classe de widgets disponibles de SWT. Il est parfaitement normal, mais il y a une petite remarque, il faut passer outre à la méthode checkSubclass() sans avoir à faire quoi que ce soit dans cette méthode.
MyButton.java
package org.o7planning.tutorial.swt.swtsubclass;

import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;

public class MyButton extends Button {

   public MyButton(Composite parent, int style) {
       super(parent, style);
   }

   // You have to override this method.
   @Override
   protected void checkSubclass() {
       // No need to do anything.
   }

   
}

11- Des interfaces de composants modulaires

Dans le cas où vous avez conçu une interface complexe. Le fractionnement des conceptions est nécessaire et ensuite de metre ensemble, ce sera plus facile si vous concevez sur WindowBuilder.

Consultez l'interface suivante, et nous essaierons de la diviser.
Supposons que vous souhaitez concevoir une interface comme l'illustration ci-dessous. (Il n'est pas compliqué de diviser la conception, mais c'est un exemple pour illustrer comment diviser la conception de l'interface)
Nous pouvons concevoir deux composites séparés et le greffer sur MainComposite.

TopComposite

  • File/New/Other...
Concevoir l'interface pour  TopComposite.
TopComposite.java
package org.o7planning.tutorial.swt.module;

import org.eclipse.swt.widgets.Composite;

public class TopComposite extends Composite {
  private Text text;

  /**
   * Create the composite.
   * @param parent
   * @param style
   */
  public TopComposite(Composite parent, int style) {
      super(parent, style);
      setLayout(new FillLayout(SWT.HORIZONTAL));
     
      Composite composite = new Composite(this, SWT.NONE);
      composite.setLayout(new GridLayout(1, false));
     
      Button btnPreferredSite = new Button(composite, SWT.CHECK);
      btnPreferredSite.setText("Preferred Site");
     
      Label lblColumnWidth = new Label(composite, SWT.NONE);
      lblColumnWidth.setText("Column width");
     
      text = new Text(composite, SWT.BORDER);
      text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

  }

  @Override
  protected void checkSubclass() {
  }
}

BottomComposite

De la même manière, créez la classe BottomComposite:
Concevoir l'interface pour  BottomComposite:
BottomComposite.java
package org.o7planning.tutorial.swt.module;

import org.eclipse.swt.SWT;

public class BottomComposite extends Composite {
  private Text text;

  /**
   * Create the composite.
   * @param parent
   * @param style
   */
  public BottomComposite(Composite parent, int style) {
      super(parent, style);
      setLayout(new FillLayout(SWT.HORIZONTAL));
     
      Composite composite = new Composite(this, SWT.NONE);
      composite.setLayout(new GridLayout(1, false));
     
      Composite composite_1 = new Composite(composite, SWT.NONE);
      GridLayout gl_composite_1 = new GridLayout(3, false);
      gl_composite_1.marginHeight = 0;
      gl_composite_1.marginWidth = 0;
      composite_1.setLayout(gl_composite_1);
      composite_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
     
      Button btnNewButton = new Button(composite_1, SWT.NONE);
      btnNewButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
      btnNewButton.setText("Add");
     
      Button btnNewButton_1 = new Button(composite_1, SWT.NONE);
      btnNewButton_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
      btnNewButton_1.setText("Delete");
     
      Button btnNewButton_2 = new Button(composite_1, SWT.NONE);
      btnNewButton_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
      btnNewButton_2.setText("Clear");
     
      text = new Text(composite, SWT.BORDER | SWT.MULTI);
      text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

  }

  @Override
  protected void checkSubclass() {
      // Disable the check that prevents subclassing of SWT components
  }

}

MainComposite

Similairement, créez la classe  MainComposite:

Enregistrez-vous TopComposite & BottomComposite sur Palette

Cliquez sur le bouton droit de  Palette et sélectionnez  Add category...
Baptisé  Pallete Category:
  • My Composite
Cliquez sur le bouton droit de Pallette Category "My Composite" pour ajouter  TopComposite & BottomComposite.
De la même facon, ajoutez  BottomComposite au catalogue  My Composite.
Maintenant  TopComposite & BottomComposite sont facilement glissés et déplacés dans des autres  Composite.
MainComposite.java
package org.o7planning.tutorial.swt.module;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;

public class MainComposite extends Composite {

  /**
   * Create the composite.
   * @param parent
   * @param style
   */
  public MainComposite(Composite parent, int style) {
      super(parent, style);
      setLayout(new FillLayout(SWT.HORIZONTAL));
     
      Composite composite = new Composite(this, SWT.NONE);
      composite.setLayout(new GridLayout(1, false));
     
      TopComposite topComposite = new TopComposite(composite, SWT.BORDER);
      topComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
     
      BottomComposite bottomComposite = new BottomComposite(composite, SWT.BORDER);
      bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

  }

  @Override
  protected void checkSubclass() {
  }

}

12- L'utilisation des gestionnaires d'événements

La gestion des événements SWT est très simple avec le support de WindowBuilder.

Des exemples:

  • File/New/Other...
  • Package: org.o7planning.tutorial.swt.event1
  • Name: ButtonEventDemo
Cliquez sur le bouton droit du  Button, sélectionnez  "Add event handler", une série des événementss de  Button sera affichée.
WindowBuilder va automatiquement générer le  code pour vous:
btnClickToMe.addSelectionListener(new SelectionAdapter() {
    @Override
    public void widgetSelected(SelectionEvent e) {
        // Sử lý sự kiện Button được chọn tại đây.
        System.out.println("Button selected!");
    }
});
ButtonEventDemo.java
package org.o7planning.tutorial.swt.event1;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class ButtonEventDemo {

  protected Shell shlButtonEventDemo;

  public static void main(String[] args) {
      try {
          ButtonEventDemo window = new ButtonEventDemo();
          window.open();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  public void open() {
      Display display = Display.getDefault();
      createContents();
      shlButtonEventDemo.open();
      shlButtonEventDemo.layout();
      while (!shlButtonEventDemo.isDisposed()) {
          if (!display.readAndDispatch()) {
              display.sleep();
          }
      }
  }

  protected void createContents() {
      shlButtonEventDemo = new Shell();
      shlButtonEventDemo.setSize(296, 205);
      shlButtonEventDemo.setText("Button Event Demo");
      shlButtonEventDemo.setLayout(new RowLayout(SWT.HORIZONTAL));

      Button btnClickToMe = new Button(shlButtonEventDemo, SWT.NONE);
      btnClickToMe.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
              // Handle Button selected here!
              System.out.println("Button selected!");
          }
      });
      btnClickToMe.setText("Click to me");

  }

}

13- JFace

Vous pouvez voir plus de  JFace, une  API supplémentaire pour   SWT: