# [JAVA] SWT - Window



## dmo95 (15 Février 2009)

Bonjour à tous,

Voilà mon problème, j'implémente deux fenêtres particulières qui héritent toutes deux d'une classe Window. Je suis sous Eclipse et je n'arrive pas à trouver mon erreur, même avec les fonctionnalité puissante d'Eclipse.

Je vous propose un petit diagramme :





​Code des différentes classes, classe Window :

```
public Window() {
        this.setDisplay(new Display());
        this.setShell(new Shell(SWT.MODELESS | SWT.CLOSE | SWT.MIN));
    }
```

Code de la classe WPresentation :

```
public WPresentation() {
        super();
        this.setMyLabel(new Label(this.getShell(), SWT.CENTER));
        this.setMyLabel2(new Label(this.getShell(), SWT.CENTER));
        this.myLabel = new Label(getShell(), SWT.CENTER);
        this.setInitButton(new Button(this.getShell(),SWT.PUSH ));
        this.setLaunchButton(new Button(this.getShell(),SWT.PUSH));
    }
```

Code de la classe WPreparation :

```
public WPreparation() {
        // TODO Auto-generated constructor stub
        super();
        
        this.setMyLabel(new Label(this.getShell(), SWT.LEFT));
        this.setForm(new Group(this.getShell(), SWT.NONE));
        this.setLabelType(new Label(this.getForm(), SWT.LEFT));
        this.setChooseType(new Combo(this.getForm(), SWT.LEFT));
        this.setLabelGame(new Label(this.getForm(), SWT.LEFT));
        this.setChooseGame(new Combo(this.getForm(), SWT.LEFT));    
        this.setLabelPlayer1(new Label(this.getForm(), SWT.LEFT));
        this.setPlayer1(new Text(this.getForm(), SWT.LEFT | SWT.BORDER));
        this.setLabelPlayer2(new Label(this.getForm(), SWT.LEFT));
        this.setPlayer2(new Text(this.getForm(), SWT.LEFT | SWT.BORDER));
        this.setValidateButton(new Button(this.getShell(),SWT.PUSH | SWT.FLAT));
    }
```
Mon code main est le suivant :

```
WPresentation wPresentation = new WPresentation();
        wPresentation.init();
        
        WPreparation wPreparation = new WPreparation();
        wPreparation.init();
        
        //Ouverture du Shell
        wPresentation.getShell().open();
...
```

L'application plante sur le deuxième new. Indépendamment l'une de l'autre, chacune des fenêtres fonctionnent. Par ailleurs, si j'inverse les deux créations, le même scénario ce produit, l'application plante. L'erreur je ne la connait pas le seul message que Eclipse me fournit est le suivant :

<arrêté, valeur d'exit : 1>/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/bin/java (15 févr. 2009 17:01:31)

Je ne comprend pas grand chose... cela fait 2 ans que je n'ai pas fait de Java. Je pense qu'il s'agit juste d'un problème conceptuel....

PS : Lorsque je dis que l'application plante, l'icône se lance dans le dock et se referme directement, tous ce qu'il y a de plus logique puisque les instructions sont au début du main.

PS2 : Si il manque des infos, n'hésitez pas !

Merci à vous


----------



## tatouille (15 Février 2009)

comprend rien a ton code pour tes classes ne sont pas extend de Panel

et ou est le controller?


----------



## grumff (16 Février 2009)

Tu dis que ça te sort pas plus d'infos que ça, mais pourtant tu dis savoir à quelle ligne ça plante, alors t'as une exception sur la sortie d'erreur ? T'as passé en debug ? Ou tu l'as fait à l'ancienne avec des println (qui s'ils sont fait sur la sortie standard sont bufferisés et peuvent ne pas s'afficher même s'ils sont intervenus avant l'erreur, et dans ce cas les points de suspension à la fin du programme c'est pas top, on aimerait savoir ce qu'il y a).


----------



## dmo95 (16 Février 2009)

En fait, Display et Shell sont des attributs de Window, or je fais deux new des classes qui en héritent. Il se créé donc 2 instances de Display et de Shell, mais je pense qu'il ne peut y avoir deux instances de Display...


----------



## Lapin Masqué (16 Février 2009)

En effet le Display est le lien entre Java et les couches plus basses de SWT et qu'il n'accepte la plupart du temps une seule instance à la fois, sauf si celle ci à été disposée. (dispose())

Source : http://www.jdocs.com/swt/3.2/org/eclipse/swt/widgets/Display.html


----------



## dmo95 (16 Février 2009)

Merci pour les réponses. J'ai d'autres problèmes, mais je vais tenter de les résoudre par moi même...

Juste une dernière question, j'ai constaté que les PNG ne sont pas correctement pris en compte sous Windows, notamment la transparence... Sous mac le rendu est du plus bel effet sous Windows XP, une belle M****. Comment cela se fait il ? Les comportements devraient être identique puisqu'il y a la JVM ?!?

Également une autre quéstion purement Eclipse... Je cherche désespérément de voir mes erreurs, plus particulièrement les erreurs en cours d'exécution (runtime errors), vous savez celle du type NullPointerException ou ArrayOutOfBoundException   Impossible de les trouver, je suis sur la dernière version d'Eclipse Ganymede 3.4.1 me semble-t-il... J'ai vu quelque part qu'il fallait afficher la vue Problems, mais rien... nothing !!! Un expert Eclipse dans les parages ?

Merci


----------



## Lapin Masqué (16 Février 2009)

Salut à toi,

Etrangement j'arrive a reproduire ton problème et il semble que cela vient de SWT.

Quand je lance une fonction main basique avec :


```
public static void main(String[] args) {
	String string = null;
	System.out.println(string.charAt(1));
}
```

Il me jette avec un NullPointerException (Normal c'est ce que je veux).

Mais si j'ajoute swt.jar (téléchargé chez eclipse) dans mon Build Path, il jette plus. Il n'affiche rien mais n'a pas l'air de lancer l'Exception. 
Il jette pas plus en Debug.

Etrange, je vais potasser un peu et voir ce que ça donne.

EDIT : Il semble que j'aie trouvé.

En fait SWT semble rediriger le flux des erreurs vers son propre flux, ce qui fait que les erreurs ne sont plus affichées dans la console.

La parade que j'ai trouvé pour le moment est de rerediriger ce flux vers la sortie "standard" comme ceci :


```
System.setErr(System.err)
```

Et là il me jette correctement =D


----------



## dmo95 (17 Février 2009)

Ah oui, moi ça ne fonctionne pas, je ne doit probablement pas l'insérer au bon endroit ?! Je l'ai tout simplement mis dans le code du main...


```
public class Test {

    public static void main(String[] arg) {
        System.setErr(System.err);
        String s = null;
        System.out.println("Hello");
        System.out.println(s.charAt(1));
    }

}
```
Cela ne m'affiche rien... enfin juste Hello...

Dans un second temps, j'ai un autre problème que j'ai tout bonnement codé sur un exemple simple pour l'illustrer. J'ouvre un shell à partir d'un événement sur un bouton dans le shell principal, le shell ouvert se ferme suite à un clique sur un bouton dans ce même shell, puis je souhaite le réouvrir par la suite dans la fenêtre mère. You got it ?

Voici le code :

```
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;

public class Test {

    public static void main(String[] arg) {
        
        
        Display.setAppName("AppMenu"); // sets name in Dock
        Display display = new Display();
    
        Shell shell = new Shell(display);
        final Shell shell2 = new Shell(display);
        shell.setText("Main Window");
        shell2.setText("Sous fenetre");
        
        Button button = new Button(shell, SWT.PUSH | SWT.FLAT);
        button.setText("Ouvrir");
        button.setBounds(10,10, 100, 30);
        
        Button button2 = new Button(shell2, SWT.FLAT);
        button2.setText("Fermer");
        button2.setToolTipText("Vous allez fermer la fenètre !!");
        button2.setBounds(10,10, 100, 30);
        
        button.addListener(SWT.MouseUp,  new Listener() {
            public void handleEvent(Event e) {
                // TODO Auto-generated method stub
                shell2.open();
                shell2.forceFocus();
            }
        });
        
        button2.addListener(SWT.MouseUp,  new Listener() {
            public void handleEvent(Event e) {
                // TODO Auto-generated method stub
                shell2.close();
            }
        });
        
        
        shell.open();
        while (!shell.isDisposed())
            if (!display.readAndDispatch())
                display.sleep();
    
        display.dispose();
    }
}
```
Le problème c'est qu'a la seconde ouverture, l'application crash... Un problème conceptuel que je n'ai pas du saisir... 

Par ailleurs, il y a quelque chose qui m'échappe lorsque je souhaite ajouter un bouton, je fais les étapes suivantes :


création (new Button)
initilisation du nom (setText)
placement (setBounds)
Sans la dernière étape, le bouton ne s'affiche pas, normal ?

Merci de votre aide


----------



## dmo95 (18 Février 2009)

Une idée ? Up !?


----------



## Lapin Masqué (18 Février 2009)

Pour le premier problème j'ai plus d'idées désolé (Regardes du côté de la vue "Errors" histoire de voir si c'est pas le workspace qui se plante, au pire réinstalles Eclipse)

Pour le prob SWT essaies d'utiliser Shell.setVisible(true/false) au lieu de open() / close().


----------



## dmo95 (18 Février 2009)

Merci, je ne sais pas pourquoi je n'y ai pas pensé par moi même !! Effectivement, cela apporte le comportement escompté. Ceci dit cela ne me donne pas la réponse au problème... mais bon le principal est que ca fonctionne 

Edit : Seul petit quak, lorsque l'utilisateur utilise la croix rouge système pour fermer la fenêtre, au quel cas il s'agit d'un équivalent a close()... Et la nouvelle tentative d'ouvertur fait planter le programme... Quelque chose m'échappe ?!? Une autre idée ?


----------

