Bonjour,
J'ai un problème de fonctionnement sur une JTable qui à la fonction de trie activée
classe MainFrame (fenêtre principale) :
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 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class MainFrame extends JFrame { private static Thread t; private Discovery objDiscovery; // **************************************************** private final JPanel sJPanel1 = new JPanel(); private final JPanel ssJPanel1 = new JPanel(); private final JPanel ssJPanel2 = new JPanel(); private JTable jTable1; private MyTableModel2 jTableModel1; private final JButton jButton1 = new JButton("Test"); MainFrame myFrame = this; // constructeur public MainFrame(){ super(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(true); initComposant(); // construction de la fenetre this.setVisible(true); this.setSize(600, 400); run_app(); // lancement des Threads } // efface le tableau private void clearTable(){ while (jTableModel1.getRowCount() != 0){ jTableModel1.removeRow(jTableModel1.getRowCount() - 1); } } // construction de la fenetre private void run_app(){ // ********************************************************************** objDiscovery = new Discovery(); objDiscovery.addStatusListener(new StatusListener(){ @Override public void infoMessageDetected(String[] messages, short type){ System.out.print("Discovery.listener"); System.out.print("Discovery.listener.add"); for (String message : messages) { System.out.print(" " + message); } //jTable1.setAutoCreateRowSorter(false); jTableModel1.addRow(messages); // ajout de la ligne //jTable1.setAutoCreateRowSorter(true); } }); // bouton clear console jButton1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { clearTable(); objDiscovery.sendDiscoveryMsg(); } }); t = new Thread(objDiscovery); t.start(); objDiscovery.sendDiscoveryMsg(); // lance une requete au demarrage } // construction de la fenetre private void initComposant(){ String[] columnNames = {"column 1", "column 2", "column 3", "column 4", "column 5", "column 6"}; Object[][] data = null; jTable1 = new JTable(new MyTableModel2(data, columnNames)); jTableModel1 = (MyTableModel2)jTable1.getModel(); // pour pouvoir utiliser l'ajout/suppression de lignes JScrollPane jScrollPane1 = new JScrollPane(jTable1); jTable1.setFillsViewportHeight(true); jTable1.setAutoCreateRowSorter(true); // pour activer la gestion de trie this.setLayout(new BorderLayout()); this.getContentPane().add(sJPanel1, BorderLayout.NORTH); this.getContentPane().add(jScrollPane1, BorderLayout.CENTER); sJPanel1.setLayout(new BorderLayout()); sJPanel1.add(ssJPanel1, BorderLayout.WEST); sJPanel1.add(ssJPanel2, BorderLayout.EAST); ssJPanel1.add(jButton1); } // initialise la Table suivant le modele private class MyTableModel2 extends DefaultTableModel { public MyTableModel2(Object[][] data, String[] columnNames) { super(data, columnNames); } @Override public boolean isCellEditable(int row, int col) { return false; } } }
classe Discovery qui envoie des infos vers la JTable pour la remplir
interface StatusListener pour la gestion d’événements
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 import javax.swing.event.EventListenerList; public final class Discovery implements Runnable { private boolean stopThread = false; // mettre volatile pour le multi-threading Integer counter = 9; boolean sendMessage = false; // constructeur public Discovery(){ super(); } // envoie le message public void sendDiscoveryMsg(){ sendMessage = true; } // reception des data // lance le thread @Override public void run(){ boolean threadOff = false; while(!threadOff){ if(sendMessage == true){ System.out.println("run.start"); String[] myStr = {"a", "b", "c", "d", "e", "f"}; myStr[0] = counter.toString(); switch(counter){ case 9: counter = 5; break; case 5: counter = 2; break; case 2: counter = 7; break; default: counter = 9; sendMessage = false; break; } sendMessage(myStr); } synchronized(this) { threadOff = this.stopThread; } } } // ferme le thread public void close(){ this.stopThread = true; System.out.println("Discovery : close"); } // *********************************************************************** // Gestion des messages console (implementation de l'interface StatusListener que j'ai créée) private final static EventListenerList listeners = new EventListenerList(); // gestion de l'ajout d'un ecouteur a liste listeners // => on peut ajouter plusieurs type de listener dans la liste (on repere leur type grace a StatusListener.class) public void addStatusListener(StatusListener listener){ listeners.add(StatusListener.class, listener); } // suppression d'un listener dans la liste public void removeStatusListener(StatusListener listener){ listeners.remove(StatusListener.class, listener); } // recupere la liste de tous les abonnés public StatusListener[] getStatusListener(){ return listeners.getListeners(StatusListener.class); } // envoie de l'evenement //protected void sendMessage(String message, short type){ protected void sendMessage(String[] messages){ System.out.print("DiscoveryMsg : send => " ); for(int i = 0; i<messages.length; i++){ if (i !=0){ System.out.print(" / "); } System.out.print(messages[i]); } System.out.println(); // fin de la ligne for(StatusListener listener : getStatusListener()) { listener.infoMessageDetected(messages, (short) 0); } } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 import java.util.EventListener; public interface StatusListener extends EventListener{ public void infoMessageDetected(String[] messages, short type); }
Lorsqu'on spam le bouton "test", tout fonctionne bien.
Mais si on appuie sur l’entête de la première colonne pour activer le tri et qu'ensuite on spam le bouton "test", on peut voir dans la console qu'il y a l'erreur suivante qui est générée :
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.DefaultRowSorter.convertRowIndexToModel(DefaultRowSorter.java:518)
at javax.swing.JTable.convertRowIndexToModel(JTable.java:2642)
at javax.swing.JTable.getValueAt(JTable.java:2717)
at javax.swing.JTable.prepareRenderer(JTable.java:5719)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
at javax.swing.JComponent._paintImmediately(JComponent.java:5167)
at javax.swing.JComponent.paintImmediately(JComponent.java:4978)
at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Remarque : dans la classe MainFrame, si j'active les deux lignes qui sont en commentaire (voir ci-dessous), il n'y a plus d'erreur généré mais le tri ne fonctionne plus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 //jTable1.setAutoCreateRowSorter(false); jTableModel1.addRow(messages); // ajout de la ligne //jTable1.setAutoCreateRowSorter(true);
Comment résoudre le problème, je ne trouve vraiment pas la solution ?
Merci d'avance
Partager