JavaFX Warum kriege ich eine Exception?

Bitte aktiviere JavaScript!
Hallo liebe Leute

Problem in folgender Klasse:
Java:
public class CenterviewStamptable extends SpreadsheetView
        implements
        ModelObservable,
        ListChangeListener<Object>{
    
    private View view;
    private MultiLangSupport lang;
    private ViewSettings settings;
    private StamppageModel activeStamppage;
    private ModelsViewLinkable model;
    private ArrayList<StamptableObservable> selectionobserver;
    
    private Grid centerviewStampgrid;

    public CenterviewStamptable(View view, ModelsViewLinkable model) {
        selectionobserver = new ArrayList<>();
        this.view = view;
        this.model = model;
        lang = new MultiLangSupport();
        settings = ViewSettings.getInstance();
        model.addModelobserver(this, ModelChange.THE_STAMPPAGE_AT_ACTIVE_PAGE_HAS_CHANGED);
        activeStamppage = model.getStamppageModel(model.getAddressOfActiveLibrarypage());
        init();
        //this.addEventHandler(EventType.ROOT, this);
//        eventhandler = new EventHandler<ActionEvent>() {
//            @Override
//            public void handle(ActionEvent event) {
//                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//            }
//        };
        this.getSelectionModel().getSelectedCells().addListener(this);
    }
    
    private void init(){
        setShowColumnHeader(true);
        setShowRowHeader(false);
        //refreshActiveLibStampPage();
        refreshActiveLibStampPage();
    }
    
    private void refreshActiveLibStampPage() {
        int rowcnt;
        int colcnt;
        int spanwidht;
        int spanstart;
        ObservableList<ObservableList<SpreadsheetCell>> rows;
        
        //Build grid
        rowcnt = activeStamppage.hasNoStampsets() ? 1 : 2 * activeStamppage.cntStampsets();
        colcnt = activeStamppage.hasNoProperties()? 1 : activeStamppage.cntAllProperties();
        centerviewStampgrid = new GridBase(rowcnt, colcnt);
        
        //Build rows
        if(activeStamppage.hasNoStampsets()){
            if (activeStamppage.hasNoProperties()) {    //Im ersten Durchgang wird hier korrekt reingesprungen
                buildEmptyCenterviewStamptableheader();
                rows = getRowWithEmptyMSG();
            }
            else {
                buildCenterviewStamptableheader();
                rows = getRowWithEmptyMSGAndCellspan();
            }
        }
        else{
            if (activeStamppage.hasNoProperties()) {
                buildEmptyCenterviewStamptableheader();
                rows = getRowsWithStampsetNamesAndEmptyMSG();
            }
            else {
                buildCenterviewStamptableheader();
                rows = getRowsWithStampsetNamesAndDescriptions();
            }
        }
        
        this.setGrid(centerviewStampgrid);
        centerviewStampgrid.setRows(rows);
        
        //Build table header
        buildCenterviewStamptableheader();
        
        //Fit Columns
        for(SpreadsheetColumn column : this.getColumns()){
            column.fitColumn();
        }
        
        //span name cells
        if(activeStamppage.hasNoStampsets()){
            spanstart = 0;
            spanwidht = activeStamppage.cntAllProperties();
            centerviewStampgrid.spanColumn(spanwidht, 0, spanstart);
        }
        else{
            spanwidht = activeStamppage.cntPersistantProperties();
            spanstart = activeStamppage.cntTemporaryProperties();
            for (int row = 0; row < rowcnt; row += 2) {
                centerviewStampgrid.spanColumn(spanwidht, row, spanstart);
            }
        }
    }
    
    private void buildEmptyCenterviewStamptableheader() {
        centerviewStampgrid.getColumnHeaders().add(lang.getString(3080));
    }
    
    private void buildCenterviewStamptableheader() {
//        for (StamppageheaderModel stamppageHeader : activeStamppage.getColumnheaderModels()) {
//            if(stamppageHeader.kindOfProperty == KindOfProperty.TEMPORARY){
//                centerviewStampgrid.getColumnHeaders().add(stamppageHeader.propertyName);
//            }
//        }
//        for (StamppageheaderModel stamppageHeader : activeStamppage.getColumnheaderModels()) {
//            if(stamppageHeader.kindOfProperty == KindOfProperty.PERSISTANT){
//                centerviewStampgrid.getColumnHeaders().add(stamppageHeader.propertyName);
//            }
//        }
        for(StamppageheaderModel stamppageHeader : activeStamppage.getColumnheaderModels()){
            centerviewStampgrid.getColumnHeaders().add(stamppageHeader.propertyName);
        }
    }
    
    private ObservableList<ObservableList<SpreadsheetCell>> getRowWithEmptyMSG() {
        ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
        ObservableList<SpreadsheetCell> row = FXCollections.observableArrayList();
        
        SpreadsheetCell cell = SpreadsheetCellType.STRING.createCell(
                1, 1, 1, 1, lang.getString(3081));
        row.add(cell);
        rows.add(row);
        return rows;
    }
    
    private ObservableList<ObservableList<SpreadsheetCell>> getRowWithEmptyMSGAndCellspan() {
        ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
        ObservableList<SpreadsheetCell> row = FXCollections.observableArrayList();
        SpreadsheetCell cell;

        for(int colcnt = 0; colcnt < activeStamppage.cntAllProperties(); colcnt++){
            cell = SpreadsheetCellType.STRING.createCell(
                    0, colcnt, 1, 1, lang.getString(3081));
            row.add(cell);
        }
        rows.add(row);
        return rows;
    }

    private ObservableList<ObservableList<SpreadsheetCell>> getRowsWithStampsetNamesAndEmptyMSG() {
        ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
        ObservableList<SpreadsheetCell> row;
        
        for(int stampsetCnt = 0; stampsetCnt < activeStamppage.cntStampsets(); stampsetCnt++){
            StampsetModel stampset = activeStamppage.getRowModel(stampsetCnt);
            String stampsetName = stampset.getName();
            
            row = getRowWithStampSetName(stampsetName, stampsetCnt);
            rows.add(row);
            
            row = getRowWithEmptyDescriptionMSG(2 * stampsetCnt + 1);
            rows.add(row);
        }
        return rows;
    }

    private ObservableList<ObservableList<SpreadsheetCell>> getRowsWithStampsetNamesAndDescriptions() {
        ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
        ObservableList<SpreadsheetCell> row;
        
        for(int stampsetCnt = 0; stampsetCnt < activeStamppage.cntStampsets(); stampsetCnt++){
            StampsetModel stampset = activeStamppage.getRowModel(stampsetCnt);
            String stampsetName = stampset.getName();
            
            row = getRowWithStampSetName(stampsetName, stampsetCnt);
            rows.add(row);
            
            row = getRowWithStampDescriptions(stampset.getItemmodels(),2 * stampsetCnt + 1);
            rows.add(row);
        }
        return rows;
    }

    private ObservableList<SpreadsheetCell> getRowWithEmptyDescriptionMSG(int rowcnt) {
        ObservableList<SpreadsheetCell> row = FXCollections.observableArrayList();
        SpreadsheetCell cell;
        
        cell = SpreadsheetCellType.STRING.createCell(rowcnt, 0, 1, 1, lang.getString(3082));
        row.add(cell);
        return row;
    }
    
    private ObservableList<SpreadsheetCell> getRowWithStampSetName(String name, int rowcnt) {
        ObservableList<SpreadsheetCell> row;
        SpreadsheetCell cell;
        int columncnt;
        
        row = FXCollections.observableArrayList();
        if(activeStamppage.hasNoProperties()){
            cell = SpreadsheetCellType.STRING.createCell(rowcnt, 0, 1, 1, name);
            row.add(cell);
        }
        else{
            columncnt = 0;
            for(String s : activeStamppage.getTemporaryProperties()){
                cell = SpreadsheetCellType.STRING.createCell(rowcnt, columncnt, 1, 1, "");
                row.add(cell);
                columncnt++;
            }
            for(String s : activeStamppage.getPersistantProperties()){
                cell = SpreadsheetCellType.STRING.createCell(rowcnt, columncnt, 1, 1, name);
                row.add(cell);
                columncnt++;
            }
        }
        return row;
    }
    
    private ObservableList<SpreadsheetCell> getRowWithStampDescriptions(ArrayList<ComponentstampModel> itemmodels, int rowcnt) {
        ObservableList<SpreadsheetCell> row;
        SpreadsheetCell cell;
        int columnindex;
        String cellcontent;
        
        row = FXCollections.observableArrayList();
        
        columnindex = 0;
        
        for(ComponentstampModel component : itemmodels){
            if(component == null){
                cellcontent = lang.getString(3082);
            }
            else{
                cellcontent = component.getDescription();
            }
            cell = SpreadsheetCellType.STRING.createCell(rowcnt, columnindex, 1, 1, cellcontent);
            row.add(cell);
            columnindex++;
        }
        return row;
    }
    
    /**
     * New StamptableObservers register here.
     *
     * @param observer
     */
    void addStamptableSelectionObserver(StamptableObservable observer){
        if(!selectionobserver.contains(observer)){
            selectionobserver.add(observer);
        }
    }
    
    /**
     * StamptableObserver can remove thereself from notify list here.
     *
     * @param observer
     */
    void removeStamptableSelectionObserver(StamptableObservable observer){
        selectionobserver.remove(observer);
    }
    
    @Override
    public void notifyAboutChanges(ModelChange change) {
        if(change == ModelChange.THE_STAMPPAGE_AT_ACTIVE_PAGE_HAS_CHANGED){
            activeStamppage = model.getStamppageModel(model.getAddressOfActiveLibrarypage());
            refreshActiveLibStampPage();
        }
    }

    @Override
    public void onChanged(Change<? extends Object> c) {
        TablePosition tp;
        int row;
        int column;
        Identifier selectedStampset;
        Identifier selectedProperty;
        
        tp = getSelectionModel().getSelectedCells().get(0);
        System.out.println("Zeile: " + tp.getRow() + " - Spalte: " + tp.getColumn());
        
        row = tp.getRow()/2;
        column = tp.getColumn();
        
        if(activeStamppage.hasNoStampsets()){
            selectedStampset = null;
        }
        else{
            selectedStampset = activeStamppage.getItem(row, column).getRow();
        }
        
        if(activeStamppage.hasNoProperties()){
            selectedProperty = null;
        }
        else{
            selectedProperty = activeStamppage.getItem(row, column).getColumn();
        }
        
        for(StamptableObservable observer : selectionobserver){
            observer.setNewSelection(selectedStampset, selectedProperty);
        }
    }
}

