JavaFX TableColumns mit CellFactory setzen

Diskutiere TableColumns mit CellFactory setzen im AWT, Swing, JavaFX & SWT Bereich.
L

lam_tr

Hallo zusammen,

wie kann ich in JavaFX die CellFactory setzen wenn der zweite Generic Parameter von einer TableColumn nicht bekannt ist? Aktuell versuche ich es, schaffe aber den Compile-Error nicht weg zu bekommen.

Code:
package com.rockwell.ssb.serialization.monitor.controller.sig;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableViewSample extends Application {

    private TableView<Person> table = new TableView<Person>();

    private final ObservableList<Person> data = FXCollections.observableArrayList(
            new Person("Jacob", "Smith", "[email protected]"),
            new Person("Isabella", "Johnson", "[email protected]"),
            new Person("Ethan", "Williams", "[email protected]"),
            new Person("Emma", "Jones", "[email protected]"),
            new Person("Michael", "Brown", "[email protected]"));

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(500);

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("firstName"));

        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("lastName"));

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("email"));

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        for (TableColumn<Person, ?> column : table.getColumns()) {
            column.setCellFactory(new Callback<TableColumn<Person,>, TableCell<Person,>>() {
                @Override
                public TableCell<Person, ?> call(TableColumn<Person, ?> param) {
                    return new TableCell<>(){
                    };
                }
            });
        }

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }

    public static class Person {

        private final SimpleStringProperty firstName;

        private final SimpleStringProperty lastName;

        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }
}
das Problem liegt an der Stelle

Code:
        for (TableColumn<Person, ?> column : table.getColumns()) {

            column.setCellFactory(new Callback<TableColumn<Person,>, TableCell<Person,>>() {

                @Override

                public TableCell<Person, ?> call(TableColumn<Person, ?> param) {

                    return new TableCell<>(){

                    };

                }

            });

        }
Wie kriege ich das Fragezeichen weg? der TableColumn<T, S> wobei T schon gesetzt ist und S noch ? bleibt.

An sich ist das eher eine Generic Frage als JavaFX.

Grüße
lam
 
mrBrown

mrBrown

Was willst du denn erreichen? (Also mit dem Code, wo du die unbekannten TableCell setzt, das sieht eigentlich überflüssig aus)
 
L

lam_tr

Was willst du denn erreichen? (Also mit dem Code, wo du die unbekannten TableCell setzt, das sieht eigentlich überflüssig aus)
Ich will die TableCell erweitern mit Custom Control, und wenn das zweite Argument nicht bekannt ist, kann ich die updateItem Methode nicht überschreiben.
 
mihe7

mihe7

Lagere den Code in eine Methode aus:
Java:
private <T> void setupPersonCellFactory(TableColumn<Person, T> col) {
...
}
In der Schleife:
Java:
for (TableColumn<Person, ?> column : table.getColumns()) {
    setupPersonCellFactory(column);
}
 
L

lam_tr

Lagere den Code in eine Methode aus:
Java:
private <T> void setupPersonCellFactory(TableColumn<Person, T> col) {
...
}
In der Schleife:
Java:
for (TableColumn<Person, ?> column : table.getColumns()) {
    setupPersonCellFactory(column);
}
Ich bekomme da immer noch ein compile error

Code:
    public FilteredTableView<T> setColumnText(String currentName, String newName) {
        for (TableColumn<T, ?> column : getColumns()) {
            if (column.getText().equals(currentName.toUpperCase())) {
                column.setText(newName);
                setupPersonCellFactory(column);
            }
        }
        return this;
    }
    
    private <T> void setupPersonCellFactory(TableColumn<T, T> column) {
        column.setCellFactory(new Callback<TableColumn<T,T>, TableCell<T,T>>() {
            @Override
            public TableCell<T, T> call(TableColumn<T, T> param) {
                // TODO Auto-generated method stub
                return null;
            }
        });
    }
 
L

lam_tr

Ich habe jetzt einen megahässlichen Weg gefunden wie man es machen kann.

Code:
    public FilteredTableView<T> setColumnText(String currentName, String newName) {
        for (TableColumn<T, ?> column : getColumns()) {
            if (column.getText().equals(currentName.toUpperCase())) {
                column.setText(newName);
                setupPersonCellFactory(column, new TableCell<T, Object>(){
                    @Override
                    protected void updateItem(Object item, boolean empty) {
                        super.updateItem(item, empty);
                    }
                });
            }
        }
        return this;
    }
   
    private void setupPersonCellFactory(TableColumn column, TableCell<T, Object> tableCell) {
        column.setCellFactory(param -> tableCell);
    }
Vielleicht kennt da jemand eine bessere Lösung. Ich gebe TableColumn ohne Argumente mit. Als Nachteil habe ich nur Typ Object und müsste es in der Update Methode casten.
 
mihe7

mihe7

Du brauchst schon zwei Typvariablen. Mach mal <S,T> draus. Oben war S ja fix Person.
 
L

lam_tr

Ach du hast recht, so gehts :)

Code:
public FilteredTableView<T> setColumnValue(String currentName, String newName) {
        for (TableColumn<T, ?> column : getColumns()) {
            if (column.getText().equals(currentName.toUpperCase())) {
                column.setText(newName);
                setupPersonCellFactory(column, new TableCell<T, Double>(){
                    @Override
                    protected void updateItem(Double item, boolean empty) {
                        super.updateItem(item, empty);
                    }
                });
            }
        }
        return this;
    }
  
    private <S> void setupPersonCellFactory(TableColumn column, TableCell<T, S> tableCell) {
        column.setCellFactory(param -> tableCell);
    }
 
Thema: 

TableColumns mit CellFactory setzen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben