tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
595
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Larrywayn Larrywayn ist offline Mitglied Silber
    Registriert seit
    May 2009
    Ort
    Berlin
    Beiträge
    60
    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.

  2. #2
    Avatar von bile
    bile bile ist offline Mitglied Silber
    Registriert seit
    Jun 2009
    Ort
    Zug (Schweiz)
    Beiträge
    52
    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...

  3. #3
    Larrywayn Larrywayn ist offline Mitglied Silber
    Registriert seit
    May 2009
    Ort
    Berlin
    Beiträge
    60
    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.

  4. #4
    Avatar von bile
    bile bile ist offline Mitglied Silber
    Registriert seit
    Jun 2009
    Ort
    Zug (Schweiz)
    Beiträge
    52
    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...

  5. #5
    Larrywayn Larrywayn ist offline Mitglied Silber
    Registriert seit
    May 2009
    Ort
    Berlin
    Beiträge
    60
    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.o
     
    http://larrywayn.pytalhost.eu xD
    Friss zeurst, sonst wirst du gefressen.

  6. #6
    Avatar von bile
    bile bile ist offline Mitglied Silber
    Registriert seit
    Jun 2009
    Ort
    Zug (Schweiz)
    Beiträge
    52
    Keine Ursache. Soll vorkommen
     
    Wandering in Greyhawk...

Ähnliche Themen

  1. JList, DefaultListModel - Liste wird nicht aktualisiert
    Von Alex Duschek im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 4
    Letzter Beitrag: 26.05.09, 18:27
  2. Problem Swing: Contentpane wird nicht immer angezeigt
    Von bk99 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 13.03.09, 11:44
  3. Neue JList wird nicht sofort angezeigt.
    Von Kai008 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 10.03.09, 14:15
  4. AWT Fensterinhalt wird nicht immer angezeigt
    Von raptot im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 0
    Letzter Beitrag: 16.05.08, 12:46
  5. Status Fenster wird nicht immer angezeigt
    Von ulki im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 1
    Letzter Beitrag: 15.04.05, 08:34

Stichworte