javaFX中tableview修改属性实现初始化和最简单的刷新功能

谷善
2023-12-01

本程序使用了JavaFX Sence Builder 2.0设计UI界面,设计的是通讯录管理系统
作者通过修改tableview和tableColumn的属性实现初始化以及刷新的功能。这里的person是一个类。

 @FXML
    private TableView<person> tableGroup;
    @FXML
    private TableColumn<person, String> name;
    @FXML
    private TableColumn<person, CheckBox> checklist;
     String Name[]={"1","2","3"};//这是初期预先定义的,DataGroup这个是已经没有用了,但是DataContacts依然在使用的。虽然没有但是不能删除,因为我在后面的table显示
    person DataGroup[]=new person[Name.length];//person类对象数组
    personContact DataContacts[]=new personContact[Name.length];
    personContact selectContacts[]=new personContact[Name.length];

这个用来修改属性和设置基本的对象数组,注意,DataGroup等是全局变量

ObservableList<person> data = FXCollections.observableArrayList(DataGroup);//转化得到的person类DataGroup

在这里我们得到有person类属性的ObservableList对象。然后现在要对着tablecolumn设置tablecell,并且把data的放进tableview才能显示

name.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().name));//把转化的类内涵的参数传递给列,也就是cellData
tableGroup.setItems(data);

当然现在data是空的所以我们要给初始化data的DataGroup赋值。注意,这里的DataGroup是person类的对象数组,所以我们赋值的时候也要创建一个person类的对象数组然后覆盖这个DataGroup

try {
                        Connection conn=new conn().getConnection();
                        new conn().initGroup(conn);
                        person[] Data1=new conn().selectGroup(conn);//建立数据库连接连接的是选择组数据库,专门对组读取信息,而且是不重复的查找
                        DataGroup=Data1;
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }

这里作者读取了数据库来创建person类数组,当然也可以采用以下方法来创建person类对象数组。这里就是利用了person类的构造方法把Name数组中单个的数传到person类里面,然后返回一个person对象(构造方法不能自己设置返回类型,因为本身自带返回类型!)

for (int i = 0; i < Name.length; i++) {
                        DataGroup[i] = new person(Name[i]);
                    }

这里作者亲测,就算你创建的person类对象数组长度和你的DataGroup不一样也是可以直接赋值的。
下面是完整版的tableview显示方法,如果没带数据库请修改所有try内赋值方法,具体修改方式看上面。

 void tableviewGroup(){
        Platform.runLater(new Runnable() {//多线程操作
            @Override
            public void run() {
                    /*for (int i = 0; i < Name.length; i++) {
                        DataGroup[i] = new person(Name[i]);
                    }*/
                    try {
                        Connection conn=new conn().getConnection();
                        new conn().initGroup(conn);
                        person[] Data1=new conn().selectGroup(conn);//建立数据库连接连接的是选择组数据库,专门对组读取信息,而且是不重复的查找
                        DataGroup=Data1;
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    if(DataGroup!=null) {
                    tableGroup.getColumns().remove(checklist);//从tableview里面移除选择列,tablegroup是这个table view的名字
                    ObservableList<person> data = FXCollections.observableArrayList(DataGroup);//转化得到的person类DataGroup
                    name.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().name));//把转化的类内涵的参数传递给列,也就是cellData
                    tableGroup.setItems(data);
                    tableGroup.getSelectionModel().getSelectedItems().addListener((ListChangeListener<? super person>) indicesListener -> {
                        //System.out.println(tableGroup.getSelectionModel().getSelectedItem().getName());//此处的getNamea是person类里面的构造器。
                        try {
                            if(tableGroup.getSelectionModel().getSelectedItem()!=null) {//选择当分组tableview里面不是空的时候才初始化联系人的tableview,不然联系人的tableview匹配不到分组的会报错
                                Connection conn = new conn().getConnection();
                                personContact[] Data1 = new conn().select(conn, tableGroup.getSelectionModel().getSelectedItem().getName());//查找该分组下面的联系人
                                DataContacts = Data1;
                                conn.close();
                                tableviewContacts();//联系人的tableview
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    });
                    tableGroup.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);//只能单选
                }
            }
        });
    }
    //从这里开始就是另一个tableview要放入下面给出的控件才能运行,如果不用,上面第二个try就可以隐藏掉
    void tableviewContacts(){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if(DataContacts!=null) {//初始化之后的联系人类的对象数组为空时不能加载,不然报错。这里千万不能用equals因为初始化完之后的联系人数组里面可能有值是空的比如分组信息,如果用了equals语句会默认为true

                    ObservableList<personContact> data = FXCollections.observableArrayList(DataContacts); //与上面相同就只是改了几个参数
                    name1.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().name));
                    tel.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().tel));
                    org.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().org));
                    email.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().email));
                    uid.setCellValueFactory(cellData -> new SimpleObjectProperty<Integer>(cellData.getValue().uid));
                    selectColumn.setCellValueFactory(cellData -> cellData.getValue().cb.getCheckBox());
                    tableContact.setItems(data);
                    tableContact.getSelectionModel().getSelectedItems().addListener((ListChangeListener<? super personContact>) indicesListener -> {
                    });
                    tableContact.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
                }
            }
        });
    }

当然,如果要运行另一个tableview类要放入以下的控件

 @FXML
    private TableColumn<personContact, String> email;

    @FXML
    private TableColumn<personContact, Integer> uid;

    @FXML
    private TableView<personContact> tableContact;

    @FXML
    private TableColumn<personContact, String> org;
    @FXML
    private TableColumn<personContact, String> tel;
    @FXML
    private TableColumn<personContact, String> name1;
    @FXML
    private TableColumn<personContact, CheckBox> selectColumn;
    @FXML
    private TextField getNameOfSelect;

