JavaFX setCellValueFactory (Programare, Java, Javafx, Javafx 8)

ednhzrd a intrebat.
a intrebat.

Știu, această întrebare a fost pusă de sute de ori și mi-am petrecut ultimele 3 ore citindu-le pe toate. Scriu o mică aplicație cu JavaFX (și am mai făcut-o și înainte…). Totul funcționează în afară de a pune conținut în coloana mea:

@FXML public void initialize() {
    exerciseColumn.setCellValueFactory(new PropertyValueFactory<Exercise, String>("name"));
}

Aceasta este metoda mea de inițializare și aceasta:

public StringProperty nameProperty() {
    return name;
}

este Property Getter pentru „StringProperty name”. Lucrul cu adevărat amuzant este că codul este copia exactă a unui alt proiect pe care l-am făcut cu ceva timp în urmă (am verificat totul de două și trei ori, desigur) pe care l-am compilat din nou astăzi și care funcționează perfect. Am citit documentația pentru, după cum se pare, jumătate din JavaFX pentru a găsi o soluție, dar pur și simplu nu are niciun sens. Dacă credeți că aveți nevoie de mai mult cod pentru a mă ajuta, atunci pot să vi-l furnizez, bineînțeles.

edit: un alt exemplu cu aceeași problemă (cel puțin așa sper)

Principalul:

package test;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import test.model.Exercise;
import test.view.Controller;

public class Main extends Application {

private Stage primaryStage;
private AnchorPane pane;

private ObservableList<Exercise> activeSession = FXCollections.observableArrayList();

public Main() {
    activeSession.add(new Exercise("ednhzrd"));
}

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

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("Test");

    try {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(Main.class.getResource("view/view.fxml"));
        pane = (AnchorPane) loader.load();
        Scene scene = new Scene(pane);
        primaryStage.setScene(scene);
        primaryStage.show();

        Controller controller = new Controller();
        controller.setMainApp(this);
    } catch(Exception e) {
        e.printStackTrace();
    }
}
}

Controller:

package test.view;

import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import test.Main;
import test.model.Exercise;

public class Controller {
@FXML private TableView<Exercise> exerciseTable;
@FXML private TableColumn<Exercise, String> exerciseColumn;

private Main main;

public Controller() {}

@FXML
public void initialize() {
    exerciseColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
}

public void setMainApp(Main main) {
    this.main = main;
}
}

Exercițiu:

enter codepackage test.model;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Exercise {

private StringProperty name;

public Exercise(String name) {
    this.name = new SimpleStringProperty(name);
}

public StringProperty nameProperty() {
    return name;
}
}

fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="400.0" prefWidth="209.0"  xmlns_fx="http://javafx.com/fxml/1" fx_controller="test.view.Controller">
   <children>
      <TableView fx_id="exerciseTable" layoutX="200.0" layoutY="100.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <columns>
          <TableColumn fx_id="exerciseColumn" prefWidth="75.0" text="C1" />
        </columns>
         <columnResizePolicy>
            <TableView fx_constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
      </TableView>
   </children>
</AnchorPane>

Comentarii

  • Nu este nimic în neregulă cu codul postat de tine. Creați un exemplu minim reproductibil și includeți-l în întrebare. Presupunem că ați verificat toate aspectele legate de „este activat” (adică știți că initialize() metoda este invocată, etc.). Ați încercat, de asemenea, să convertiți la modul mai actual de a face acest lucru: exerciseColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());? –  > Por James_D.
  • Cu siguranță este invocată, verificarea acestui lucru cu câteva ieșiri de bază este întotdeauna primul lucru pe care îl fac. Voi încerca să reproduc problema într-o versiune mai mică decât cea pe care o am acum și voi reveni într-o secundă. –  > Por ednhzrd.
  • aceasta a fost prima mea soluție, am luat-o dintr-un tutorial, dar am lăsat-o pentru că nu înțeleg cum funcționează lambdas… –  > Por ednhzrd.
  • Avantajul acestei abordări este că erorile vor fi detectate la compilare. (Greșeli de scriere în șirul de caractere transmis către PropertyValueFactory, de exemplu, vor eșua pur și simplu în tăcere). Deci, dacă asta se compilează, cu siguranță nu este nimic în neregulă cu codul pe care l-ați prezentat. (OT: chiar ar trebui să luați în considerare învățarea expresiilor lambda. Acestea fac parte din Java de peste patru ani și vă vor simplifica foarte mult viața). –  > Por James_D.
  • Da, am ieșit de mult timp din Java și m-aș considera un începător… Există vreo literatură bine scrisă sau vreo introducere bună pe această temă pe care ați putea-o recomanda? –  > Por ednhzrd.
1 răspunsuri
James_D

Nu există nici o problemă cu dvs. cellValueFactory. Singura problemă aici este că nu ai pus niciodată elemente în tabel. Dacă modificați controlerul pentru a adăuga un element de test în tabel:

package test.view;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import test.Main;
import test.model.Exercise;

public class Controller {
    @FXML
    private TableView<Exercise> exerciseTable;
    @FXML
    private TableColumn<Exercise, String> exerciseColumn;

    private ObservableList<Exercise> activeSession = FXCollections.observableArrayList();

    private Main main;

    public Controller() {
    }

    @FXML
    public void initialize() {
        exerciseColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        activeSession.add(new Exercise("hrrykane"));
        exerciseTable.setItems(activeSession);
    }

    public void setMainApp(Main main) {
        this.main = main;
    }
}

atunci veți vedea efectul dorit: