JavaFX表中的工作复选框(CheckBoxTableCell)

JavaFX表中的工作复选框(CheckBoxTableCell),checkbox,javafx,listener,fxml,javafx-tableview,Checkbox,Javafx,Listener,Fxml,Javafx Tableview,这类似于家庭作业问题 我最近在Scenebuilder中制作了一个示例UI,后来我不得不用JavaSwing编程。这或多或少起了作用。现在,我的任务不是实际开发程序,而是在工作培训中学习一些东西,用Scenebuilder创建一个类似的UI,但这次是一个实际工作的UI。规格如下: 这是一扇有桌子的窗户。 至少有两个栏目中有类似于复选框或类似于广播框的复选框,因为该公司有奇怪的标准。 它使用由Scenebuilder生成的FXML文件进行布局。 如果我可以启用编辑功能,那么让复选框充当广播框应该很

这类似于家庭作业问题

我最近在Scenebuilder中制作了一个示例UI,后来我不得不用JavaSwing编程。这或多或少起了作用。现在,我的任务不是实际开发程序,而是在工作培训中学习一些东西,用Scenebuilder创建一个类似的UI,但这次是一个实际工作的UI。规格如下:

这是一扇有桌子的窗户。 至少有两个栏目中有类似于复选框或类似于广播框的复选框,因为该公司有奇怪的标准。 它使用由Scenebuilder生成的FXML文件进行布局。 如果我可以启用编辑功能,那么让复选框充当广播框应该很容易。我发现很多例子几乎都能满足我的需求,但仍然不适用于我的情况。以下是其中一些:

我从一开始就几乎完全复制了代码,首先创建了一个工作示例。然后我根据我的需要调整它,直到我只有复选框来做第一个工作原型,而不是布尔值。 然后,我参与了的完整代码的一部分,以添加复选框。这很有效,但它们对点击没有反应。 ,并且似乎只适用于文本字段,而不适用于复选框。 然后我使用了第二个代码块中的两个lambda表达式,实际上我在第一个答案中使用了变量,并手动解决了一些错误,直到Eclipse突然自动将其转换为lambda表达式。我还添加了public observevalue getCompleted方法,Eclipse提供了一些神奇的建议,然后我得到了您可以在下面的相应代码中看到的东西,而无需控制台打印。 我还向布尔属性添加了一个侦听器,就像我认为的site一样,但这似乎没有多大帮助。 下面是对话框的外观图片,我仍然无法使用复选框:

我的问题:如何使复选框对点击做出反应?React可能意味着在控制台上输出一些东西,我不需要一个给定的代码使它自动禁用另一个复选框,我想自己找出那个部分

我的代码:

src.controller.MainController.java

src.controller.MainController.fxml

src.view.Table.java


我找到了解决办法。在问了那个问题之后,我花了将近20个小时才让这个愚蠢的东西工作,因为我改变了很多,所以列举我所做的所有改变并不是很有用。但这里至少有一个有效的例子。 只有很少几条线负责使公盒和母盒触发彼此的对立,这是我的任务所特有的,其他一切都只是为了让CheckBoxTableCells真正正常工作。有人会认为这是一种非常常见的情况,应该有标准的方法,比如将文本打印到控制台或读取文件,但显然不是,显然,在使用UI编程时,一切都必须复杂

不管怎么说,这里是工作代码:

src.controller.MainView.java

src.controller.MainController.java

src.controller.MainController.fxml


您需要实现属性访问器方法,即public BooleanProperty rMaleBoxProperty;,等在模型类表中。不确定这是否是唯一的问题,但如果没有这些方法,您的单元格将无法正确绑定到属性。然后将单元格值工厂设置为指向从这些方法返回的属性。我真的不知道你从完成后返回的财产应该做什么;它似乎只是返回一个不做任何事情的属性。首先:将SimpleBoleAnProperty更改为BooleanProperty使它们可以单击,耶!谁知道移除简单的东西会是如此简单的修复;但是当我点击它时,我仍然没有得到控制台输出。我应该如何以及在哪里引用addListener方法?我可以触发它,但是我该怎么处理那个听众呢?在MainController.java中将行添加到表中倒数第二个代码行之前,我的新代码是:table horst=new TableHorst,Meier,true,false;horst.getCompleted.addListenernew ChangeListener{@Override public void CHANGEDOBSERVABLEVALUE我仍然不知道getCompleted的目的是什么。您将其表示为complete是什么?为什么不尝试我概述的方法?您是否为MABLE和MABLE创建了属性访问器方法?只需将侦听器添加到这些属性中。但我可能必须对这两种方法中的任何一种进行处理e列或单个单元格,对吗?我需要一个用于复选框的更改侦听器。我有这个RMalBox.addListenerChangeListenerobservable,oldValue,newValue->{System.out.printlntest;};我现在扩展到RMalBox.addListenernew ChangeListener{@Override public void changedServableValue
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import view.Table;
public class MainController implements Initializable{
 @FXML TableView<Table> tableID;
 @FXML TableColumn<Table,String> iFirstName;
 @FXML TableColumn<Table,String> iLastName;
 @FXML TableColumn<Table,Boolean> iMalebox;
 @FXML TableColumn<Table,Boolean> iFemalebox;
 @Override public void initialize(URL location,ResourceBundle resources){
  iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
  iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
  iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
  iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
  iMalebox.setEditable(true);
  // iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
  // iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
  iFemalebox.setCellValueFactory(p->p.getValue().getCompleted());
  iFemalebox.setCellFactory(p->new CheckBoxTableCell<>());
  // iMalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rMalebox"));
  // iFemalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rFemalebox"));
  tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true,false),new Table("Anna","Becker",false,true),new Table("Karl","Schmidt",true,false)));
  tableID.setEditable(true);
 }
}
package controller;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainView extends Application{
 @Override public void start(Stage primaryStage){
  try{
   // FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
   AnchorPane page=(AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
   Scene scene=new Scene(page);
   primaryStage.setScene(scene);
   primaryStage.setTitle("Window Title");
   primaryStage.show();
  }catch(Exception e){
   Logger.getLogger(MainView.class.getName()).log(Level.SEVERE,null,e);
  }
 }
 public static void main(String[] args){
  Application.launch(MainView.class,(java.lang.String[])null);
 }
}
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
 <children>
<TableView fx:id="tableID" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="iFirstName" prefWidth="75.0" text="First name" />
<TableColumn fx:id="iLastName" prefWidth="75.0" text="Last name" />
            <TableColumn fx:id="iMalebox" prefWidth="75.0" text="Male" />
            <TableColumn fx:id="iFemalebox" prefWidth="75.0" text="Female" />
</columns>
</TableView>
 </children>
</AnchorPane>
package view;
import javafx.beans.InvalidationListener;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class Table{
 private SimpleStringProperty rFirstName;
 private SimpleStringProperty rLastName;
 private SimpleBooleanProperty rMalebox;
 private SimpleBooleanProperty rFemalebox;
 public Table(String sFirstName,String sLastName,Boolean sMalebox,Boolean sFemalebox){
  rFirstName=new SimpleStringProperty(sFirstName);
  rLastName=new SimpleStringProperty(sLastName);
  rMalebox=new SimpleBooleanProperty(sMalebox);
  rMalebox.addListener((ChangeListener)(observable,oldValue,newValue)->{
   System.out.println("test");
   System.out.println("abc");
  });
  rFemalebox=new SimpleBooleanProperty(sFemalebox);
 }
 public String getRFirstName(){
  return rFirstName.get();
 }
 public void setRFirstName(String v){
  rFirstName.set(v);
 }
 public String getRLastName(){
  return rLastName.get();
 }
 public void setRLastName(String v){
  rLastName.set(v);
 }
 public Boolean getRMalebox(){
  return rMalebox.get();
 }
 public void setRMalebox(Boolean v){
  rMalebox.set(v);
 }
 public Boolean getRFemalebox(){
  return rFemalebox.get();
 }
 public void setRFemalebox(Boolean v){
  rFemalebox.set(v);
 }
 public ObservableValue<Boolean> getCompleted(){
  return new ObservableValue<Boolean>(){
   @Override public void removeListener(InvalidationListener arg0){}
   @Override public void addListener(InvalidationListener arg0){}
   @Override public void removeListener(ChangeListener<? super Boolean> listener){}
   @Override public Boolean getValue(){
    return null;
   }
   @Override public void addListener(ChangeListener<? super Boolean> listener){
    System.out.println("Test");
   }
  };
 }
}
package controller;
import java.io.*;
import javafx.application.*;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MainView extends Application{
 @Override public void start(Stage primaryStage) throws IOException{
  primaryStage.setScene(new Scene((AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"))));
  primaryStage.show();
 }
 public static void main(String[] args){
  Application.launch(MainView.class);
 }
}
package controller;
import java.net.*;
import java.util.*;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.fxml.*;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.*;
import javafx.scene.control.cell.*;
import javafx.util.*;
import view.*;
public class MainController implements Initializable{
 @FXML TableView<Table> tableID;
 @FXML TableColumn<Table,String> iFirstName;
 @FXML TableColumn<Table,String> iLastName;
 @FXML TableColumn<Table,Boolean> iMalebox;
 @FXML TableColumn<Table,Boolean> iFemalebox;
 @Override public void initialize(URL location,ResourceBundle resources){
  iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
  iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
  iMalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
   @Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
    return cellData.getValue().maleCheckedProperty(true);
   }
  });
  iMalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
   @Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
    return new CheckBoxTableCell<>();
   }
  });
  iFemalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
   @Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
    return cellData.getValue().femaleCheckedProperty(true);
   }
  });
  iFemalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
   @Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
    return new CheckBoxTableCell<>();
   }
  });
  tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true),new Table("Anna","Becker",false),new Table("Karl","Schmidt",true)));
 }
}
package view;
import javafx.beans.property.*;
public class Table{
 private String rFirstName;
 private String rLastName;
 public Table(String sFirstName,String sLastName,Boolean sMale){
  rFirstName=sFirstName;
  rLastName=sLastName;
  maleCheckedProperty(false).set(sMale);
 }
 private SimpleBooleanProperty maleChecked=new SimpleBooleanProperty(false);
 private SimpleBooleanProperty femaleChecked=new SimpleBooleanProperty(false);
 public SimpleBooleanProperty maleCheckedProperty(boolean recursion){
  if(recursion) femaleCheckedProperty(false).set(!maleChecked.get());
  return maleChecked;
 }
 public SimpleBooleanProperty femaleCheckedProperty(boolean recursion){
  if(recursion) maleCheckedProperty(false).set(!femaleChecked.get());
  return femaleChecked;
 }
 public String getRFirstName(){
  return rFirstName;
 }
 public String getRLastName(){
  return rLastName;
 }
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="98.0" prefWidth="218.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
 <children>
 <TableView fx:id="tableID" editable="true" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
  <columns>
   <TableColumn fx:id="iFirstName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="First name" />
   <TableColumn fx:id="iLastName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="Last name" />
   <TableColumn fx:id="iMalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Male"/>
   <TableColumn fx:id="iFemalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Female"/>
   </columns>
  </TableView>
 </children>
</AnchorPane>