表视图整数排序错误



我有一个表视图,我的一列由整数值组成:

  • 1
  • 444-9

如果我对这一列进行排序,我希望 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 s,因此它们按字典顺序排序; 由于字符"4"在字符"9"之前,因此"444"在"9"之前。

如果将这些字段设置为整数字段,则它们将按数字排序。在这里,使用正确键入的 TableView s 和 TableColumn s 而不是原始类型很有帮助。

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);
}
}

您可以创建一个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;
    }
}

最新更新