Tableview整数排序有问题吗?

时间:2014-11-21 13:16:00

标签: javafx tableview

我有一个tableview,其中一个列包含Integer值:

  • 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 ..所以更新的问题是,如何在表列上创建一个新的排序功能,以便它排序为整数,即使它存在& #39;中的字符串?

2 个答案:

答案 0 :(得分:8)

您的值为String s,因此按字典顺序排序;因为字符'4'在字符'9'之前,'444'在'9'之前。

如果您将这些字段设为整数字段,那么它们将按数字排序。这里使用正确键入的TableViewTableColumn来代替原始类型是有帮助的。

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