这里作者使用的数据库是检索该分组下面的所有联系人,所以如果不使用数据库的话则需在tableviewGroup()方法的第二个try内改变给DataContacts赋的值可以自定义。可以采用之前用for循环给创建person类对象数组的方法
现在只需要添加person类和personContact类就可以运行了

package model;
import com.example.tableviewtest1.checkbox;

public class person {//构造分组类
    public String name;
    public checkbox cb=new checkbox();
    public person(String name)
    {

        this.name=name;

    }
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name=name;
    }
}

package model;

import com.example.tableviewtest1.checkbox;

public class personContact {//构造联系人类
    public String name;
    public String tel;
    public String org;
    public String email;
    public Integer uid;
    public checkbox cb=new checkbox();
    public personContact(String name,String tel,String org,String email,Integer uid)
    {

        this.name=name;
        this.tel=tel;
        this.org=org;
        this.email=email;
        this.uid=uid;
    }
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name=name;
    }
    public String getTel(){
        return this.tel;
    }
    public void setTel(String tel){
        this.tel=tel;
    }
    public String getOrg(){
        return this.org;
    }
    public  void setOrg(String org){
        this.org=org;
    }
    public String getEmail(){
        return this.email;
    }
    public void setEmail(String email){
        this.email=email;
    }
    public Integer getUid(){
        return this.uid;
    }
    public void setUid(){
        this.uid=uid;
    }
}

注意这里作者放的是model包。
因为我这边的是先刷新联系人分组点击分组就可以刷新出对应的联系人
刷新的话主要是两种办法

tableviewContacts();
tableContact.refresh();

第一种是再运行一遍tableview方法,第二种是refresh刷新法。因为只是简单地修改了属性,所以用refresh并不能刷新因为修改单个tablecell而产生的变化。
最后是作者的FXML文件

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

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="862.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.tableviewtest1.HelloController">
   <children>
      <TableView fx:id="tableGroup" prefHeight="557.0" prefWidth="200.0" style="-fx-background-color: derive(pink, +30%);" stylesheets="@../../../transparent.css">
         <columns>
            <TableColumn fx:id="name" prefWidth="134.0" text="联系组" />
            <TableColumn fx:id="checklist" prefWidth="65.0" text="选择">
               <styleClass>
                  <String fx:value=".table-row-cell" />
                  <String fx:value="}.table-view .column-header-background" />
               </styleClass></TableColumn>
         </columns></TableView>
      <Button fx:id="delete" layoutX="378.0" layoutY="7.0" mnemonicParsing="false" onAction="#deleteItem" text="删除组" />
      <Button fx:id="Multiselect" layoutX="313.0" layoutY="7.0" mnemonicParsing="false" onAction="#select" text="编辑组" />
      <Button fx:id="output" layoutX="744.0" layoutY="484.0" mnemonicParsing="false" onAction="#outputItem" text="Vcard导出" />
      <TableView fx:id="tableContact" layoutX="199.0" layoutY="117.0" prefHeight="319.0" prefWidth="664.0" stylesheets="@../../../transparent1.css">
        <columns>
          <TableColumn fx:id="name1" prefWidth="86.0" text="姓名" />
          <TableColumn fx:id="tel" prefWidth="88.0" text="电话" />
            <TableColumn fx:id="org" prefWidth="90.0" text="单位" />
            <TableColumn fx:id="email" prefWidth="170.0" text="邮箱" />
            <TableColumn fx:id="uid" prefWidth="64.0" text="ID" />
            <TableColumn fx:id="selectColumn" prefWidth="98.0" text="选择" />
        </columns>
      </TableView>
      <TextField fx:id="nameText" layoutX="207.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="联系人姓名" />
      <TextField fx:id="telText" layoutX="302.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="联系人电话" />
      <TextField fx:id="orgText" layoutX="396.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="联系人单位" />
      <TextField fx:id="emailText" layoutX="491.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="联系人邮箱" />
      <Button fx:id="deleteContacts" layoutX="590.0" layoutY="7.0" mnemonicParsing="false" onAction="#deleteC" text="删除联系人信息" />
      <Button fx:id="changeContacts" layoutX="467.0" layoutY="7.0" mnemonicParsing="false" onAction="#changeC" text="修改联系人信息" />
      <Button fx:id="addContacts" layoutX="207.0" layoutY="7.0" mnemonicParsing="false" onAction="#addC" text="添加联系人" />
      <TextField fx:id="groupText" layoutX="586.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="联系人分组" />
      <Button fx:id="nameOfSelect" layoutX="805.0" layoutY="54.0" mnemonicParsing="false" onAction="#setSelectTableView" text="搜索" />
      <TextField fx:id="getNameOfSelect" layoutX="701.0" layoutY="54.0" prefHeight="30.0" prefWidth="95.0" promptText="搜索联系人" />
      <Button fx:id="inputVcard" layoutX="612.0" layoutY="484.0" mnemonicParsing="false" onAction="#InputVCard" text="VCard导入" />
      <Button fx:id="csvOutput" layoutX="513.0" layoutY="484.0" mnemonicParsing="false" onAction="#CsvOutput" text="csv导出" />
      <Button fx:id="csvInput" layoutX="418.0" layoutY="484.0" mnemonicParsing="false" onAction="#CsvInput" text="csv导入" />
   </children>
</AnchorPane>

如果你下载了JavaFX Sence Builder 2.0你可以直接打开作者的FXML文件,然后把对应的控件全部复制到你的代码里面,放在你的类里面。

 类似资料: