我有一个tableview,其中一个列包含Integer值:
如果我对这个专栏进行排序,我认为444是"最高"数字和因此是第一行,但JavaFX认为9更高?
任何提示?
MVCE:
public class TableViewTEST extends Application {
private TableView table = new TableView();
final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("1", "Smith", "jacob.smith@example.com"),
new Person("9", "Johnson", "isabella.johnson@example.com"),
new Person("444", "Williams", "ethan.williams@example.com")
);
@Override
public void start(Stage stage) {
table.getItems().addAll(data);
Scene scene = new Scene(new Group());
stage.setTitle(
"Table View Sample");
stage.setWidth(
300);
stage.setHeight(
500);
final Label label = new Label("Address Book");
label.setFont(
new Font("Arial", 20));
TableColumn firstNameCol = new TableColumn("First");
TableColumn lastNameCol = new TableColumn("Last Name");
TableColumn emailCol = new TableColumn("Email");
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName")
);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("lastName")
);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email")
);
table.getColumns()
.addAll(firstNameCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(
5);
vbox.setPadding(
new Insets(10, 0, 0, 10));
vbox.getChildren()
.addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
修改的
好吧,我发现原因是因为我在模型中使用了String ..所以更新的问题是,如何在表列上创建一个新的排序功能,以便它排序为整数,即使它存在& #39;中的字符串?
答案 0 :(得分:8)
您的值为String
s,因此按字典顺序排序;因为字符'4'在字符'9'之前,'444'在'9'之前。
如果您将这些字段设为整数字段,那么它们将按数字排序。这里使用正确键入的TableView
和TableColumn
来代替原始类型是有帮助的。
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSortTest extends Application {
private TableView<Person> table = new TableView<>();
final ObservableList<Person> data = FXCollections.observableArrayList(
new Person(1, "Smith", "jacob.smith@example.com"),
new Person(9, "Johnson", "isabella.johnson@example.com"),
new Person(444, "Williams", "ethan.williams@example.com")
);
@Override
public void start(Stage stage) {
table.getItems().addAll(data);
Scene scene = new Scene(new Group());
stage.setTitle(
"Table View Sample");
stage.setWidth(
300);
stage.setHeight(
500);
final Label label = new Label("Address Book");
label.setFont(
new Font("Arial", 20));
TableColumn<Person, Integer> idCol = new TableColumn<>("Id");
TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
idCol.setCellValueFactory(
new PropertyValueFactory<Person, Integer>("id")
);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("name")
);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email")
);
table.getColumns()
.addAll(idCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(
5);
vbox.setPadding(
new Insets(10, 0, 0, 10));
vbox.getChildren()
.addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final IntegerProperty id = new SimpleIntegerProperty(this, "id");
private final StringProperty name = new SimpleStringProperty(this, "name");
private final StringProperty email = new SimpleStringProperty(this, "email");
public Person(int id, String name, String email) {
this.id.set(id);
this.name.set(name);
this.email.set(email);
}
public final IntegerProperty idProperty() {
return this.id;
}
public final int getId() {
return this.idProperty().get();
}
public final void setId(final int id) {
this.idProperty().set(id);
}
public final StringProperty nameProperty() {
return this.name;
}
public final java.lang.String getName() {
return this.nameProperty().get();
}
public final void setName(final java.lang.String name) {
this.nameProperty().set(name);
}
public final StringProperty emailProperty() {
return this.email;
}
public final java.lang.String getEmail() {
return this.emailProperty().get();
}
public final void setEmail(final java.lang.String email) {
this.emailProperty().set(email);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
答案 1 :(得分:2)
您可以创建Comparator
:
firstNameCol.setComparator(new CustomComparator());
编辑
假设您的列中有String
类型,就像它最初发布的那样,并且您希望在数字上对其进行排序,尝试解析所有字符串,以防万一是非整数字符串按字典顺序对这些进行排序,这将是有效的Comparator
:
private class CustomComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
if (o1 == null && o2 == null) return 0;
if (o1 == null) return -1;
if (o2 == null) return 1;
Integer i1=null;
try{ i1=Integer.valueOf(o1); } catch(NumberFormatException ignored){}
Integer i2=null;
try{ i2=Integer.valueOf(o2); } catch(NumberFormatException ignored){}
if(i1==null && i2==null) return o1.compareTo(o2);
if(i1==null) return -1;
if(i2==null) return 1;
return i1-i2;
}
}