Bonjour/Bonsoir,

Je concois actuellement un petit programme de chat peer to peer en Java RMI. Le client est à la fois "client et serveur" donc.

Je rencontre un gros problème qui me bloque complètement.... étant donné que je ne sais même pas le citer (ni le stack d'ailleurs !)

Pour faire simple, à chaque fois qu'un utilisateur est connecté/se connecte, on l'ajoute dans le volet droit de mon interface graphique qui est une JList.
Ca me l'ajoute bien, c'est parfait ! Sauf que ca me met une erreur pas possible (comme je l'ai déjà dis).
Ca ne crashe pas mon programme, et ca fait bien ce que je veux... mais bon je prefere résoudre ce probleme qui me semble assez delicat plutot que de fermer les yeux dessus.


Puisque du code vaut mieux qu'un long discours, voici mon erreur :
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
 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at javax.swing.plaf.basic.BasicScrollPaneUI.paint(Unknown Source)
        at javax.swing.plaf.ComponentUI.update(Unknown Source)
        at javax.swing.JComponent.paintComponent(Unknown Source)
        at javax.swing.JComponent.paint(Unknown Source)
        at javax.swing.JComponent.paintToOffscreen(Unknown Source)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
        at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
        at javax.swing.RepaintManager.paint(Unknown Source)
        at javax.swing.JComponent._paintImmediately(Unknown Source)
        at javax.swing.JComponent.paintImmediately(Unknown Source)
        at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
        at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$000(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at javax.swing.plaf.basic.BasicScrollBarUI.layoutVScrollbar(Unknown Source)
        at javax.swing.plaf.basic.BasicScrollBarUI.layoutContainer(Unknown Source)
        at java.awt.Container.layout(Unknown Source)
        at java.awt.Container.doLayout(Unknown Source)
        at java.awt.Container.validateTree(Unknown Source)
        at java.awt.Container.validateTree(Unknown Source)
        at java.awt.Container.validate(Unknown Source)
        at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$000(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
Je suppose que ca doit se situer au niveau du thread... mais je comprends absolument pas ce qu'il se passe
Bin oui, car comme je l'ai dis, ca me met bien le nom de mon nouvel utilisateur dans mon JList... mais pour ce qui est du reste, aucune idée.

Voici le code de mes diverses classes, j'ai coupé les trucs pas important (c'est à dire ne concernant pas l'erreur, car pas appelé) :

Mon IHM :
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 
 
 
public class FenChat extends JFrame implements ActionListener
{
	/**
         * 
         */
	private static final long serialVersionUID = 4271744985869772735L;
	private JTextArea JTA_entree; // pour l'entree au clavier
	private JTextPane JP_chat; // pour les styles
	private JScrollPane JSP_scroll; // pour la barre de defilement
	private StyledDocument SD_forme; // pour la mise en forme
	Style defaut;
	private JList JL_co; // pour le volet de droite
	private JScrollPane JSP_scrollco; // pour la barre de defilement
	private Vector<String> user_co;
	private BorderLayout BL_calque;
	private JMenuBar menubar;
	private JMenu men_gene;
	private JMenu men_apropos;
	private JMenuItem it_connexion;
	private JMenuItem it_deconnexion;
	private JMenuItem it_quitter;
	private JButton JB_envoi;
 
	// La partie fonctionnelle
	private boolean is_connected;
	private Client client;
	private String entree="";
	private String receveur="";
	private String contenu="";
	private String last="";
	private int count=0;
 
 
	public FenChat()
	{
		BuildFen();
		client = new Client(this);
 
		is_connected=false;
 
 
	}
 
 
	// Methode construisant les composants présents dans la fenetre
	public  void BuildFen()
	{
		BL_calque = new BorderLayout(3, 3);
		setLayout(BL_calque);
 
 
 
		// zone d'affichage des messages
		JP_chat = new JTextPane();
		SD_forme = JP_chat.getStyledDocument();
		JP_chat.setEditable(false);
		defaut = JP_chat.getStyle("default");
 
 
 
 
		JSP_scroll = new JScrollPane(JP_chat, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
 
 
		try {
			SD_forme.insertString(SD_forme.getLength(), "Test\n", defaut);
 
		} catch (BadLocationException be) {
			be.printStackTrace();
		}
 
		add(JSP_scroll, BorderLayout.CENTER);
 
		// zone utilisateurs connectés
		JL_co = new JList();
		user_co = new Vector<String>();
		user_co.add("Test"); user_co.add("abcdef");
		JL_co.setListData(user_co);
		JSP_scrollco = new JScrollPane(JL_co);//, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		JSP_scrollco.setPreferredSize(new Dimension(100,100));
		add(JSP_scrollco, BorderLayout.EAST);
 
		// champ d'entrée de message
		JTA_entree = new JTextArea();
		BorderLayout bl = new BorderLayout(1,1);
		JPanel jp = new JPanel(bl);
		add(jp, BorderLayout.SOUTH);
		jp.add(JTA_entree, BorderLayout.CENTER);
 
		// Bouton envoi a coté
		JB_envoi = new JButton("Envoi");
		JB_envoi.setPreferredSize(new Dimension(100, 30));
		jp.add(JB_envoi, BorderLayout.EAST);
 
 
		menubar = new JMenuBar();
		men_gene = new JMenu("General");
		men_apropos = new JMenu("A propos");
		menubar.add(men_gene); 
		menubar.add(men_apropos);
		it_connexion = new JMenuItem("Connexion");
		it_deconnexion = new JMenuItem("Deconnexion");
		it_quitter = new JMenuItem("Quitter");
		men_gene.add(it_connexion);
		men_gene.add(it_deconnexion);
		men_gene.addSeparator();
		men_gene.add(it_quitter);
 
		setJMenuBar(menubar);
 
 
		// Partie ou l'on met en place tous nos listeners
		it_connexion.addActionListener(this);
		it_deconnexion.addActionListener(this);
		it_quitter.addActionListener(this);
		JB_envoi.addActionListener(this);
	}
 
	public void actionPerformed(ActionEvent e) 
	{
		String action = e.getActionCommand();
		// On clique sur le menu "Général -> Connexion"
		if(action.equals("Connexion"))
		{
			if(is_connected == false)
			{
				try {
					client.getHote().connexion();
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
				is_connected = true;
			}
			else
			{
				JOptionPane.showMessageDialog(null, "Vous êtes déjà connecté ! \n", "Erreur", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
 
	public static void main(String[] args)
	{
		SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
		    	try {
					LocateRegistry.createRegistry(4444);
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
				FenChat fenetre = new FenChat();
				fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				fenetre.setTitle("Main");
				fenetre.setPreferredSize(new Dimension(600,320));
				fenetre.pack();
				fenetre.setLocationRelativeTo(null);
				fenetre.setVisible(true);
			}
		});
 
	}
 
 
	public void majConnecte(String str)
	{
 
		user_co.add(str);
		JL_co.setListData(user_co);
 
	}
 
}
Mon client :
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
 
public class Client implements Serializable
{
 
 
	private static final long serialVersionUID = -5745502707211939900L;
	private HashMap<String, String> contact;
	private HashMap<String, String> groupe;
	private String pseudo;
	private String port;
	private String locate;
	private int idgroupe;
	private FenChat fen;
	private Hote hote;
 
 
	public Client(FenChat fen)
	{
		pseudo = "Jacquot";
		port="4444";
		contact = new HashMap<String, String>();
		groupe = new HashMap<String, String>();
		lireFichier("./src/cfg.txt"); // lit le fichier de config
		try {
			hote = new HoteImpl(this);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		this.fen = fen;
 
	}
 
	public void setConnecte(String key) 
	{
		fen.majConnecte(key);
	}
 
	public Hote getHote() {
		return hote;
	}
 
 
}
La partie "serveur" de mon client... nommé Hote :
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
 
public class HoteImpl extends UnicastRemoteObject implements Hote 
{
 
	/**
         * 
         */
	private static final long serialVersionUID = 5761334226628054873L;
	private HashMap<String, String> connecte;
	private HashMap<String, Hote> ref;
	private Client client;
	private String ps;
	private String adresse;
	private String port;
 
	public  HoteImpl(Client cli) throws RemoteException 
	{
		client = cli;
		ps = "Jacquot";
		connecte = new HashMap<String, String>();
		ref = new HashMap<String, Hote>();
	}
 
	public void connexion() 
	{
		port="";
		adresse="";
		System.out.println("my ip : "+client.getIp()+" my port : "+client.getPort()); // on recup l'ip et le port
 
		try {
			Naming.rebind("rmi://"+client.getIp()+":"+client.getPort()+"/ChatPdi", this);
 
		} catch (RemoteException e) { e.printStackTrace(); }
		  catch (MalformedURLException e) { e.printStackTrace(); }
 
 
		for (Map.Entry<String, String> e : client.getContact().entrySet())
		{  
			adresse = decoupAddr(e.getValue(), 0);
			port = decoupAddr(e.getValue(), 1);
			System.out.println("addr : "+adresse+" ; port : "+port);
			Hote hotedst = null;
			try {
				hotedst = (Hote) Naming.lookup("rmi://"+adresse+":"+port+"/ChatPdi");
			} catch (MalformedURLException me) {
				System.out.println("me");
			} catch (RemoteException re) {
				System.out.println("re");
			} catch (NotBoundException ne) {
				System.out.println("ne");
			}
 
			if(hotedst == null)
			{
				System.out.println("Aucun contact de connecté");
			}
			else
			{
				try {
					hotedst.addConnecte(client.getPseudo(), client.getIp(), this);
					addConnecte(hotedst.getClient().getPseudo(), hotedst.getClient().getIp(), hotedst);
 
				} catch (RemoteException re) {
					System.out.println("client non connecte");
				}	
			}
 
		}
 
 
	}
 
 
	public synchronized void addConnecte(String key, String value, Hote h)
	{
		System.out.println(key+" vient de se connecter");
		ref.put(key, h);
		connecte.put(key, value);
		System.out.println("size connecte : "+connecte.size()+" size ref "+ref.size());
		client.setConnecte(key);
	}
 
 
	public Client getClient()
	{
		return client;
	}
 
}
J'ai beau fouiner a droite à gauche pour voir si quelqu'un a deja eu mon erreur, les 3/4 du temps personne répond (j'espère pas que ce sera le cas ici )
Et les 1/4 du temps restant, c'est des choses ne correspondant pas du tout à mon probleme.

Donc si quelqu'un a une idée, ce serait la bienvenue, je suis dans une belle grosse impasse là :p
Merci d'avance de votre aide.

Cordialement,