Swing JGoodies: SelectionInList / ObservableList hört nicht auf Veränderungen in den Items

  • Themenstarter Themenstarter daersc
  • Beginndatum Beginndatum
D

daersc

Gast
Liebe Community,

Ich habe folgendes Problem: Mit JGoodies Binding versuche ich eine Liste von Beans an ein JTable zu binden. Soweit funktioniert das auch gut.

Probleme gibt es dann, wenn irgendwelche Properties der Bean Items geändert wird: Die SelectionInList feuert dann nämlich kein ChangeEvent.

Anbei ein kleines Programm, dass eine Liste in zwei verschiedene JTables bindet. Wird ein Wert in der einen JTable bearbeitet, so erscheint die Änderung in der zweiten JTable erst dann, wenn die entsprechende Zelle ausgewählt oder abgewählt wird.

Erwünscht wäre, dass die zweite Tabelle sofort nach dem Ändern eines Wertes in der ersten Tabelle reagiert und den neuen Wert anzeigt. Hat jemand Erfahrung damit, wie das (am besten mit JGoodies Binding) umsetzbar ist?

Vielen Dank schon einmal für eure Hilfe!

Java:
package test;

import com.jgoodies.common.bean.Bean;

@SuppressWarnings("serial")
public class MyBean extends Bean {
    
    private String value = null;
    
    public MyBean(String value) {
        setValue(value);
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        String tmp = this.value;
        this.value = value;
        
        firePropertyChange("value", tmp, value);
    }

}

Java:
package test;

import com.jgoodies.binding.adapter.AbstractTableAdapter;

@SuppressWarnings("serial")
public class TableAdapter extends AbstractTableAdapter<MyBean> {
    
    public TableAdapter() {
        super("value");
    }
    
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return getRow(rowIndex).getValue();
    }
    
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        getRow(rowIndex).setValue((String) aValue);
    }

}

Java:
package test;

import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.list.SelectionInList;
import com.jgoodies.common.collect.ArrayListModel;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.FormLayout;

public class Launcher {

    public static void main(String[] args) {
 
        final List<MyBean> list = new ArrayListModel<>();
        list.add(new MyBean("val 1"));
        list.add(new MyBean("val 2"));
        
        final SelectionInList<MyBean> sel1 = new SelectionInList<>(list);
        final SelectionInList<MyBean> sel2 = new SelectionInList<>(list);
        
        final JTable t1 = BasicComponentFactory.createTable(
                sel1, new TableAdapter());
        final JTable t2 = BasicComponentFactory.createTable(
                sel2, new TableAdapter());
        
        // display the created tables in a frame and show it
        final JFrame frame = new JFrame("Test frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final DefaultFormBuilder builder = new DefaultFormBuilder(
                new FormLayout("fill:pref:grow"));
        
        builder.border(Borders.DIALOG);
        
        builder.append(new JScrollPane(t1));
        builder.append(new JScrollPane(t2));
        
        frame.add(builder.build());
        
        frame.pack();
        frame.setLocationByPlatform(true);
        
        frame.setVisible(true);
    }

}
 
Die Antwort habe ich inzwischen selbst finden können.

Das Problem besteht darin, dass der ListDataListener in SelectionInList (wie auch jeder andere ListDataListener) nur über Änderungen in der Struktur der Liste informiert wird.

Abhilfe kann man sich über einen Wrapper für die ObservableList beschaffen, der zusätzlich auf alle seine Items und deren PropertyChangeEvents hört. Ein Beispiel für eine Implementierung habe ich hier gefunden: https://code.google.com/p/jgoodies-extensions/source/browse/trunk/src/java/ws/leipold/felix/jgoodies/misc/BeanListModel.java.

An der entsprechenden Stelle in meiner Launcher.java muss natürlich
Code:
final List<MyBean> list = new BeanListModel(new ArrayListModel<>())
geschrieben werden.
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben