我有一个简单的JavaFX TableView,它由JPA数据库查询填充。我有一个列设置为可编辑,并且有效。但是,在单元格中进行更改后,只要我对TableView进行排序甚至导航,它就会消失。另外,您如何将这些编辑保留回数据库?
这是FXML文件及其控制器:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.IXS.synergyixs.ingestor.ViewUsersController">
<stylesheets>
<URL value="@/styles/IssueTrackingLite.css" />
</stylesheets>
<children>
<TableView fx:id="loginsTable" editable="true" prefHeight="593.0" prefWidth="794.0">
<columns>
<TableColumn fx:id="idCol" editable="false" text="Id">
</TableColumn>
<TableColumn fx:id="loginCol" text="Login">
</TableColumn>
<TableColumn fx:id="partyCol" editable="false" text="Party ID">
</TableColumn>
<TableColumn fx:id="creatorCol" editable="false" text="Creator ID">
</TableColumn>
<TableColumn fx:id="modifierCol" editable="false" text="Modifier ID">
</TableColumn>
</columns>
</TableView>
</children>
</AnchorPane>
控制器:
package com.IXS.synergyixs.ingestor;
import com.IXS.synergyixs.ingestor.data.Usr;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.Pane;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* FXML Controller class
*
* @author Owner
*/
public class ViewUsersController implements Initializable {
public EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.mycompany_SynergyIXS-Ingestor_jar_1.0-SNAPSHOTPU");
public EntityManager em = emf.createEntityManager();
public ObservableList<Usr> tableData;
public Usr currentUsr;
/**
* Initializes the controller class.
*/
@FXML
private Pane rootPane;
@FXML
private TableView<Usr> loginsTable;
@FXML
private TableColumn<Usr, Number> idCol;
@FXML
private TableColumn<Usr, String> loginCol;
@FXML
private TableColumn<Usr, Number> partyCol;
@FXML
private TableColumn<Usr, Number> creatorCol;
@FXML
private TableColumn<Usr, Integer> modifierCol;
@Override
public void initialize(URL location, ResourceBundle resources) {
/* to verify query is returning data
for (Usr u : userList) {
System.out.println(u.getId() + " " + u.getLogin());
}
*/
idCol.setCellValueFactory(new PropertyValueFactory<>("id"));
loginCol.setCellValueFactory(new PropertyValueFactory<>("login"));
loginCol.setCellFactory(TextFieldTableCell.forTableColumn());
partyCol.setCellValueFactory(new PropertyValueFactory<>("partyId"));
creatorCol.setCellValueFactory(new PropertyValueFactory<>("creatorId"));
modifierCol.setCellValueFactory(new PropertyValueFactory<>("modifierId"));
updateUserList();
loginsTable.setItems(tableData);
}
public void updateUserList() {
List<Usr> userList = em.createNamedQuery("Usr.findAll").getResultList();
if (tableData == null) {
tableData = FXCollections.observableArrayList(userList);
} else {
tableData.clear();
tableData.addAll(userList);
}
}
/*
public void saveUser()
{
em.getTransaction().begin();
em.persist(currentUsr);
em.getTransaction().commit();
updateUserList();
}
*/
}
Usr课程:
package com.IXS.synergyixs.ingestor.data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* @author Owner
*/
@Entity
@Table(name = "USR", catalog = "", schema = "ADMIN")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Usr.findAll", query = "SELECT u FROM Usr u")
, @NamedQuery(name = "Usr.findById", query = "SELECT u FROM Usr u WHERE u.id = :id")
, @NamedQuery(name = "Usr.findAllLogin", query = "SELECT u.login FROM Usr u")
, @NamedQuery(name = "Usr.findByLogin", query = "SELECT u FROM Usr u WHERE u.login = :login")
, @NamedQuery(name = "Usr.findByPwd", query = "SELECT u FROM Usr u WHERE u.pwd = :pwd")
, @NamedQuery(name = "Usr.findByPartyId", query = "SELECT u FROM Usr u WHERE u.partyId = :partyId")
, @NamedQuery(name = "Usr.findByCreatorId", query = "SELECT u FROM Usr u WHERE u.creatorId = :creatorId")
, @NamedQuery(name = "Usr.findByCreationDttm", query = "SELECT u FROM Usr u WHERE u.creationDttm = :creationDttm")
, @NamedQuery(name = "Usr.findByModifierId", query = "SELECT u FROM Usr u WHERE u.modifierId = :modifierId")
, @NamedQuery(name = "Usr.findByModificationDttm", query = "SELECT u FROM Usr u WHERE u.modificationDttm = :modificationDttm")})
public class Usr implements Serializable {
private static final long serialVersionUID = 1L;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Id
@Basic(optional = false)
@Column(name = "ID")
private BigDecimal id;
@Basic(optional = false)
@Column(name = "LOGIN")
private String login;
@Basic(optional = false)
@Column(name = "PWD")
private String pwd;
@Column(name = "PARTY_ID")
private BigInteger partyId;
@Basic(optional = false)
@Column(name = "CREATOR_ID")
private BigInteger creatorId;
@Basic(optional = false)
@Column(name = "CREATION_DTTM")
@Temporal(TemporalType.TIMESTAMP)
private Date creationDttm;
@Basic(optional = false)
@Column(name = "MODIFIER_ID")
private BigInteger modifierId;
@Basic(optional = false)
@Column(name = "MODIFICATION_DTTM")
@Temporal(TemporalType.TIMESTAMP)
private Date modificationDttm;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "usr")
private List<UsrAppRole> usrAppRoleList;
public Usr() {
}
public Usr(BigDecimal id) {
this.id = id;
}
public Usr(BigDecimal id, String login, String pwd, BigInteger creatorId, Date creationDttm, BigInteger modifierId, Date modificationDttm) {
this.id = id;
this.login = login;
this.pwd = pwd;
this.creatorId = creatorId;
this.creationDttm = creationDttm;
this.modifierId = modifierId;
this.modificationDttm = modificationDttm;
}
public BigDecimal getId() {
return id;
}
public void setId(BigDecimal id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public BigInteger getPartyId() {
return partyId;
}
public void setPartyId(BigInteger partyId) {
this.partyId = partyId;
}
public BigInteger getCreatorId() {
return creatorId;
}
public void setCreatorId(BigInteger creatorId) {
this.creatorId = creatorId;
}
public Date getCreationDttm() {
return creationDttm;
}
public void setCreationDttm(Date creationDttm) {
this.creationDttm = creationDttm;
}
public BigInteger getModifierId() {
return modifierId;
}
public void setModifierId(BigInteger modifierId) {
this.modifierId = modifierId;
}
public Date getModificationDttm() {
return modificationDttm;
}
public void setModificationDttm(Date modificationDttm) {
this.modificationDttm = modificationDttm;
}
@XmlTransient
public List<UsrAppRole> getUsrAppRoleList() {
return usrAppRoleList;
}
public void setUsrAppRoleList(List<UsrAppRole> usrAppRoleList) {
this.usrAppRoleList = usrAppRoleList;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Usr)) {
return false;
}
Usr other = (Usr) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.mycompany.synergyixs.ingestor.Usr[ id=" + id + " ]";
}
}
答案 0 :(得分:1)
默认onEditCommit
处理程序假定表格的模型使用JavaFX properties pattern(请参阅TableView
documentation标题为&#34;编辑&#34;的部分)。由于您的Usr
类本质上是一个普通的JavaBean,没有属性访问器方法,因此默认处理程序简化为无操作。
您需要重构您的Usr
类,以便它使用JavaFX属性(有关在JPA实体中使用JavaFX属性的讨论,请参阅Using javafx.beans properties in model classes),或者设置onEditCommit
处理程序专栏:
loginCol.setOnEditCommit(e -> {
Usr usr = e.getRowValue();
usr.setLogin(e.getNewValue());
});
要将值存储在数据库中,请使用merge(...)
:
loginCol.setOnEditCommit(e -> {
Usr usr = e.getRowValue();
usr.setLogin(e.getNewValue());
// merge change to database:
Usr mergedUsr = em.merge(usr);
// ensure table has same reference as ORM cache:
loginsTable.set(e.getTablePosition().getRow(), mergedUsr);
});