初心者です
javaFXを使ってスケジュール表を作ってみたいと思い、リンクを参考にしてTableを使って作成しようとしました。
リンクの内容を要約すると、セル内のレイアウトを実装してくれるList(Table)Cellクラスを継承したクラスを作り、Controllerクラスでそれを設定すればセルをカスタマイズできるよ、という内容です。
簡単に経緯を話すとリンクに言われた通りにやったところ、TableCellを継承したクラス内のupdateItemメソッド内の、値を設定するために行ったsetTextメソッドでヌルポが出た、という内容です。以下にコードを張ります。
Controller
1import javafx.scene.control.TableView; 2import javafx.util.Callback; 3 4public class SceduleTableController implements Initializable { 5 @FXML // ResourceBundle that was given to the FXMLLoader 6 private ResourceBundle resources; 7 8 @FXML // URL location of the FXML file that was given to the FXMLLoader 9 private URL location; 10 11 @FXML // fx:id="table" 12 private TableView<ScheduleData> table; // Value injected by FXMLLoader 13 14 @FXML // fx:id="scheduleColumn" 15 private TableColumn<String,ScheduleData> scheduleColumn; // Value injected by FXMLLoader 16 17 @FXML // fx:id="timeColumn" 18 private TableColumn<String, ?> timeColumn; // Value injected by FXMLLoader 19 20 21 @Override 22 public void initialize(URL location, ResourceBundle resources) { 23 scheduleColumn.setCellFactory(new Callback<TableColumn<String,ScheduleData>, TableCell<String,ScheduleData>>() { // (1) 24 @Override 25 public TableCell<String,ScheduleData> call(TableColumn<String,ScheduleData> tableColumn) { 26 return new ScheduleDataCell(); 27 } 28 }); 29 ObservableList<ScheduleData> scheduleDatas = createScheduleDatas(); 30 table.setItems(scheduleDatas); 31 32 assert scheduleColumn != null : "fx:id=\"sheduleColumn\" was not injected: check your FXML file 'ScheduleIndividual.fxml'."; 33 assert timeColumn != null : "fx:id=\"timColumn\" was not injected: check your FXML file 'ScheduleIndividual.fxml'."; 34 35 } 36 37 private ObservableList<ScheduleData> createScheduleDatas(){ 38 ObservableList<ScheduleData> scheduleDatas = FXCollections.observableArrayList(); 39 40 ScheduleData data1 = new ScheduleData("部活",LocalTime.of(12,30),LocalTime.of(16,0),"試合"); 41 42 scheduleDatas.add(data1); 43 44 return scheduleDatas; 45 } 46} 47
TableCell
1package application; 2 3import javafx.scene.control.TableCell; 4import javafx.scene.layout.Priority; 5import javafx.scene.layout.VBox; 6import javafx.scene.text.Font; 7import javafx.scene.text.Text; 8 9public class ScheduleDataCell extends TableCell<String,ScheduleData> { 10 private VBox cellContainer; 11 private Text scheduleTitle; 12 private Text time; 13 private Text txtDetail; 14 private boolean bound = false; 15 16 public ScheduleDataCell() { 17 //関係ないので端折ります。 18 } 19 20 @Override 21 public void updateItem(ScheduleData scheduleData, boolean empty) { 22 super.updateItem(scheduleData, empty); 23 if (!bound) { // セルの幅に合わせて折り返されるように、親となる ListView の width プロパティと、それぞれの wrappingWidth プロパティをバインドしています。 24 scheduleTitle.wrappingWidthProperty().bind(getTableView().widthProperty().subtract(25)); 25 time.wrappingWidthProperty().bind(getTableView().widthProperty().subtract(25)); 26 txtDetail.wrappingWidthProperty().bind(getTableView().widthProperty().subtract(25)); 27 bound = true; 28 } 29 30 31 if (empty) { 32 setText(null); 33 setGraphic(null); 34 } else { // タイトルやら詳細やらを設定 35 scheduleTitle.setText(scheduleData.titleProperty().get()); 36 time.setText(scheduleData.timeProperty().get()); 37 txtDetail.setText(scheduleData.detailProperty().get()); 38 setGraphic(cellContainer); 39 } 40 } 41} 42
*ヌルポが起きたのはscheduleTitle.setText(scheduleData.titleProperty().get());
の部分です。
試したこと
0. デバッグをしたところ、TableCellのupdateItemの第一引数がnullになっていました。(よくわからないのですが、デバックの途中で”~使用不可”と出てくるフレームがありました)
0. なので、一旦nullでも関係なくなるように、scheduleDataクラスをすべてStringにしてみたところ、実行はできましたが、セルにデータが入っていませんでした。
0. そこで、リンクの人はlistで自分はtableなので、何かが違うのかな、と思い、リストの人のサンプルをそのままコピーして実行してやると、なんとデータが表示されませんでした。
考えられることとしては、かれこれ2週間くらい悩んでいるので、実はもう出来ませんでしたオチはどうしても嫌なのですが、javaFXが新しくなってしまい、できてなくなったということですが、いかんせんいくら調べてみても、Oracleのjava8の記事以外全く情報が無くてどうしようもありません。
長文、知識不足でわかりにくい文章だったと思いますが、読んでくださりありがとうございます、私の助けになっていただけるととても助かります!
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/17 09:44
2021/04/17 10:06
2021/04/17 10:27
2021/04/17 11:18
2021/04/17 11:52
2021/04/17 12:34 編集
2021/04/17 12:36
2021/04/20 10:05