Die Klasse dient dazu, Daten anzuzeigen, soweit, so gut. Wenn ich mein Programm starte und keine Daten vorhanden sind, dann soll die Tabelle eine Zelle mit einer entsprechenden Nachricht anzeigen (siehe refreshActiveLibStampPage-Methode). Das Anzeigen an sich funktioniert soweit.

Jetzt habe ich ein Event, wenn der Benutzer eine Zelle anklickt (onChanged-Methode). Die wird auch korrekt getriggert.

Jetzt kommt das Problem: Wenn ich die Zelle mit der Keine-Daten-Nachricht anklicke, erhalte ich eine IndexOutOfBoundsException. Ich habe den starken Verdacht daß es damit zusammenhängt, daß die SpreadsheetView ein Problem mit den Spalten hat, den tp.column() liefert -1 (siehe onChanged-Methode). Ich sehe aber nicht, welches Problem. Spaltenheader ist da und wird korrekt angezeigt, sowohl SpreadsheetView.getColumns.size() als auch das Grid.getColumnCount() liefern wie erwartet 1. Siehe Screenshot.

Hat jemand eine Idee, woran das liegen kann?
 

Anhänge

Hm... Evtl. deswegen:
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TablePosition.html?is-external=true hat gesagt.:
Because the TableView can have different selection modes, the row and column properties in TablePosition can be 'disabled' to represent an entire row or column. This is done by setting the unrequired property to -1 or null.
 
Hm...ok. Aber mir sagt das leider nicht genug um eine Lösung auszubrüten. Es gibt zwar die Methode getSelectionModel.setSelectionMode(), aber soweit ich das verstehe kann ich da nur auswählen, ob nur eine oder mehrere Zellen gleichzeitig ausgewählt werden können.

Weitere Ideen oder Hinweise?
 
Oh, sorry, das habe ich missverstanden: bei Swing wählt man ja aus, ob man zellen- oder zeilenweise selektieren kann und ich dachte, das bezieht sich darauf (nach dem Motto: bei zeilenweiser Selektion macht die Spalte keinen Sinn).
 
Wie dumm von mir, ich hätte vielleicht noch den Stacktrace mitliefern können. Und vielleicht kann @dzim ja was damit anfangen...

Code:
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
    at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136)
    at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242)
    at com.sun.javafx.scene.control.behavior.TableViewBehaviorBase.lambda$new$219(TableViewBehaviorBase.java:245)
    at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
    at impl.org.controlsfx.spreadsheet.TableViewSpanSelectionModel.handleSelectedCellsListChangeEvent(TableViewSpanSelectionModel.java:217)
    at impl.org.controlsfx.spreadsheet.TableViewSpanSelectionModel.clearAndSelect(TableViewSpanSelectionModel.java:770)
    at javafx.scene.control.TableView$TableViewSelectionModel.clearAndSelect(TableView.java:1914)
    at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.simpleSelect(TableCellBehaviorBase.java:215)
    at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.doSelect(TableCellBehaviorBase.java:148)
    at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)
 
Und die Methode SelectionModel().getFocusedCell() liefert zwar ein plausibles Ergebnis, die Exception kommt aber trotzdem noch. :(
 
Hm...merkwürdig.

Wenn ich zwei Zellen habe, kann ich zwischen den Zellen hin- und herselektieren ohne daß es zu einer Exception kommt.
Aber wehe ich klicke in den freien Bereich...BUMM. :(
 
Hm, was ist denn das für ein Müll...da hab ich jetzt ein lauffähiges Minimalbeispiel zusammengestümpert-und nun funktioniert es???

Sieht wenigstens jemand einen Unterschied bei dem, was ich oben gepostet habe?

Java:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TablePosition;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.controlsfx.control.spreadsheet.Grid;
import org.controlsfx.control.spreadsheet.GridBase;
import org.controlsfx.control.spreadsheet.SpreadsheetCell;
import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
import org.controlsfx.control.spreadsheet.SpreadsheetView;


public class SpreadsheetViewListening extends Application {
    
    class Table
            extends SpreadsheetView
            implements ListChangeListener<Object>{
        private Grid tablegrid;
        
        public Table() {
            init();
        }
        
        void init(){
            ObservableList<ObservableList<SpreadsheetCell>> rows;
            ObservableList<SpreadsheetCell> row;
            SpreadsheetCell cell;
            
            setShowColumnHeader(true);
            setShowRowHeader(false);
            
            tablegrid = new GridBase(2, 2);
            
            //Build cells
            rows = FXCollections.observableArrayList();
            
            row =  FXCollections.observableArrayList();
            cell = SpreadsheetCellType.STRING.createCell(
                    0, 0, 1, 1, "A1");
            row.add(cell);
            cell = SpreadsheetCellType.STRING.createCell(
                    0, 1, 1, 1, "A2");
            row.add(cell);
            rows.add(row);
            
            row =  FXCollections.observableArrayList();
            cell = SpreadsheetCellType.STRING.createCell(
                    1, 0, 1, 1, "B1");
            row.add(cell);
            cell = SpreadsheetCellType.STRING.createCell(
                    1, 1, 1, 1, "B2");
            row.add(cell);
            rows.add(row);
            
            this.setGrid(tablegrid);
            tablegrid.setRows(rows);
            tablegrid.getColumnHeaders().add("Spalte A");
            tablegrid.getColumnHeaders().add("Spalte B");
            
            //Add Listener
            getSelectionModel().getSelectedCells().addListener(this);
        }

        @Override
        public void onChanged(Change<? extends Object> c) {
            TablePosition tp;
        
            tp = this.getSelectionModel().getFocusedCell();
            System.out.println("Zeile: " + tp.getRow() + " - Spalte: " + tp.getColumn());
        }
    }
    
    @Override
    public void start(Stage primaryStage) {
//        Button btn = new Button();
//        btn.setText("Say 'Hello World'");
//        btn.setOnAction(new EventHandler<ActionEvent>() {
//           
//            @Override
//            public void handle(ActionEvent event) {
//                System.out.println("Hello World!");
//            }
//        });
        
        Table t = new Table();
        StackPane root = new StackPane(t);
//        root.getChildren().add(btn);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    
}
 
Ich glaube, ich habe den Fehler gefunden.

Im Gegensatz zu dem Beispiel baue ich die Tabelle neu auf. In dem Codebeispiel hab ich den Fehler nachgestellt:
Java:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TablePosition;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.controlsfx.control.spreadsheet.Grid;
import org.controlsfx.control.spreadsheet.GridBase;
import org.controlsfx.control.spreadsheet.SpreadsheetCell;
import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
import org.controlsfx.control.spreadsheet.SpreadsheetView;

public class SpreadsheetViewListening extends Application {
    
    class Table
            extends SpreadsheetView
            implements ListChangeListener<Object>{
        private Grid tablegrid;
        
        public Table() {
            init();
            //Add Listener
            getSelectionModel().getSelectedCells().addListener(this);
        }
        
        void init(){
            ObservableList<ObservableList<SpreadsheetCell>> rows;
            ObservableList<SpreadsheetCell> row;
            SpreadsheetCell cell;
            
            setShowColumnHeader(true);
            setShowRowHeader(false);
            
            tablegrid = new GridBase(2, 2);
            
            //Build cells
            rows = FXCollections.observableArrayList();
            
            row =  FXCollections.observableArrayList();
            cell = SpreadsheetCellType.STRING.createCell(
                    0, 0, 1, 1, "A1");
            row.add(cell);
            cell = SpreadsheetCellType.STRING.createCell(
                    0, 1, 1, 1, "A2");
            row.add(cell);
            rows.add(row);
            
            row =  FXCollections.observableArrayList();
            cell = SpreadsheetCellType.STRING.createCell(
                    1, 0, 1, 1, "B1");
            row.add(cell);
            cell = SpreadsheetCellType.STRING.createCell(
                    1, 1, 1, 1, "B2");
            row.add(cell);
            rows.add(row);
            
            this.setGrid(tablegrid);
            tablegrid.setRows(rows);
            tablegrid.getColumnHeaders().add("Spalte A");
            tablegrid.getColumnHeaders().add("Spalte B");
        }

        @Override
        public void onChanged(Change<? extends Object> c) {
            TablePosition tp;
        
            tp = this.getSelectionModel().getFocusedCell();
            System.out.println("Zeile: " + tp.getRow() + " - Spalte: " + tp.getColumn());
            init(); // <- ########## Tabelle neu aufbauen ##########
        }
    }
    
    @Override
    public void start(Stage primaryStage) {
//       
        Table t = new Table();
        StackPane root = new StackPane(t);
//        root.getChildren().add(btn);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

In meiner Klasse oben mache ich das, um die Daten aus dem Model zu aktualisieren. Hast du vielleicht eine Idee, wie ich die Tabelle sonst aktualisieren könnte? Den Listener entfernen hab ich schon probiert, aber das klappt nicht (und ich bin mir auch nicht sicher, daß das wirklich ein guter Weg ist).
 
Hm...mal sehen. Die äußerste Liste könnte ich stehen lassen. Es ist leider ein wesentlicher Bestandteil der ganzen Angelegenheit, Zeilen und Spalten hinzuzufügen und wieder zu entfernen.
 
Sind doch auch alles ObservableLists, oder nicht? Einfach leeren und neu füllen sollte klappen, wenn ich grad nicht danebenlieg
 
Ja, das sind alles ObservableLists. Ich hab gerade mal probiert, die äußere Liste (rows) nur zu leeren und nicht neu zu erstellen. Aber das ändert leider nicht viel, höchstens daß die Exception mal an anderer Stelle kommt.

Ich werde morgen mal ausprobieren was passiert, wenn ich auch die Zeilen-Listen nur leere anstatt sie zu ersetzen. Wobei ich die Lösung recht häßlich fände. Wenn einmal sehr viele Zeilen angezeigt wurden, bleiben halt alle Objekte am Leben, auch wenn sie nicht mehr gebraucht werden.
 
Sofern niemand eine bessere Idee hat werde ich wohl einen Thread parallel laufen lassen, der so alle 50ms das SelectionModel auswertet und den "Event"kram übernimmt.
Ach man, das ist doch aber eine Scheißlösung...
 
Moment'n. Wenn ich den Thread richtig verstehe (und nein, ich hab ihn aufgrund Antworten vorher nur überflogen), willst du @White_Fox eigentlich nur eine Zelle mit einem Platzhalter versehen, wenn noch keine Daten drin sind. Korrekt?
 
Ja, das war der Plan.
Es kann aber zwischendurch vorkommen, daß später keine Daten mehr da sind (wenn der Benutzer z.B. alle löscht).

Edit:
Wenn es eine andere Möglichkeit für eine leere Ansicht gibt, dann würde ich auch die nehmen, auf die eine leere Zelle will ich mich nicht festlegen. Aber Zeilen/Spalten dynamisch hinzuzufügen und wieder zu entfernen, das wäre schon wichtig (und wenn ich meinen Versuch da oben richtig verstanden habe, ist das das Problem).
 
Stimmt...ich hab das sogar schon öfter gesehen, daß die Tabelle dann sowas wie "Keine Daten" oder so anzeigt, wenn nichts drin steht. Den Fall 'Keine Daten' kann ich dann streichen.

Edit:
Allerdings ist löst das mein Problem mit der Exception und dem Aktualisieren der Tabelle leider nicht (was mich gerade weitaus mehr stört). :(
 
Zuletzt bearbeitet:
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben