防止 ObservableList 中的重复条目
Preventing duplicate entries in ObservableList
我好像不太对劲。我有一个包含类别项目的 listbox
。我还有一个数据模型,它定义了 ID、姓名、姓氏、类别……和一个保存数据的 ObservableList
。我正在尝试更新现有对象,以防用户单击 listbox
中的同一项目并更改姓名、姓氏。
这是我的代码:
public class FXMLDocController implements Initializable {
ObservableList<String> listitems = FXCollections.observableArrayList(
"Visual Basic", "ASP.net", "JavaFX");
ObservableList<Persons> personData = FXCollections.observableArrayList();
Persons pp = new Persons();
private Label label;
@FXML
private TextField txtName;
@FXML
private TextField txtLastName;
@FXML
private Button btnSave;
@FXML
private TextArea txtArea;
@FXML
private ListView<String> listview = new ListView<String>();
@FXML
private Button btnTest;
@FXML
private Label lblCategory;
@FXML
private Label lblIndex;
@Override
public void initialize(URL url, ResourceBundle rb) {
listview.setItems(listitems);
}
@FXML
private void handleSave(ActionEvent event) {
String category = lblCategory.getText();
boolean duplicate = false;
//Add data. Check first if personData is empty
if (personData.isEmpty()){
pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText());
personData.add(pp);
}else{
for(int i = 0 ; i<personData.size() ; i ++){
if(Integer.toString(personData.get(i).getID()).equals(lblIndex.getText())){
duplicate = true;
}else{
duplicate = false;
}
}
System.out.println(duplicate);
if (duplicate == false){
pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText());
personData.add(pp);
}else{
System.out.println("Duplicate");
// Do Update later.
}
}
//Show data to Test
System.out.println("-- START OF LIST --");
for (Persons person : personData){
System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " " );
}
System.err.println(" ");
}
@FXML
private void handleListClick(MouseEvent event) {
lblCategory.setText(listview.getSelectionModel().getSelectedItem());
lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex()));
}
}
如果我在 listbox
上的一个项目上单击多次它工作正常..但是如果我单击 Visual Basic,然后 ASP.net 返回到 Visual Basic 它仍然接受它。 :(
需要建议和帮助。请
这是根据 Phil 的建议编写的代码
@FXML
private void handleSave(ActionEvent event) {
String category = lblCategory.getText();
boolean duplicate = false;
int x = 0;
//Add data
Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), category, txtName.getText(), txtLastName.getText());
if (!personData.contains(newPerson)) {
personData.add(newPerson);
}else{
System.out.println("Duplicate!");
}
//Show data
System.out.println("-- START OF LIST --");
for (Persons person : personData){
System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " " );
}
}
这是我的人物 Class
public class Persons {
private SimpleIntegerProperty id;
private SimpleStringProperty name;
private SimpleStringProperty lastname;
private SimpleStringProperty category;
public Persons(){}
public Persons(int id, String category, String name, String lastname){
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
this.category = new SimpleStringProperty(category);
}
public Persons(String name, String lastname){
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
}
@Override
public boolean equals(Object o){
if (o == this) return true;
if (!(o instanceof Persons)){
return false;
}
Persons persons = (Persons) o;
return persons.id.equals(id) &&
persons.name.equals(name) &&
persons.lastname.equals(lastname) &&
persons.category.equals(category);
}
//SETTERS
public void setID(int id) {
this.id = new SimpleIntegerProperty(id);
}
public void setName(String name) {
this.name = new SimpleStringProperty(name);
}
public void setLastname(String lastname) {
this.lastname = new SimpleStringProperty(lastname);
}
public void setCategory(String category) {
this.category = new SimpleStringProperty(category);
}
//GETTERS
public int getID() {
return id.getValue();
}
public String getName() {
return name.getValue();
}
public String getLastname() {
return lastname.getValue();
}
public String getCategory(){
return category.getValue();
}
// PROPERTIES
public SimpleIntegerProperty idProperty(){
return this.id;
}
public SimpleStringProperty nameProperty(){
return this.name;
}
public SimpleStringProperty lastnameProperty(){
return this.lastname;
}
public SimpleStringProperty categoryProperty(){
return this.category;
}
}
好的,这看起来不错。 equals 实现中的一件小事:
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Persons)) {
return false;
}
Persons persons = (Persons) o;
// persons.id.equals() leads to the default implementation in Object
// --> instead use this one.
// The Property classes have their own isEqualTo method
// with get(), you will get your simple boolean from the returned BooleanBinding
return persons.id.isEqualTo(id).get() &&
persons.name.isEqualTo(name).get() &&
persons.lastname.isEqualTo(lastname).get() &&
persons.category.isEqualTo(category).get();
}
Object 的默认 equals 实现只是比较它是否是同一个实例。我们正在创建一个新实例并检查 contains(...) 列表是否包含 Persons.
这是我用来测试它的全部代码:
public class Main extends Application {
private ObservableList<String> listitems = FXCollections.observableArrayList("Visual Basic", "ASP.net", "JavaFX");
private ObservableList<Persons> personData = FXCollections.observableArrayList();
private TextField txtName = new TextField();
private TextField txtLastName = new TextField();
private Button btnSave = new Button("save");
private ListView<String> listview = new ListView<>();
private Label lblCategory = new Label();
private Label lblIndex = new Label();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
listview.setItems(listitems);
listview.setOnMouseClicked(this::handleListClick);
btnSave.setOnAction(this::handleSave);
VBox vb = new VBox(new HBox(5, new Label("Index:"), lblIndex),
new HBox(5, new Label("Category:"), lblCategory),
new HBox(5, new Label("Name:"), txtName),
new HBox(5, new Label("Last name:"), txtLastName)
);
BorderPane bp = new BorderPane();
bp.setLeft(listview);
bp.setCenter(vb);
bp.setRight(btnSave);
Scene scene = new Scene(bp, 600, 400);
stage.setScene(scene);
stage.show();
}
private void handleSave(ActionEvent event) {
Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), lblCategory.getText(), txtName.getText(), txtLastName.getText());
if (!personData.contains(newPerson)) {
personData.add(newPerson);
} else {
System.out.println("Duplicate!");
}
System.out.println("-- START OF LIST --");
for (Persons person : personData) {
System.out.println(person);
}
}
private void handleListClick(MouseEvent event) {
System.out.println("click");
lblCategory.setText(listview.getSelectionModel().getSelectedItem());
lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex()));
}
public class Persons {
SimpleIntegerProperty id;
SimpleStringProperty name;
SimpleStringProperty lastname;
SimpleStringProperty category;
Persons(int id, String category, String name, String lastname) {
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
this.category = new SimpleStringProperty(category);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Persons)) {
return false;
}
Persons persons = (Persons) o;
// persons.id.equals() leads to the default implementation in Object
// --> instead use this one.
// The Property classes have their own isEqualTo method
// with get(), you will get your simple boolean from the returned BooleanBinding
return persons.id.isEqualTo(id).get() &&
persons.name.isEqualTo(name).get() &&
persons.lastname.isEqualTo(lastname).get() &&
persons.category.isEqualTo(category).get();
}
@Override
public String toString() {
return "Persons{" +
"id=" + id +
", name=" + name +
", lastname=" + lastname +
", category=" + category +
'}';
}
}
}
我好像不太对劲。我有一个包含类别项目的 listbox
。我还有一个数据模型,它定义了 ID、姓名、姓氏、类别……和一个保存数据的 ObservableList
。我正在尝试更新现有对象,以防用户单击 listbox
中的同一项目并更改姓名、姓氏。
这是我的代码:
public class FXMLDocController implements Initializable {
ObservableList<String> listitems = FXCollections.observableArrayList(
"Visual Basic", "ASP.net", "JavaFX");
ObservableList<Persons> personData = FXCollections.observableArrayList();
Persons pp = new Persons();
private Label label;
@FXML
private TextField txtName;
@FXML
private TextField txtLastName;
@FXML
private Button btnSave;
@FXML
private TextArea txtArea;
@FXML
private ListView<String> listview = new ListView<String>();
@FXML
private Button btnTest;
@FXML
private Label lblCategory;
@FXML
private Label lblIndex;
@Override
public void initialize(URL url, ResourceBundle rb) {
listview.setItems(listitems);
}
@FXML
private void handleSave(ActionEvent event) {
String category = lblCategory.getText();
boolean duplicate = false;
//Add data. Check first if personData is empty
if (personData.isEmpty()){
pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText());
personData.add(pp);
}else{
for(int i = 0 ; i<personData.size() ; i ++){
if(Integer.toString(personData.get(i).getID()).equals(lblIndex.getText())){
duplicate = true;
}else{
duplicate = false;
}
}
System.out.println(duplicate);
if (duplicate == false){
pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText());
personData.add(pp);
}else{
System.out.println("Duplicate");
// Do Update later.
}
}
//Show data to Test
System.out.println("-- START OF LIST --");
for (Persons person : personData){
System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " " );
}
System.err.println(" ");
}
@FXML
private void handleListClick(MouseEvent event) {
lblCategory.setText(listview.getSelectionModel().getSelectedItem());
lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex()));
}
}
如果我在 listbox
上的一个项目上单击多次它工作正常..但是如果我单击 Visual Basic,然后 ASP.net 返回到 Visual Basic 它仍然接受它。 :(
需要建议和帮助。请
这是根据 Phil 的建议编写的代码
@FXML
private void handleSave(ActionEvent event) {
String category = lblCategory.getText();
boolean duplicate = false;
int x = 0;
//Add data
Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), category, txtName.getText(), txtLastName.getText());
if (!personData.contains(newPerson)) {
personData.add(newPerson);
}else{
System.out.println("Duplicate!");
}
//Show data
System.out.println("-- START OF LIST --");
for (Persons person : personData){
System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " " );
}
}
这是我的人物 Class
public class Persons {
private SimpleIntegerProperty id;
private SimpleStringProperty name;
private SimpleStringProperty lastname;
private SimpleStringProperty category;
public Persons(){}
public Persons(int id, String category, String name, String lastname){
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
this.category = new SimpleStringProperty(category);
}
public Persons(String name, String lastname){
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
}
@Override
public boolean equals(Object o){
if (o == this) return true;
if (!(o instanceof Persons)){
return false;
}
Persons persons = (Persons) o;
return persons.id.equals(id) &&
persons.name.equals(name) &&
persons.lastname.equals(lastname) &&
persons.category.equals(category);
}
//SETTERS
public void setID(int id) {
this.id = new SimpleIntegerProperty(id);
}
public void setName(String name) {
this.name = new SimpleStringProperty(name);
}
public void setLastname(String lastname) {
this.lastname = new SimpleStringProperty(lastname);
}
public void setCategory(String category) {
this.category = new SimpleStringProperty(category);
}
//GETTERS
public int getID() {
return id.getValue();
}
public String getName() {
return name.getValue();
}
public String getLastname() {
return lastname.getValue();
}
public String getCategory(){
return category.getValue();
}
// PROPERTIES
public SimpleIntegerProperty idProperty(){
return this.id;
}
public SimpleStringProperty nameProperty(){
return this.name;
}
public SimpleStringProperty lastnameProperty(){
return this.lastname;
}
public SimpleStringProperty categoryProperty(){
return this.category;
}
}
好的,这看起来不错。 equals 实现中的一件小事:
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Persons)) {
return false;
}
Persons persons = (Persons) o;
// persons.id.equals() leads to the default implementation in Object
// --> instead use this one.
// The Property classes have their own isEqualTo method
// with get(), you will get your simple boolean from the returned BooleanBinding
return persons.id.isEqualTo(id).get() &&
persons.name.isEqualTo(name).get() &&
persons.lastname.isEqualTo(lastname).get() &&
persons.category.isEqualTo(category).get();
}
Object 的默认 equals 实现只是比较它是否是同一个实例。我们正在创建一个新实例并检查 contains(...) 列表是否包含 Persons.
这是我用来测试它的全部代码:
public class Main extends Application {
private ObservableList<String> listitems = FXCollections.observableArrayList("Visual Basic", "ASP.net", "JavaFX");
private ObservableList<Persons> personData = FXCollections.observableArrayList();
private TextField txtName = new TextField();
private TextField txtLastName = new TextField();
private Button btnSave = new Button("save");
private ListView<String> listview = new ListView<>();
private Label lblCategory = new Label();
private Label lblIndex = new Label();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
listview.setItems(listitems);
listview.setOnMouseClicked(this::handleListClick);
btnSave.setOnAction(this::handleSave);
VBox vb = new VBox(new HBox(5, new Label("Index:"), lblIndex),
new HBox(5, new Label("Category:"), lblCategory),
new HBox(5, new Label("Name:"), txtName),
new HBox(5, new Label("Last name:"), txtLastName)
);
BorderPane bp = new BorderPane();
bp.setLeft(listview);
bp.setCenter(vb);
bp.setRight(btnSave);
Scene scene = new Scene(bp, 600, 400);
stage.setScene(scene);
stage.show();
}
private void handleSave(ActionEvent event) {
Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), lblCategory.getText(), txtName.getText(), txtLastName.getText());
if (!personData.contains(newPerson)) {
personData.add(newPerson);
} else {
System.out.println("Duplicate!");
}
System.out.println("-- START OF LIST --");
for (Persons person : personData) {
System.out.println(person);
}
}
private void handleListClick(MouseEvent event) {
System.out.println("click");
lblCategory.setText(listview.getSelectionModel().getSelectedItem());
lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex()));
}
public class Persons {
SimpleIntegerProperty id;
SimpleStringProperty name;
SimpleStringProperty lastname;
SimpleStringProperty category;
Persons(int id, String category, String name, String lastname) {
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
this.lastname = new SimpleStringProperty(lastname);
this.category = new SimpleStringProperty(category);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Persons)) {
return false;
}
Persons persons = (Persons) o;
// persons.id.equals() leads to the default implementation in Object
// --> instead use this one.
// The Property classes have their own isEqualTo method
// with get(), you will get your simple boolean from the returned BooleanBinding
return persons.id.isEqualTo(id).get() &&
persons.name.isEqualTo(name).get() &&
persons.lastname.isEqualTo(lastname).get() &&
persons.category.isEqualTo(category).get();
}
@Override
public String toString() {
return "Persons{" +
"id=" + id +
", name=" + name +
", lastname=" + lastname +
", category=" + category +
'}';
}
}
}