ERLEDIGT
JA
JA
ANTWORTEN
5
5
ZUGRIFFE
595
595
EMPFEHLEN
-
Hallo mal wieder =)
Vorgeschichte:
Ich programmiere an einem recht großen Programm und habe dort bisher eine JTable eingesetzt ohne Probleme. Jedoch passt eine JList wesentlich besser in das Konzept und ist auch einfacher zu handhaben. Deshalb hab ich das Programm nun auf eine JList umgestellt.
Problem:
Das Problem ist nicht 100%ig reproduzierbar, deshalb muss man den angehängten Code eventuell mehrmals starten, bis man das Verhalten sieht.
Die JList, wird erzeugt und enthält auch alle Elemente, an der Konsolenausgabe zu erkennen. Es wird auch angezeigt, dass die Jlist sichtbar ist, aber das ist sie nicht immer.
Nach dem starten des Programms sieht man entweder die Liste, oder nix, manchmal sieht man sie auch kurz aufflackern. Fehler werden soweit keine geworfen, bzw. konnte ich nirgends einen Protokollieren.
Ich gehe stark davon aus, dass es etwas mit den 2 Threads, die an der JList arbeiten zu tun hat. Jedenfalls weißt das Verhalten und Unregelmässigkeit stark darauf hin.
Normalerweise wäre ja ein InvokeLater oder ähnliches angebracht, nur Arbeite ich ja nicht mit der Liste an sich, sondern nur mit dem Model.
Jegliche in/re/validate und repaints, sind rein spekulativ, falls es ein repaint Problem wäre.
Zusätzlich: Packt man die JList in die JScrollPane, sieht man sie eigentlich so gut wie nie.
Quelltext:
Eine zu Testzwecken erstellte Version, welche nur das Verhalten der Gui simuliert und nicht den Aufbau des original Codes komplett wiederspiegelt
Code java: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
import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import java.awt.Rectangle; import javax.swing.BoxLayout; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; class Runner extends Thread { private DefaultListModel dlm; private JList list; private boolean begin; public Runner(JList list, DefaultListModel bigData) { this.dlm = bigData; this.list = list; this.begin = true; } public void run() { while(true) { if(begin) { int i = 0; while(i < 3) { dlm.addElement(new JLabel("<html>"+i+"<br />BB<a href=\"mailto:CC\">CC</a></html>")); ++i; } list.validate(); begin = false; } else { System.out.println("Thread Slave - Showing: "+list.isShowing()+" Vissible: "+list.isVisible()+" Valide: "+list.isValid()); System.out.println("Thread Slave - Groesse Model: "+dlm.size()); System.out.println("Thread Slave - Groesse Liste: "+list.getModel().getSize()); //do something else; } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Listtester { public static void main(String [] args) { JFrame f = new JFrame(); f.setSize(600,600); Container cp = new Container() { private static final long serialVersionUID = 1L; public void paint(Graphics g) { g.setColor(this.getBackground()); g.fillRect(0, 0, this.getWidth(), this.getHeight()); super.paint(g); } }; JPanel pcp = new JPanel(); JPanel pm = new JPanel(); DefaultListModel dlm = new DefaultListModel(); JList list = new JList(dlm); DefaultListCellRenderer r = new DefaultListCellRenderer() { private static final long serialVersionUID = 1L; public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setComponentOrientation(list.getComponentOrientation()); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } if (value instanceof Icon ) { setIcon((Icon)value); setText(""); } else if(value instanceof JLabel) { setIcon(((JLabel) value).getIcon()); setText(((JLabel) value).getText()); } else { setIcon(null); setText((value == null) ? "Kein Inhalt" : value.toString()); } setEnabled(list.isEnabled()); setFont(list.getFont()); return this; } }; list.setCellRenderer(r); list.setOpaque(false); Rectangle rec = new Rectangle(0,0,f.getWidth()/2,f.getHeight()/2); cp.setLayout(null); cp.setBounds(rec); cp.setBackground(Color.green); pcp.setLayout(null); pcp.setBounds(rec); pcp.setOpaque(false); pm.setLayout(new BoxLayout(pm,BoxLayout.Y_AXIS)); pm.setOpaque(false); pm.setBounds(rec); pcp.add(pm); cp.add(pcp); f.setContentPane(cp); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pm.removeAll(); new Runner(list, dlm).start(); //JScrollPane jsp = new JScrollPane(list); //jsp.setOpaque(false); //jsp.getViewport().setOpaque(false); //pm.add(jsp); pm.add(list); cp.validate(); f.repaint(); while(true) { System.out.println("Thread Main - Showing: "+list.isShowing()+" Vissible: "+list.isVisible()+" Valide: "+list.isValid()); System.out.println("Thread Main - Groesse Model: "+dlm.size()); System.out.println("Thread Main - Groesse Liste: "+list.getModel().getSize()); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }
http://larrywayn.pytalhost.eu xD
Friss zeurst, sonst wirst du gefressen.
-
Naja... mitm Model zu arbeiten und von zwei Orten gleichzeitig reinzuschreiben und zu lesen ist so auch nicht gerade sicherer, als wenn du direkt an der Liste rumbasten würdest...
Ich nehme doch an, dass du den invokeLater() auch ausprobiert hast? - Obwohl es sicher schöner wäre das ganze Model Thread-safe zu machen. Dazu gibts ziemlich viel Literatur und früher oder später kommt man nicht drum rum, sowas hier zu lesen.Wandering in Greyhawk...
-
Der Hauptthread arbeitet ja nicht mehr mit der JList, der startet nur das ganze GUI und die anderen Klassen/Threads übernehmen das Datenbeschaffen.
Aber ich denke, auch wenn es in einem Thread bliebe, liefe es ja trotzdem seperat in 2 Threads( Anzeige und Main).
thread safety ist mir schon klar, race condition, synchronized und co.
Deshalb wird ja auch nur in einem Thread einmalig am anfang in das Model geschrieben
Das InvokeLater hab ich bisher nicht ausprobiert, aus dem Grund, weil dann alle Variablen immer final sein müssen, dass immer etwas nervig, alles extra nochmal final zu machen dafür? Gibt es da eine andere Lösung eigentlich? o.o
edit: Ok mit invokeLater scheint es zu arbeiten, wieso ich das nicht selber probiert hatte, weiß ich auch nicht o.o
Aber man soll den Tag ja nicht vor dem Abend loben, da das Problem eh nur sporadisch auftrat.Geändert von Larrywayn (21.07.09 um 15:59 Uhr)
http://larrywayn.pytalhost.eu xD
Friss zeurst, sonst wirst du gefressen.
-
Also der hier ist sicher nicht Thread-safe:
Code java:1 2 3 4
new Runner(list, dlm).start(); pm.add(list); cp.validate(); f.repaint();
bei new Runner().start() fängst du an in die Liste zu schreiben:
Code java:1 2 3 4 5 6
int i = 0; while(i < 3) { dlm.addElement(new JLabel("<html>"+i+"<br />BB<a href=\"mailto:CC\">CC</a></html>")); ++i; } list.validate();
da arbeiten zu 99% sicher zwei Threads mit Dingen aus der Liste...Wandering in Greyhawk...
-
Naja macht der main-Thread aber auch, nur hab ich grad gesehen, dass dann das GUI solange blockiert ist

War halt ein Denkfehler und wie gesagt nun geht es ja .. ich Depp
Dabei hab ich das schon in zig Programmen gemacht und im selben Programm ist es auch zu hauf schon genutzt.. das kommt davon wenn man ein paar Wochen nix macht
Das mit dem Final ist auch nur, wenn man Variablen außerhalb deklariert, aber die kann man der Methode, welche das invokeLater dann hat, dann direkt als final übergeben.. praktisch =)
Aber danke für den Denkanstoß o.ohttp://larrywayn.pytalhost.eu xD
Friss zeurst, sonst wirst du gefressen.
-
Keine Ursache. Soll vorkommen
Wandering in Greyhawk...
Ähnliche Themen
-
JList, DefaultListModel - Liste wird nicht aktualisiert
Von Alex Duschek im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 4Letzter Beitrag: 26.05.09, 18:27 -
Problem Swing: Contentpane wird nicht immer angezeigt
Von bk99 im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 2Letzter Beitrag: 13.03.09, 11:44 -
Neue JList wird nicht sofort angezeigt.
Von Kai008 im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 2Letzter Beitrag: 10.03.09, 14:15 -
AWT Fensterinhalt wird nicht immer angezeigt
Von raptot im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 0Letzter Beitrag: 16.05.08, 12:46 -
Status Fenster wird nicht immer angezeigt
Von ulki im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 1Letzter Beitrag: 15.04.05, 08:34





Zitieren
Login





