JList aktualisiert nicht

flo1306

Mitglied
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:
Java:
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.
 
Zuletzt bearbeitet:
Wenn du ein lauffähiges Beispiel hier posten würdest, dann könnte man das auch ausführen und "ausbessern".
 
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...
Java:
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);
        }
    }
  
}
 
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.
 
Ich bin mir ganz sicher dass es nicht am methodenaufruf liegt da wenn ich debugge und zb
Java:
System.out.println("Test");
wird das ohne probleme ausgegeben
 
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.
 
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 🙁
 
Zuletzt bearbeitet:
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.
 
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 ? 😀
 
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:

Java:
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);
      }
}
 
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.
Java:
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);
      }
}
 
Habe das hier:
Java:
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
Java:
    private MAIN m;
    public FileTest(MAIN m) {
        this.m = m;
    }
habe ich meiner FileTest-Klasse hinzugefügt leider aber ohne Erfolg
 
Hier die ganze FileTest Klasse:
Java:
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);
    }
    }
}
 
Wie rufst du die Funktion "DirTest" der Klasse "FileTest" auf?

Warum ist diese Methode statisch? Lass "static" einfach weg (auch bei den Variablen)
Java:
    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.

Java:
    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?
 

Zurück
Oben