Обновление Java Значения ячеек Таблицы из другого класса - PullRequest
0 голосов
/ 25 августа 2018

Я пытаюсь изменить один из моих столбцов и значения его ячеек из другого класса, однако я получаю исключение пустого указателя, когда Java пытается выполнить эту строку OverviewController.getOverviewController.returnStatusColumn.setCellValueFactory( cellData -> cellData.getValue().getStatusProperty());, я удалил весь непочтительный код

Класс TableView:

@FXML 
private TableView<Task> taskTable;
@FXML
private TableColumn<Task, String> statusColumn;

private final static OverviewController controller = new OverviewController 
();


public static OverviewController getOverviewController() {
    return controller;
}


public void setMainApp(MainApp mainApp) {
    this.mainApp = mainApp;
    taskTable.setItems(mainApp.getTaskData());
    taskTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    taskTable.setPlaceholder(new Label(""));
}

public TableView<taskTable> returnTasks() {
    return taskTable;
}

public TableColumn<taskTable, String> returnStatusColumn() {
    return statusColumn;
}

@Override
public void initialize(URL location, ResourceBundle resources) {
        statusColumn.setCellValueFactory(cellData -> 
cellData.getValue().getStatusProperty());
}

@FXML
public void createTask(ActionEvent event) throws InterruptedException, 
IOException, ParseException {
    thread = new MyThread();
    thread.main(null);

    statusColumn.setCellValueFactory(cellData -> 
cellData.getValue().getStatusRunningProperty());
    statusColumn.setStyle("-fx-text-fill: green; -fx-font-weight: bold;");
    taskTable.refresh();
}

@FXML
public void stopTasks() {
    statusColumn.setCellValueFactory(cellData -> 
cellData.getValue().getStatusProperty());
    statusColumn.setStyle("-fx-text-fill: red; -fx-font-weight: bold;");
    taskTable.refresh();
}

Этот класс работает нормально, когда я хочу обновить столбцы таблицы, если я щелкаю по методу остановки задач (который связан с кнопкой), столбец состояния обновляется до метки остановки, которую яхочу сделать то же самое с методом запуска задач.

Случайный класс, в котором я хочу обновить столбец состояния представления таблицы:

public class UpdateTable {
public static void main(String[] args) {
    OverviewController.getOverviewController.returnStatusColumn.setCellValueFactory(
    cellData -> cellData.getValue().getStatusProperty());
    OverviewController.getOverviewController().returnTasks().refresh();
    }

}

Данные представления таблицы:

//Status Information
private final SimpleStringProperty status;
private final SimpleStringProperty statusRunning;


public Task() {
    this(null, null);
}

    public Task() {
        this.statusRunning = new SimpleStringProperty("Running");
        this.status= new SimpleStringProperty("Stop");
    }

    public StringProperty getStatusProperty( ) {
        return status;
    }

    public StringProperty getStatusRunningProperty( ) {
        return statusRunning;
    }

}

Если я запустил случайный класс, это приведет к исключению нулевого указателя, в частности к этой строке: OverviewController.getOverviewController().returnStatusColumn().setCellValueFactory(cellData -> cellData.getValue().getStatusProperty());

Я сделал это совершенно неправильно?Я просто хочу иметь возможность обновлять ячейки столбца табличного представления из другого класса.

1 Ответ

0 голосов
/ 25 августа 2018

Да, вы делаете это неправильно.

Вы нигде не используете подкласс Application, который необходимо использовать как точку входа вашего приложения (при условии, что вы не используете JFXPanel или Platform.startup). Кроме того, вы обращаетесь к столбцу как к первому утверждению в вашей программе, что означает, что поле statusColumn не инициализируется.

Также обычно не нужно включать какой-либо класс, кроме класса контроллера для инициализации cellValueFactory. Особенно использование static полей - плохой подход:

Если вы укажете класс контроллера в fxml, FXMLLoader создаст новый экземпляр класса контроллера. Этот экземпляр отличается от экземпляра, хранящегося в поле controller, поэтому даже при использовании

OverviewController.getOverviewController.returnStatusColumn.setCellValueFactory(
    cellData -> cellData.getValue().getStatusProperty());

после загрузки fxml вы не получите нужный вам экземпляр.

Вместо этого я рекомендую использовать метод initialize класса контроллера для такого рода инициализаций. Он вызывается FXMLLoader после создания и внедрения всех объектов, указанных в fxml.

public class OverviewController {

    ...

    @FXML
    private TableColumn<Task, String> statusColumn;

    ...

    @FXML
    private void initialize() {
        statusColumn.setCellValueFactory(cellData -> cellData.getValue().getStatusProperty());
    }

}

Если вам делать необходимо передать некоторую информацию из класса, который не является контроллером, см. Ответы здесь Передача параметров JavaFX FXML . В ответах описаны лучшие подходы, чем использование static.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...