Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse?

Wuast

Bekanntes Mitglied
Hi,
kann mir jemand sagen, ob es in einem der o.g. Bereichen eine Art "automatischen" Listener gibt, der Updates feuert wenn man im UI einen Reiter verschiebt?
Ich habe eine Methode, die ein neues Objekt erzeugt, welches dann mithilfe der abstract table Model in einer JTable abgebildet werden soll. Ich habe noch keinen Listener dafür implementiert, sodass auch erstmal nichts aufploppt. Wenn ich jetzt die Spalten zurechtrücke, taucht das neue Objekt dann aber "von alleine" auf.
Woran liegt das? Ich denke mal, es gibt entsprechende Listener, damit das grafisch auch abgebildet werden kann, wenn der Bumms "resizable" ist, oder? Aber warum greift das dann auch auf die Inhalte der JTable oder ATM zu (bzw. auch welche überhaupt)?
liebe Grüße Yannick
 
Der Effekt kommt vermutlich von deinem gewählten Layoutmanager. Wenn die Größe der Komponenten in der Anwendung geändert wird, dann muss diese neu gezeichnet werden. Wenn erst dann der gesamte Inhalt sichtbar wird, dann machst du beim Layout etwas falsch. Was genau das ist kann man aber ohne Code nicht sagen.
 
Der Effekt kommt vermutlich von deinem gewählten Layoutmanager. Wenn die Größe der Komponenten in der Anwendung geändert wird, dann muss diese neu gezeichnet werden.
Ich habe den absolute-Layout-Typen gewählt. Oder was meinst du mit Manager?

Wenn erst dann der gesamte Inhalt sichtbar wird, dann machst du beim Layout etwas falsch.

Ich dachte eigentlich, es liegt daran, dass ich beim Programmstart einfach noch keine Inhalte habe und diese dann nach und nach erzeugt werden. Und bisher habe ich es mal wieder noch nicht geschafft, da die entsprechenden Listener korrekt zu implementieren... weswegen ich da nichts anderes erwartet hatte.

Was genau das ist kann man aber ohne Code nicht sagen.

Ich versuche mal auszuwählen, was brauchbare Infos liefert. Sonst gerne sagen, ob / was fehlt.

Java:
//Main-Klasse mit UI, enthält dann schließlich auch die Methode...
private void initialize() {
        mainFrame = new JFrame();
        mainFrame.setTitle(functions.displayMonth());   
        mainFrame.setBounds(100, 100, 629, 435);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().setLayout(null);
        
        JScrollPane scrollPaneForJtable = new JScrollPane();
        scrollPaneForJtable.setViewportBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
        scrollPaneForJtable.setBounds(6, 27, 623, 371);
        mainFrame.getContentPane().add(scrollPaneForJtable);
        
        TableModel atm = new ATM_4_GUI(finAdmin);
        
        informationDisplay = new JTable(atm);
    
    //...
    
    JButton buttonNewEntry = new JButton("New entry");
        buttonNewEntry.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                functions.createNewEntry();
            }
        });
        menuBar.add(buttonNewEntry);
    
    //...
    
}

public class UI_Functions {
    
    //...
    
    public void createNewEntry() {
        CashFlow cf = finAdmin.factory(displayDate(), 0, 0, 0, 0); //Objekterzeugung
        finAdmin.addCashFlow(cf);    //Objekt zur ArrayList hinzufügen
        atm.displayNewEntry(cf);    //führt zur Klasse mit der AbstractTableModel
    }
}

public class ATM_4_GUI extends AbstractTableModel {
    
    //...
    
    public void displayNewEntry(CashFlow cf) {
            int newIndex = finAdmin.getMonthlyFinances().size();   
            cashflowList.add(cf);
            fireTableRowsInserted(newIndex, newIndex);
        }
}

hier dachte ich eigentlich, dass der neue Eintrag angezeigt wird. Tut er aber nicht, also irgendetwas habe ich mal wieder noch nicht hingekriegt.
Aber wenn ich die Größe der Reiter ändere und das neu gezeichnet wird, dann tauchen das neue Objekt (aktuell leider noch 2 x) in der JTable auf.^^

Hoffe, das hilft zum Verständnis.
 
Offensichtlich verwendest du Swing mit Null-Layout, das ist keine gute Idee und wird dir ständig Schwierigkeiten machen: mainFrame.getContentPane().setLayout(null);
 
Also ich arbeite ja in Eclipse und habe da den Swing-Disgner benutzt. Layout-Typ ist absolutLayout. Der Rest ist automatisch implementiert wurden.
Was würdest du denn stattdessen empfehlen?

Ich habe bei einem anderen Projekt mit dem Null-Layout nicht diese Erfahrung gemacht, da waren aber auch funktionierende / korrekte Listender dabei. Also es hat definitiv was mit dem Layout zu tun?
 
wonach genau suche ich denn hier, also was ist mein Problem bzw. falsch an dem Code bisher? xD Das ist wieder so viel auf einmal
Das Layout ist doch im Frame allg. , oder geht es um das JTable Layout?
Java:
informationDisplay = new JTable(atm);
        informationDisplay.setColumnSelectionAllowed(true);
        informationDisplay.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
        informationDisplay.setForeground(Color.BLACK);
        informationDisplay.setBackground(new Color(224, 255, 255));
        scrollPaneForJtable.setViewportView(informationDisplay);
ein Layout konnte ich speziell für die JTable ja nicht auswählen, nur die Border..

Grundsätzlich bin ich mit der JTable ja zufrieden und die ATM funktioniert (bis auf die Listener) auch.
 
Was soll ich sagen, so etwas wie "Swing-Disgner" kann natürlich eine Menge Tipparbeit sparen, man muss trotzdem genau wissen was man tut. Das ist meine Empfehlung. Welcher Layoutmanager genau der Richtige für dich ist kann ich nicht sagen. Du wirst dir ja sicherlich die Programmoberfläche mal aufgemalt haben, in den verschieden Bearbeitungsstufen usw. Damit müsstest du dann eine Entscheidung treffen können.
 
Was soll ich sagen, so etwas wie "Swing-Disgner" kann natürlich eine Menge Tipparbeit sparen, man muss trotzdem genau wissen was man tut. Das ist meine Empfehlung. Welcher Layoutmanager genau der Richtige für dich ist kann ich nicht sagen. Du wirst dir ja sicherlich die Programmoberfläche mal aufgemalt haben, in den verschieden Bearbeitungsstufen usw. Damit müsstest du dann eine Entscheidung treffen können.
Hm okay, dann muss ich mir das i-wann mal im Detail reinziehen, bringt mich aber akut nicht weiter. Grundsätzlich ist es ja auch nicht weiter störend (in meinem Fall), weil wenn ich die Listener richtig hinkriege dann tauchen die Inhalte ja ohnehin sofort auf. Ich hatte mich halt nur gefragt, ob da irgendwo ein entsprechender Mechanismus updates feuert, sobald das neu gezeichnet wird.
dachte, dass man das ja vllt. sogar für sich nutzen könnte, z.B. also "Universal-Listener" oder so, der einfach immer einmal neu zeichnet und dann automatisch Änderungen übernommen werden (sodass ich nicht für jede wünschenswerte Änderungsanzeige einen separaten Listener bräuchte).

Ja wenn es so einfach wäre, dann könnte es jeder und eine Ausbildung und Erfahrung wären nicht notwendig.
Richtig. Nur irgendwo müsste man ja mal anfangen und einen Überblick erhalten, sonst ist es ja keine geführte "Ausbildung". Leider kam das bei uns eigentlich alles so kurz, dass ich nur autodidaktisch und mithilfe des Forums lerne..
 
Das sagt mir, dass du das Konzept hinter Listenern noch nicht verstanden hast.
Deshalb die " "; ist mir schon klar, dass das so nicht ganz richtig ist. Nennen wir es halt besser "Weg, um die Notwendigkeit, viele Listener implementieren zu müssen, zu umgehen" (für mich so ein Gedanke, weil ich das irgendwie alleine nie so richtig ans laufen kriege. Dass es dem State of the art wohl nicht entspricht, ist mir auch klar)
 
Naja, wenn irgend etwas bestimmtes auf irgend einen Event passieren soll, dann wirst du dafür einen Listener schreiben müssen. Java liest keine Gedankden. Sei froh drum, wäre das möglich, bräuchte es keine Programmierer mehr und wir wären arbeitslos.
 
dass man das ja vllt. sogar für sich nutzen könnte, z.B. also "Universal-Listener" oder so, der einfach immer einmal neu zeichnet und dann automatisch Änderungen übernommen werden (sodass ich nicht für jede wünschenswerte Änderungsanzeige einen separaten Listener bräuchte).
Hier muss man erstmal unterscheiden zwischen Objekt und Klasse. Natürlich kann man sich eine Klasse bauen, die als Listener für alle möglichen Ereignisse herhalten kann:

Java:
class RepaintOnEventListener implements ChangeListener, 
        PropertyChangeListener /* weitere Listener, falls gewünscht */  {
    private JComponent component;

    public RepaintOnEventListener(JComponent comp) {
        component = comp;
    }

    // Listener-Implementierungen

    public void stateChanged(ChangeEvent e) {
        repaint();
    }

    public void propertyChanged(PropertyChangeEvent e) {
        repaint();
    }

    // Helferlein

    private void repaint() {
        if (component != null) {
            component.repaint();
        }
    }
}

Dann erstellt man für die neu zu zeichnende Komponente ein Objekt dieser Klasse und registriert dieses als Listener. Das könnte man ggf. sogar noch etwas allgemeiner halten, mit einem Proxy bzw. Reflection aber das führt hier zu weit.

Die Frage ist natürlich: wo ist jetzt der Vorteil von z. B.
Java:
meinModel.addPropertyChangeListener(new RepaintOnEventListener(panelToRedraw));
// ggü
meinModel.addPropertyChangeListener(e -> panelToRedraw.repaint());
?
 

Zurück
Oben