IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Agents de placement/Fenêtres Java Discussion :

Pattern singleton sur une JFrame


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 26
    Points : 22
    Points
    22
    Par défaut Pattern singleton sur une JFrame
    Bonjour à tous,
    Je suis sur un projet tout simple, je fais une appli qui, sur une interface graphique, affiche un nombre tiré au hasard. L'utilisateur définit la borne supérieure, les détails de ce tirage au sort ne sont pas intéressants pour cette discussion, tout fonctionne très bien, sachez juste que la fenêtre contient un générateur qui tire des nombres aléatoires et jamais deux fois le même.
    En revanche, je dois pouvoir cacher la fenêtre à l'aide d'un bouton (la réduire, ou mieux la faire disparaître), et la faire revenir de préférence en exécutant de nouveau le programme.

    Du coup, j'ai utilisé le pattern Singleton afin de n'avoir qu'une unique instance de fenêtre, qui sera appelée par le lanceur du programme. Mon problème est que ça n'a absolument pas l'effet escompté: la fenêtre cachée est toujours ne cours d'exécution mais le lanceur génère néanmoins une nouvelle fenêtre.

    Je fournis le code ci-après :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
     
    public class LotoUI extends JFrame{
     
    	private static final long serialVersionUID = 1L;	//Pour l'extension de JFrame
     
    	private Generateur g;	//Le générateur de nombre aléatoire
     
    	final JLabel nombre;	//Le nombre affiché dans la JFrame
    	final JTextArea tBorne;	//La borne maximum, renseignée par l'utilisateur
     
    	// Classe privée contenant l'instance unique (pattern singleton)
    	private static class LotoUIHolder
    	{	
    		/** Instance unique non préinitialisée */
    		private final static LotoUI instance = new LotoUI();
    	}
     
    	/** Point d'accès pour l'instance unique du singleton */
    	public static LotoUI getInstance()
    	{
    		return LotoUIHolder.instance;
    	}
     
    	private LotoUI()
    	{
    	//Initialisation des variables de classe
    		g=new Generateur();
     
    	//Paramètres de la fenêtre
    		this.setName("Jeu de loterie");
    		this.setSize(1300,650);
    		this.setDefaultCloseOperation(LotoUI.DISPOSE_ON_CLOSE);
    		this.setUndecorated(true);
     
    	//Définition des éléments à ajouter
    	    JLabel lBorne=new JLabel("Borne supérieure :");
    	    tBorne= new JTextArea("100",1,6);
    	    tBorne.setEditable(true);
    	    tBorne.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    	    JScrollPane scrollPane = new JScrollPane(tBorne);
    	    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    	    nombre=new JLabel(" ");
    	    nombre.setPreferredSize(new Dimension(1000,1000));
    	    Font font = new Font("Arial",Font.BOLD,300);
    	    nombre.setFont(font);
     
    	//Boutons :
                JButton lancer = new JButton("Lancer");
    	    JButton hide = new JButton("Poursuivre");
    	    JButton quit = new JButton("Quitter");
     
    	//Placement des éléments dans une grille
    		JPanel monPanel= new JPanel();
    		monPanel.setLayout(new GridBagLayout());
    		GridBagConstraints gbc = new GridBagConstraints();		
    		gbc.insets = new Insets(9, 8, 0, 10);
    		gbc.anchor = GridBagConstraints.BASELINE;
    		gbc.gridx = 0;
    	    gbc.gridy = 0;
    	    gbc.weightx=0;		
    		monPanel.add(lBorne,gbc);
     
    		gbc.fill = GridBagConstraints.VERTICAL;
    		gbc.gridx = 2;
    	    gbc.gridy = 0;
    	    gbc.gridheight = 1;
    	    gbc.weightx=100000000;
    		monPanel.add(tBorne,gbc);
     
    		gbc.gridx = 5;
    	    gbc.gridy = 0;
    	    gbc.gridheight = 1;
    		monPanel.add(lancer,gbc);
     
    		gbc.gridx = 7;
    	    gbc.gridy = 0;
    	    gbc.gridheight = 1;
    		monPanel.add(quit,gbc);
     
    		gbc.gridx = 4;
    	    gbc.gridy = 0;
    	    gbc.gridheight = 1;
    		monPanel.add(hide,gbc);
     
    		gbc.gridx = 4;
    	    gbc.gridy = 6;
    	    gbc.gridheight = 100;
    	    gbc.weighty=0.5;
    	    gbc.ipady = 0;
    		monPanel.add(nombre,gbc);
     
    		Color maCouleur = new Color((float)0.2,(float)0.6,1.F,1.F);
     
    		monPanel.setBackground(maCouleur);
     
    	    this.add(monPanel);
     
    	    quit.addActionListener(new ActionListener(){
    		    public void actionPerformed(ActionEvent event){
    		    	System.exit(0);
    		      }
    	    });
     
    	    lancer.addActionListener(new ActionListener(){
    		    public void actionPerformed(ActionEvent event){		    	
    		    	new Thread(new Runnable() {
    		    	      public void run() {
    		    	        anime();
    		    	        SwingUtilities.invokeLater(new Runnable() {
    		    	          public void run() {
    		    	        	  int tmp=g.joue(Integer.parseInt(tBorne.getText()));
    		    	        	  if(tmp!=-1)
    		    	        		  nombre.setText(Integer.toString(tmp));
    		    	        	  else
    		    	        		  nombre.setText("Fin !");
    		    	          }
    		    	        });
    		    	      }
    		    	  }).start();	    	
    		      }
    	    });
     
    // Ici, le bouton qui cache la fenêtre
    	    hide.addActionListener(new ActionListener(){
    	    	public void actionPerformed(ActionEvent event){
    	    		LotoUI.getInstance().setVisible(false);
    	    	}
    	    });
    	}
     
    	// Cette méthode sert juste à animer le tirage au sort
    	private void anime()
    	{
    		int i=0;
        	for(i=0;i<70;i++)
        	{
        		nombre.setText(Integer.toString(g.tire(Integer.parseInt(tBorne.getText()))));
        		//repaint();
        		try{
        			Thread.sleep(60);
        		}catch(InterruptedException e){}
        	}
    	}
    }
    et le code du lanceur au cas où :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class Lanceur {
     
    	public static void main(String[] args) {
     
    		LotoUI fenetre = LotoUI.getInstance();
    		fenetre.setVisible(true);
    	}
    }
    Comme vous le voyez, ce n'est pas le singleton basique que tout le monde connait avec un if(instance==null) tout simplement car j'avais fais ainsi avant et ça ne fonctionnait pas, j'ai donc prit exemple ici.

    J'ai pensé résoudre le problème en "bricolant" une sauvegarde (genre XML qui contiendrait la borne sup et les nombres déjà tirés) avant fermeture du programme mais d'une part c'est bien plus lourd, d'autre part ça me parait moins bien adapté. Sans compter qu'il faudrait que je me mette au XML ;-)

    Si vous avez des idées n'hésitez pas, merci.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il n'y absolument aucun partage d'instance naturel entre deux sessions d'éxécution d'une même application : ton singleton est valable, mais à l'intérieur d'une même session d'éxécution.

    Il y a plusieurs manières de "partager" des objets entre sessions applicatives. Le fait de sauvegarder les informations dans un fichier (xml, ou properties, ou n'importe quel autre format) ne te permettra de résoudre le problème qu'entre 2 sessions consécutives, mais non concurrente (et uniquement pour la valeur de borne, pas pour l'instance de fenêtre). Pour résoudre le problème entre 2 sessions concurrentes, un moyen simple est d'utiliser une socket. Le lanceur teste si la socket est déjà ouverte (en écoute) : si oui, il envoie un signal sur la socket pour indiquer qu'on demande un nouveau lancement (et arrête immédiatement l'exécution), sinon il ouvre la socket, et créé le singleton. Lorsque la socket reçoit le signal, elle rend visible la fenêtre/singleton.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    D'accord, je craignais que ce soit un problème de session d'exécution. Zut. Les socket, c'est quoi exactement? La dernière fois que j'en ai entendu parler c'était en réseau...

    A priori du coup je vais effectivement partir sur mon idée de sauvegarde en fichier XML (avec des exécutions non concurrentes bien sûr, le bouton "hide" ne cachera plus la fenêtre mais sauvegardera, le bouton "quit" réinitialisera le fichier de sauvegarde).

    Merci beaucoup pour ta réponse rapide, je ne suis pas déçu de m'être inscrit ici. =)

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Canartitude Voir le message
    D'accord, je craignais que ce soit un problème de session d'exécution. Zut. Les socket, c'est quoi exactement? La dernière fois que j'en ai entendu parler c'était en réseau...
    Les sockets sont un moyen de communiquer entre 2 ports (un en écoute, un en écriture) : s'ils sont ouverts sur 2 machines différentes, ils permettent effectivement de communiquer sur un réseau. Mais rien n'empêche 2 applications différentes sur une même machine de communiquer ensemble par ce moyen, ou même 2 instances de la même application de communiquer ainsi, voire même une instance d'application de communiquer avec elle-même (bon c'est se compliquer la vie dans la plupart des cas, mais parfois ça peut servir).
    Pour un cas comme le tiens, un simple DatagramSocket peut suffire.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Entendu, les tutos sont en effet quasi-systématiquement basés sur de la communication entre plusieurs machines. Ca ne m'a pas l'air tellement moins lourd à mettre en place que le XML, je pense donc m'orienter sur le XML quand même, après tout il faut en avoir fait au moins une fois. Et puis j'ai jamais aimé les protocoles de communication, déjà en programmation système alors en réseau...

    Merci beaucoup pour ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Image de fond sur une JFrame et dans une JToolBar
    Par FredPsy dans le forum Agents de placement/Fenêtres
    Réponses: 9
    Dernier message: 01/02/2007, 18h12
  2. Réponses: 8
    Dernier message: 30/09/2006, 05h18
  3. [débutant]Afficher une image sur une JFrame
    Par mavina dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 09/08/2006, 16h25
  4. [AWT] JFrame - Mettre une taille minimum sur une Jframe
    Par rabobsky dans le forum Agents de placement/Fenêtres
    Réponses: 12
    Dernier message: 27/07/2005, 18h20
  5. [Icon] logo sur une JFrame
    Par ibou2610 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 30/07/2004, 10h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo