# JList aktualisiert nicht



## flo1306 (20. Aug 2017)

Hallo,
Ich habe vor Kurzem mit Java begonnen und stehe jetzt vor einem für mich unlösbarem Problem. Ich habe eine JList mit einem Defaultlistmodel. Die beiden sind durch .setModel verbunden und alles wunderbar. Wenn ich meinem DefaultListModel Elemente hinzufüge per .addElement('Element') wird es im DefaultListModel gespeichert (was ich mir bereits ausgeben habe lassen) aber in der JList nicht angezeigt. Hoffe einer von den Experten hier weiß mehr als ich. Danke schonmal im vorraus .


Hier der Code:

```
import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JList;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Vector;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;

public class MAIN extends JFrame {

    private JPanel contentPane;
    private DefaultListModel<String> FachAuswahl = new DefaultListModel<String>();
    JTextField tfumbenennen;
    DefaultListModel<String> DateienList = new DefaultListModel<String>();
    JList<String> Dateien;

    /**
    * Launch the application.
    */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MAIN frame = new MAIN();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
    * Create the frame.
    */
    public MAIN() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 729, 493);
        setTitle("FileManager");
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
      
        Dateien = new JList<String>();
        Dateien.setFont(new Font("Tahoma", Font.PLAIN, 15));
        Dateien.setBounds(38, 46, 189, 98);
        Dateien.setModel(DateienList);


      
        JScrollPane scrollPane_1 = new JScrollPane();
        scrollPane_1.setBounds(38, 43, 192, 100);
        contentPane.add(scrollPane_1);
        scrollPane_1.setViewportView(Dateien);


      
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(454, 43, 191, 100);
        contentPane.add(scrollPane);
      
        JList<String> list = new JList<String>();
        list.setFont(new Font("Tahoma", Font.PLAIN, 15));
        list.setBounds(537, 384, -134, -89);
        list.setModel(FachAuswahl);
        scrollPane.setViewportView(list);
        FachAuswahl.addElement("Englisch");
        FachAuswahl.addElement("FIT");
        FachAuswahl.addElement("Deutsch");
        FachAuswahl.addElement("Geografie");
        FachAuswahl.addElement("Geschichte");
        FachAuswahl.addElement("Religion");
        FachAuswahl.addElement("Französisch");
        FachAuswahl.addElement("Latein");
        FachAuswahl.addElement("Physik");
        FachAuswahl.addElement("Musik");
        FachAuswahl.addElement("Mathematik");
        FachAuswahl.addElement("Biologie");
        FachAuswahl.addElement("Sonstiges");
      
        JLabel lblFachordnerZumVerschieben = new JLabel("Fach/Ordner ausw\u00E4hlen");
        lblFachordnerZumVerschieben.setBounds(455, 24, 151, 16);
        contentPane.add(lblFachordnerZumVerschieben);
      
        JButton btnCancel = new JButton("Cancel");
        btnCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        btnCancel.setBounds(12, 384, 121, 34);
        contentPane.add(btnCancel);
      
        JButton button = new JButton("OK");
        button.setBounds(578, 384, 121, 34);
        contentPane.add(button);
      
        tfumbenennen = new JTextField();
        tfumbenennen.setBounds(454, 195, 152, 22);
        contentPane.add(tfumbenennen);
        tfumbenennen.setColumns(10);
      
        JLabel lblFileUmbenennen = new JLabel("File umbenennen");
        lblFileUmbenennen.setBounds(454, 173, 152, 16);
        contentPane.add(lblFileUmbenennen);
      
        JButton btnFileLschen = new JButton("File l\u00F6schen");
        btnFileLschen.setBounds(457, 246, 121, 25);
        contentPane.add(btnFileLschen);
      
        JButton btnSettings = new JButton("Settings");
        btnSettings.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Settings.main(null);
                }
        });
        btnSettings.setBounds(313, 389, 97, 25);
        contentPane.add(btnSettings);

        JLabel lblDateienInZielordner = new JLabel("Dateien in Zielordner");
        lblDateienInZielordner.setBounds(38, 24, 175, 16);
        contentPane.add(lblDateienInZielordner);
    }
  
    public void schreiben() {
        File verzeichnis;
        FileTest ft = new FileTest();
       verzeichnis = new File(ft.Path);
       for (String File: verzeichnis.list()) {
            DateienList.addElement(File);
    }
    }
}
```

Ps.: Sorry für so viel Code aber besser mehr als zu wenig  und wundert euch nicht dass die Methode schreiben, um die es eigentlich geht, nicht aufgerufen wird. Das ist nicht der Fehler das passiert nämlich aus einer anderen Klasse und funktioniert wunderbar. Das betroffene DefaultListModel ist die DateienList und die JList Dateien. .revalidate und .repaint schon ausprobiert hilft alles nichts. Alle andere Foren schon durchforscht gibt auch Personen mit dem gleichen Problem, dort waren es aber andere Fehler als bei mir, da keiner der Lösungen bei mir geklappt hat.


----------



## Robat (21. Aug 2017)

Versuch mal erst die Werte deinem Model hinzuzufügen und es erst dann deiner JList zuübergeben.


----------



## flo1306 (21. Aug 2017)

Gerade eben probiert --> kein Erfolg Jlist bleibt leer Model wird aber gefüllt


----------



## Flown (21. Aug 2017)

Wenn du ein lauffähiges Beispiel hier posten würdest, dann könnte man das auch ausführen und "ausbessern".


----------



## flo1306 (21. Aug 2017)

Habe schnell ein Beispiel geschrieben: Das Programm soll im Prinzip den Inhalt eines Ordners in einer JList darstellen. Im Beispielprogramm klappts obwohl eigentlich kein Unterschied besteht...

```
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.File;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JList;
import javax.swing.JScrollPane;

public class Test extends JFrame {

    private JPanel contentPane;
    private JList list;
    private JScrollPane scrollPane;
    private String Path = ".";
    private File f = new File(Path);
    private DefaultListModel model = new DefaultListModel();
    /**
    * Launch the application.
    */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test frame = new Test();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
    * Create the frame.
    */
    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
      
        scrollPane = new JScrollPane();
        scrollPane.setBounds(51, 32, 335, 194);
        contentPane.add(scrollPane);
      
        list = new JList();
        list.setBounds(51, 32, 335, 194);
        scrollPane.setViewportView(list);
        list.setModel(model);
        listschreiben();

    }
    public void listschreiben() {
        String[] dateinamen = new String[f.list().length];
        dateinamen = f.list();
        for (String namen : dateinamen) {
            model.addElement(namen);
        }
    }
  
}
```


----------



## Flown (21. Aug 2017)

Du solltest mal durch deine Anwendung debuggen und sehen, was wie wo aufgerufen wird.


----------



## flo1306 (21. Aug 2017)

Schon getan sehe dass die elemente hinzugefügt werden wenn ich mir das model ausgebe werden mir sogar die file Namen ausgegeben


----------



## Robat (21. Aug 2017)

Du sagtest eingangs, dass die `schreiben()` Methode aus einer anderen Klasse aufgerufen wird. Wie rufst du diese Methode denn auf bzw wie kommst du in der Klasse an eine Instanz der Klasse `MAIN`. Denke mal das sich dort ein Fehler eingeschlichen hat.


----------



## flo1306 (21. Aug 2017)

```
MAIN m = new MAIN();
m.schreiben();
```
Das ist doch richtig oder


----------



## Flown (21. Aug 2017)

Wird `MAIN` einmal in der main-Methode erzeugt oder auch von dir?


----------



## flo1306 (21. Aug 2017)

Ich bin mir ganz sicher dass es nicht am methodenaufruf liegt da wenn ich debugge und zb 

```
System.out.println("Test");
```
wird das ohne probleme ausgegeben


----------



## Robat (21. Aug 2017)

flo1306 hat gesagt.:


> Das ist doch richtig oder


Nein. Du erzeugst in deiner `main` - Methode ein Objekt deiner Klasse `MAIN`. Da setzt du `setVisible(true)` - deine GUI wird also angezeigt.
Jetzt erstellst du in der anderen Klasse eine neue Instanz deiner Klasse und rufst darüber die Methode `schreiben()` auf. Davon kriegt deine eigentliche GUI aber nichts mit, da es ja ein anderes Objekt ist.

EDIT: Und natürlich bekommt die richtige Ausgabe beim Methodenaufruf. Aber wie oben bereits geschrieben hast du jetzt 2 Objekte deiner GUI wovon nur die erste sichtbar ist. Wenn du auf die unsichtbare GUI eine Methode aufrufst, bekommt die andere Instanz das nicht mit.


----------



## flo1306 (21. Aug 2017)

Danke  werd ich später testen wenn ich zuhause bin


----------



## flo1306 (21. Aug 2017)

Klappt leider noch nicht so ganz. Ich erzeuge in der Main Methode der Klasse MAIN eine Instanz der Klasse Main und mache sie sichtbar. In meiner anderen Klasse erzeuge ich ebenfalls eine Instanz und rufe schreiben auf. Klappt nicht, bin komplett verwirrt bei sowas simplen


----------



## Robat (21. Aug 2017)

Das Ziel ist es auch nicht 2 Instanzen deiner Klasse zu haben. Das Ziel ist es eine Instanz zu erstellen und diese dann mittels Dependency Injektion in die andere Klasse zu bekommen.


----------



## flo1306 (22. Aug 2017)

Tut mir leid aber Dependency Injection ist mir noch ein Fremdbegriff habe im Internet auch nichts gefunden was mich da wirklich weiterbringt magst dus mir erklären ?


----------



## Robat (22. Aug 2017)

Einfach gesprochen ist es nichts anderes als eine Variable mittels (bspw) des Konstruktors in eine andere Klasse zu überführen. Hier mal ein kleines Beispiel:


```
public class A{
    private B b;
    public A(B b){
        this.b = b;
        // Hier kann jetzt mit b gearbeitet werden
    }
}

public class B {
     public static void main(String[] args){
           A a = new A(this);
      }
}
```


----------



## Flown (22. Aug 2017)

@Robat das ist ein schlechtes Beispiel, da B in main keine Instanz ist, sondern im statischen Kontext (i.e. Compilerfehler)


----------



## Robat (22. Aug 2017)

Stimmt, da hab ich gar nicht dran gedacht.
Was lernen wir daraus: vorher noch mal nachdenken bevor man schreibt. 

Hier noch mal ohne statischen Kontext.

```
public class A{
    private B b;
    public A(B b){
        this.b = b;
        // Hier kann jetzt mit b gearbeitet werden
    }
}

public class B {
     public B(){
           A a = new A(this);
      }
}
```


----------



## flo1306 (22. Aug 2017)

Habe das hier:

```
FileTest filetest = new FileTest(this);
// FileTest ist der Name der Klasse welche die Methode schreiben ausführt
```
dem Konstruktor meiner MAIN Klasse hinzugefügt.
das hier 

```
private MAIN m;
    public FileTest(MAIN m) {
        this.m = m;
    }
```
habe ich meiner FileTest-Klasse hinzugefügt leider aber ohne Erfolg


----------



## flo1306 (22. Aug 2017)

Hier die ganze FileTest Klasse:

```
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

import javax.swing.JOptionPane;
 public class FileTest {
    static String Path;
    private static MAIN m;
    public FileTest(MAIN m) {
        this.m = m;
    }
    public static void DirTest() {
    File f = new File("." + File.separator + "Path.txt");
    if (f.exists()) {
    try {
    BufferedReader in = new BufferedReader(new FileReader("." + File.separator + "Path.txt"));
    Path = in.readLine();
    in.close();
    } catch (Exception b) {
        b.printStackTrace();
    }
    } else {
        JOptionPane.showMessageDialog(null, "Pfad in den Settings festlegen!");
    }
    File a = new File(Path);
    if (a.list().length != 0) {
        String[] Dateien = new String[a.list().length];
        Dateien = new String[a.list().length];
        Dateien = a.list();
        m.schreiben(Path);
    }
    }
}
```


----------



## Robat (22. Aug 2017)

flo1306 hat gesagt.:


> leider aber ohne Erfolg


Was heißt ohne Erfolg?


----------



## flo1306 (22. Aug 2017)

Hat nicht funktioniert hat nichts geändert


----------



## Joose (22. Aug 2017)

Wie rufst du die Funktion "DirTest" der Klasse "FileTest" auf?

Warum ist diese Methode statisch? Lass "static" einfach weg (auch bei den Variablen)

```
static String Path;
    private static MAIN m;
    public FileTest(MAIN m) {
        this.m = m;
    }
    public static void DirTest() {
```
Die Benennung deiner Variablen und Methoden ist nicht gerade vorteilhaft, außerdem solltest du dich halbwegs an die Konventionen (auch wenns deine eigenen sind) halten.
Du mischt einfach lowerCamelCase und UpperCamelCase Schreibweise  -> Normal wird alles in lowerCamelCase geschrieben, einzig Klassen in UpperCamelCase.


```
if (a.list().length != 0) {
        String[] Dateien = new String[a.list().length];
        Dateien = new String[a.list().length];
        Dateien = a.list();
        m.schreiben(Path);
    }
```
Hast du dir diesen Code schonmal genauer angeschaut? Weißt du was er macht?
Du definierst eine Variable "Dateien" und weißt dieser ein neues String[] zu.
In der nächsten Zeile weißt du der Variable wieder ein neues String[] zu, in der darauffolgenden Zeile weißt du dieser Variable wieder ein String[] zu. Wozu unnötig 2 Arrays erstellen?


----------



## flo1306 (22. Aug 2017)

Danke für eure Hilfe das Problem ist jetzt erstmals gelöst 


Robat hat gesagt.:


> *public* *class* A{
> *private* B b;
> *public* A(B b){
> *this*.b = b;
> ...


Das war die Lösung habs erst nur falsch implementiert. Danke an Alle für eure Hilfe !


----------

