JavaFX TableView Ignore empty cells when sorting










0















I have problems when sorting columns when there are empty cells.
I created a new Comparator for my codeMed column:



codeMed.setComparator(new Comparator<Integer>() 
@Override
public int compare(Integer o1, Integer o2)

if (o1 == null)return -1;
if (o2 == null) return -1;
return o1 < o2 ? -1 : o1 == o2 ? 0 :1;

);


At first, it seems to work fine:



It works !



But if I decide to sort a different column then sort the codeMed column this happens:



It doesn't work :(



I imagine the error is in the Comparator but I don't know what is the problem.



EDIT:
I want that the null values will always be at the bottom of the column.
I tried something like that:



if (codeMed.getSortType() == TableColumn.SortType.DESCENDING) 
return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
else if (codeMed.getSortType()==TableColumn.SortType.ASCENDING)
return (o1 != null ? o1 : Integer.MIN_VALUE) - (o2 != null ? o2 : Integer.MIN_VALUE);

return 0;


But it doesn't work :/ (Maybe because of the problem that Slaw suggests)



My solution:



Thank you very much Jai, I adapt your code just because I want to use it for 2 different collumns:
Comparator<Integer> integerComparator = new Comparator<>()
@Override
public int compare(Integer o1, Integer o2)
final boolean isDesc = tabInfosPatient.getSortOrder().get(0).getSortType() == TableColumn.SortType.DESCENDING;
if (o1 == null && o2 == null) return 0;
else if (o1 == null) return isDesc ? -1 : 1;
else if (o2 == null) return isDesc ? 1 : -1;
else return Integer.compare(o1, o2);

;










share|improve this question




























    0















    I have problems when sorting columns when there are empty cells.
    I created a new Comparator for my codeMed column:



    codeMed.setComparator(new Comparator<Integer>() 
    @Override
    public int compare(Integer o1, Integer o2)

    if (o1 == null)return -1;
    if (o2 == null) return -1;
    return o1 < o2 ? -1 : o1 == o2 ? 0 :1;

    );


    At first, it seems to work fine:



    It works !



    But if I decide to sort a different column then sort the codeMed column this happens:



    It doesn't work :(



    I imagine the error is in the Comparator but I don't know what is the problem.



    EDIT:
    I want that the null values will always be at the bottom of the column.
    I tried something like that:



    if (codeMed.getSortType() == TableColumn.SortType.DESCENDING) 
    return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
    else if (codeMed.getSortType()==TableColumn.SortType.ASCENDING)
    return (o1 != null ? o1 : Integer.MIN_VALUE) - (o2 != null ? o2 : Integer.MIN_VALUE);

    return 0;


    But it doesn't work :/ (Maybe because of the problem that Slaw suggests)



    My solution:



    Thank you very much Jai, I adapt your code just because I want to use it for 2 different collumns:
    Comparator<Integer> integerComparator = new Comparator<>()
    @Override
    public int compare(Integer o1, Integer o2)
    final boolean isDesc = tabInfosPatient.getSortOrder().get(0).getSortType() == TableColumn.SortType.DESCENDING;
    if (o1 == null && o2 == null) return 0;
    else if (o1 == null) return isDesc ? -1 : 1;
    else if (o2 == null) return isDesc ? 1 : -1;
    else return Integer.compare(o1, o2);

    ;










    share|improve this question


























      0












      0








      0








      I have problems when sorting columns when there are empty cells.
      I created a new Comparator for my codeMed column:



      codeMed.setComparator(new Comparator<Integer>() 
      @Override
      public int compare(Integer o1, Integer o2)

      if (o1 == null)return -1;
      if (o2 == null) return -1;
      return o1 < o2 ? -1 : o1 == o2 ? 0 :1;

      );


      At first, it seems to work fine:



      It works !



      But if I decide to sort a different column then sort the codeMed column this happens:



      It doesn't work :(



      I imagine the error is in the Comparator but I don't know what is the problem.



      EDIT:
      I want that the null values will always be at the bottom of the column.
      I tried something like that:



      if (codeMed.getSortType() == TableColumn.SortType.DESCENDING) 
      return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
      else if (codeMed.getSortType()==TableColumn.SortType.ASCENDING)
      return (o1 != null ? o1 : Integer.MIN_VALUE) - (o2 != null ? o2 : Integer.MIN_VALUE);

      return 0;


      But it doesn't work :/ (Maybe because of the problem that Slaw suggests)



      My solution:



      Thank you very much Jai, I adapt your code just because I want to use it for 2 different collumns:
      Comparator<Integer> integerComparator = new Comparator<>()
      @Override
      public int compare(Integer o1, Integer o2)
      final boolean isDesc = tabInfosPatient.getSortOrder().get(0).getSortType() == TableColumn.SortType.DESCENDING;
      if (o1 == null && o2 == null) return 0;
      else if (o1 == null) return isDesc ? -1 : 1;
      else if (o2 == null) return isDesc ? 1 : -1;
      else return Integer.compare(o1, o2);

      ;










      share|improve this question
















      I have problems when sorting columns when there are empty cells.
      I created a new Comparator for my codeMed column:



      codeMed.setComparator(new Comparator<Integer>() 
      @Override
      public int compare(Integer o1, Integer o2)

      if (o1 == null)return -1;
      if (o2 == null) return -1;
      return o1 < o2 ? -1 : o1 == o2 ? 0 :1;

      );


      At first, it seems to work fine:



      It works !



      But if I decide to sort a different column then sort the codeMed column this happens:



      It doesn't work :(



      I imagine the error is in the Comparator but I don't know what is the problem.



      EDIT:
      I want that the null values will always be at the bottom of the column.
      I tried something like that:



      if (codeMed.getSortType() == TableColumn.SortType.DESCENDING) 
      return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
      else if (codeMed.getSortType()==TableColumn.SortType.ASCENDING)
      return (o1 != null ? o1 : Integer.MIN_VALUE) - (o2 != null ? o2 : Integer.MIN_VALUE);

      return 0;


      But it doesn't work :/ (Maybe because of the problem that Slaw suggests)



      My solution:



      Thank you very much Jai, I adapt your code just because I want to use it for 2 different collumns:
      Comparator<Integer> integerComparator = new Comparator<>()
      @Override
      public int compare(Integer o1, Integer o2)
      final boolean isDesc = tabInfosPatient.getSortOrder().get(0).getSortType() == TableColumn.SortType.DESCENDING;
      if (o1 == null && o2 == null) return 0;
      else if (o1 == null) return isDesc ? -1 : 1;
      else if (o2 == null) return isDesc ? 1 : -1;
      else return Integer.compare(o1, o2);

      ;







      java javafx tableview






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 21:38







      Couldosh

















      asked Nov 14 '18 at 3:17









      CouldoshCouldosh

      549




      549






















          1 Answer
          1






          active

          oldest

          votes


















          2














          I'm surprised it even worked once. This is what I think would work well:



          codeMed.setComparator(new Comparator<Integer>() 
          @Override
          public int compare(Integer o1, Integer o2)
          return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);

          );


          This would assume any null value is treated as if it represents the largest possible int value. This would force it to move to the bottom of the list in an ascending sorted column, or at the top if it is in a descending sorted column. If the reverse is desired, switch Integer.MAX_VALUE to Integer.MIN_VALUE.



          What you did doesn't work because you have violated this:




          The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y,
          x)) for all x and y.
          (This implies that compare(x, y) must throw an
          exception if and only if compare(y, x) throws an exception.)




          An example of this violation is when o1 is 5 and o2 is null. In this case, compare(o1, o2) returns -1 and compare(o2, o1) returns -1 as well. One of them should return positive value while the other negative value, or both must return 0.



          Update



          This is what you need.



          public class Model 
          private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

          public Model(Integer v)
          this.v.setValue(v);


          public final ObjectProperty<Integer> vProperty()
          return this.v;


          public final Integer getV()
          return this.vProperty().get();


          public final void setV(final Integer v)
          this.vProperty().set(v);



          ObservableList<Model> list = FXCollections.observableArrayList();
          list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

          TableView<Model> tv = new TableView<>();
          TableColumn<Model, Integer> tc = new TableColumn<>();
          tc.setCellValueFactory(new PropertyValueFactory<>("v"));
          tv.getColumns().add(tc);
          tv.setItems(list);

          Comparator<Integer> ascComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MAX_VALUE) -
          (o2 != null ? o2 : Integer.MAX_VALUE);

          Comparator<Integer> descComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MIN_VALUE) -
          (o2 != null ? o2 : Integer.MIN_VALUE);

          @SuppressWarnings("unchecked")
          Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

          tc.comparatorProperty().bind(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
          .then(ascComparator)
          .otherwise(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
          .then(descComparator)
          .otherwise(defaultComparator)));


          Also, I would want to point out that while using Integer.MIN_VALUE and Integer.MAX_VALUE should work most of the time, there is a much higher risk of integer underflow and overflow problem, which I'm not sure if it's a problem for using comparators and comparables.



          If you want to be more safe, then do a bunch of if-else:



          Comparator<Integer> ascComparator = (o1, o2) -> 
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return -1;
          else if (o1 != null && o2 == null) return 1;
          else return Integer.compare(o1, o2);
          ;


          Update again



          After looking at what you attempted, I realized that this works:



          Comparator<Integer> comparator = (o1, o2) -> 
          final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
          else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
          else return Integer.compare(o1, o2);
          ;





          share|improve this answer

























          • Thank you for you response. Is there a way to always have the null values at the bottom?

            – Couldosh
            Nov 14 '18 at 3:49












          • I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

            – Slaw
            Nov 14 '18 at 4:07












          • I edited my question with a try to always have te null values at the bottom

            – Couldosh
            Nov 14 '18 at 4:55












          • @Couldosh Updated answer.

            – Jai
            Nov 14 '18 at 6:38










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53292696%2fjavafx-tableview-ignore-empty-cells-when-sorting%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          I'm surprised it even worked once. This is what I think would work well:



          codeMed.setComparator(new Comparator<Integer>() 
          @Override
          public int compare(Integer o1, Integer o2)
          return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);

          );


          This would assume any null value is treated as if it represents the largest possible int value. This would force it to move to the bottom of the list in an ascending sorted column, or at the top if it is in a descending sorted column. If the reverse is desired, switch Integer.MAX_VALUE to Integer.MIN_VALUE.



          What you did doesn't work because you have violated this:




          The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y,
          x)) for all x and y.
          (This implies that compare(x, y) must throw an
          exception if and only if compare(y, x) throws an exception.)




          An example of this violation is when o1 is 5 and o2 is null. In this case, compare(o1, o2) returns -1 and compare(o2, o1) returns -1 as well. One of them should return positive value while the other negative value, or both must return 0.



          Update



          This is what you need.



          public class Model 
          private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

          public Model(Integer v)
          this.v.setValue(v);


          public final ObjectProperty<Integer> vProperty()
          return this.v;


          public final Integer getV()
          return this.vProperty().get();


          public final void setV(final Integer v)
          this.vProperty().set(v);



          ObservableList<Model> list = FXCollections.observableArrayList();
          list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

          TableView<Model> tv = new TableView<>();
          TableColumn<Model, Integer> tc = new TableColumn<>();
          tc.setCellValueFactory(new PropertyValueFactory<>("v"));
          tv.getColumns().add(tc);
          tv.setItems(list);

          Comparator<Integer> ascComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MAX_VALUE) -
          (o2 != null ? o2 : Integer.MAX_VALUE);

          Comparator<Integer> descComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MIN_VALUE) -
          (o2 != null ? o2 : Integer.MIN_VALUE);

          @SuppressWarnings("unchecked")
          Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

          tc.comparatorProperty().bind(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
          .then(ascComparator)
          .otherwise(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
          .then(descComparator)
          .otherwise(defaultComparator)));


          Also, I would want to point out that while using Integer.MIN_VALUE and Integer.MAX_VALUE should work most of the time, there is a much higher risk of integer underflow and overflow problem, which I'm not sure if it's a problem for using comparators and comparables.



          If you want to be more safe, then do a bunch of if-else:



          Comparator<Integer> ascComparator = (o1, o2) -> 
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return -1;
          else if (o1 != null && o2 == null) return 1;
          else return Integer.compare(o1, o2);
          ;


          Update again



          After looking at what you attempted, I realized that this works:



          Comparator<Integer> comparator = (o1, o2) -> 
          final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
          else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
          else return Integer.compare(o1, o2);
          ;





          share|improve this answer

























          • Thank you for you response. Is there a way to always have the null values at the bottom?

            – Couldosh
            Nov 14 '18 at 3:49












          • I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

            – Slaw
            Nov 14 '18 at 4:07












          • I edited my question with a try to always have te null values at the bottom

            – Couldosh
            Nov 14 '18 at 4:55












          • @Couldosh Updated answer.

            – Jai
            Nov 14 '18 at 6:38















          2














          I'm surprised it even worked once. This is what I think would work well:



          codeMed.setComparator(new Comparator<Integer>() 
          @Override
          public int compare(Integer o1, Integer o2)
          return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);

          );


          This would assume any null value is treated as if it represents the largest possible int value. This would force it to move to the bottom of the list in an ascending sorted column, or at the top if it is in a descending sorted column. If the reverse is desired, switch Integer.MAX_VALUE to Integer.MIN_VALUE.



          What you did doesn't work because you have violated this:




          The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y,
          x)) for all x and y.
          (This implies that compare(x, y) must throw an
          exception if and only if compare(y, x) throws an exception.)




          An example of this violation is when o1 is 5 and o2 is null. In this case, compare(o1, o2) returns -1 and compare(o2, o1) returns -1 as well. One of them should return positive value while the other negative value, or both must return 0.



          Update



          This is what you need.



          public class Model 
          private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

          public Model(Integer v)
          this.v.setValue(v);


          public final ObjectProperty<Integer> vProperty()
          return this.v;


          public final Integer getV()
          return this.vProperty().get();


          public final void setV(final Integer v)
          this.vProperty().set(v);



          ObservableList<Model> list = FXCollections.observableArrayList();
          list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

          TableView<Model> tv = new TableView<>();
          TableColumn<Model, Integer> tc = new TableColumn<>();
          tc.setCellValueFactory(new PropertyValueFactory<>("v"));
          tv.getColumns().add(tc);
          tv.setItems(list);

          Comparator<Integer> ascComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MAX_VALUE) -
          (o2 != null ? o2 : Integer.MAX_VALUE);

          Comparator<Integer> descComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MIN_VALUE) -
          (o2 != null ? o2 : Integer.MIN_VALUE);

          @SuppressWarnings("unchecked")
          Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

          tc.comparatorProperty().bind(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
          .then(ascComparator)
          .otherwise(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
          .then(descComparator)
          .otherwise(defaultComparator)));


          Also, I would want to point out that while using Integer.MIN_VALUE and Integer.MAX_VALUE should work most of the time, there is a much higher risk of integer underflow and overflow problem, which I'm not sure if it's a problem for using comparators and comparables.



          If you want to be more safe, then do a bunch of if-else:



          Comparator<Integer> ascComparator = (o1, o2) -> 
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return -1;
          else if (o1 != null && o2 == null) return 1;
          else return Integer.compare(o1, o2);
          ;


          Update again



          After looking at what you attempted, I realized that this works:



          Comparator<Integer> comparator = (o1, o2) -> 
          final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
          else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
          else return Integer.compare(o1, o2);
          ;





          share|improve this answer

























          • Thank you for you response. Is there a way to always have the null values at the bottom?

            – Couldosh
            Nov 14 '18 at 3:49












          • I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

            – Slaw
            Nov 14 '18 at 4:07












          • I edited my question with a try to always have te null values at the bottom

            – Couldosh
            Nov 14 '18 at 4:55












          • @Couldosh Updated answer.

            – Jai
            Nov 14 '18 at 6:38













          2












          2








          2







          I'm surprised it even worked once. This is what I think would work well:



          codeMed.setComparator(new Comparator<Integer>() 
          @Override
          public int compare(Integer o1, Integer o2)
          return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);

          );


          This would assume any null value is treated as if it represents the largest possible int value. This would force it to move to the bottom of the list in an ascending sorted column, or at the top if it is in a descending sorted column. If the reverse is desired, switch Integer.MAX_VALUE to Integer.MIN_VALUE.



          What you did doesn't work because you have violated this:




          The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y,
          x)) for all x and y.
          (This implies that compare(x, y) must throw an
          exception if and only if compare(y, x) throws an exception.)




          An example of this violation is when o1 is 5 and o2 is null. In this case, compare(o1, o2) returns -1 and compare(o2, o1) returns -1 as well. One of them should return positive value while the other negative value, or both must return 0.



          Update



          This is what you need.



          public class Model 
          private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

          public Model(Integer v)
          this.v.setValue(v);


          public final ObjectProperty<Integer> vProperty()
          return this.v;


          public final Integer getV()
          return this.vProperty().get();


          public final void setV(final Integer v)
          this.vProperty().set(v);



          ObservableList<Model> list = FXCollections.observableArrayList();
          list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

          TableView<Model> tv = new TableView<>();
          TableColumn<Model, Integer> tc = new TableColumn<>();
          tc.setCellValueFactory(new PropertyValueFactory<>("v"));
          tv.getColumns().add(tc);
          tv.setItems(list);

          Comparator<Integer> ascComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MAX_VALUE) -
          (o2 != null ? o2 : Integer.MAX_VALUE);

          Comparator<Integer> descComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MIN_VALUE) -
          (o2 != null ? o2 : Integer.MIN_VALUE);

          @SuppressWarnings("unchecked")
          Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

          tc.comparatorProperty().bind(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
          .then(ascComparator)
          .otherwise(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
          .then(descComparator)
          .otherwise(defaultComparator)));


          Also, I would want to point out that while using Integer.MIN_VALUE and Integer.MAX_VALUE should work most of the time, there is a much higher risk of integer underflow and overflow problem, which I'm not sure if it's a problem for using comparators and comparables.



          If you want to be more safe, then do a bunch of if-else:



          Comparator<Integer> ascComparator = (o1, o2) -> 
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return -1;
          else if (o1 != null && o2 == null) return 1;
          else return Integer.compare(o1, o2);
          ;


          Update again



          After looking at what you attempted, I realized that this works:



          Comparator<Integer> comparator = (o1, o2) -> 
          final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
          else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
          else return Integer.compare(o1, o2);
          ;





          share|improve this answer















          I'm surprised it even worked once. This is what I think would work well:



          codeMed.setComparator(new Comparator<Integer>() 
          @Override
          public int compare(Integer o1, Integer o2)
          return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);

          );


          This would assume any null value is treated as if it represents the largest possible int value. This would force it to move to the bottom of the list in an ascending sorted column, or at the top if it is in a descending sorted column. If the reverse is desired, switch Integer.MAX_VALUE to Integer.MIN_VALUE.



          What you did doesn't work because you have violated this:




          The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y,
          x)) for all x and y.
          (This implies that compare(x, y) must throw an
          exception if and only if compare(y, x) throws an exception.)




          An example of this violation is when o1 is 5 and o2 is null. In this case, compare(o1, o2) returns -1 and compare(o2, o1) returns -1 as well. One of them should return positive value while the other negative value, or both must return 0.



          Update



          This is what you need.



          public class Model 
          private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

          public Model(Integer v)
          this.v.setValue(v);


          public final ObjectProperty<Integer> vProperty()
          return this.v;


          public final Integer getV()
          return this.vProperty().get();


          public final void setV(final Integer v)
          this.vProperty().set(v);



          ObservableList<Model> list = FXCollections.observableArrayList();
          list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

          TableView<Model> tv = new TableView<>();
          TableColumn<Model, Integer> tc = new TableColumn<>();
          tc.setCellValueFactory(new PropertyValueFactory<>("v"));
          tv.getColumns().add(tc);
          tv.setItems(list);

          Comparator<Integer> ascComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MAX_VALUE) -
          (o2 != null ? o2 : Integer.MAX_VALUE);

          Comparator<Integer> descComparator = (o1, o2) ->
          (o1 != null ? o1 : Integer.MIN_VALUE) -
          (o2 != null ? o2 : Integer.MIN_VALUE);

          @SuppressWarnings("unchecked")
          Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

          tc.comparatorProperty().bind(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
          .then(ascComparator)
          .otherwise(
          Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
          .then(descComparator)
          .otherwise(defaultComparator)));


          Also, I would want to point out that while using Integer.MIN_VALUE and Integer.MAX_VALUE should work most of the time, there is a much higher risk of integer underflow and overflow problem, which I'm not sure if it's a problem for using comparators and comparables.



          If you want to be more safe, then do a bunch of if-else:



          Comparator<Integer> ascComparator = (o1, o2) -> 
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return -1;
          else if (o1 != null && o2 == null) return 1;
          else return Integer.compare(o1, o2);
          ;


          Update again



          After looking at what you attempted, I realized that this works:



          Comparator<Integer> comparator = (o1, o2) -> 
          final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
          if (o1 == null && o2 == null) return 0;
          else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
          else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
          else return Integer.compare(o1, o2);
          ;






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 7:37

























          answered Nov 14 '18 at 3:39









          JaiJai

          5,82811231




          5,82811231












          • Thank you for you response. Is there a way to always have the null values at the bottom?

            – Couldosh
            Nov 14 '18 at 3:49












          • I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

            – Slaw
            Nov 14 '18 at 4:07












          • I edited my question with a try to always have te null values at the bottom

            – Couldosh
            Nov 14 '18 at 4:55












          • @Couldosh Updated answer.

            – Jai
            Nov 14 '18 at 6:38

















          • Thank you for you response. Is there a way to always have the null values at the bottom?

            – Couldosh
            Nov 14 '18 at 3:49












          • I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

            – Slaw
            Nov 14 '18 at 4:07












          • I edited my question with a try to always have te null values at the bottom

            – Couldosh
            Nov 14 '18 at 4:55












          • @Couldosh Updated answer.

            – Jai
            Nov 14 '18 at 6:38
















          Thank you for you response. Is there a way to always have the null values at the bottom?

          – Couldosh
          Nov 14 '18 at 3:49






          Thank you for you response. Is there a way to always have the null values at the bottom?

          – Couldosh
          Nov 14 '18 at 3:49














          I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

          – Slaw
          Nov 14 '18 at 4:07






          I'm not sure the magnitude of the return value matters, only if it's negative, zero, or positive. @Couldosh Return results that say nulls are greater than non-nulls and the nulls will go towards the bottom when sorted.

          – Slaw
          Nov 14 '18 at 4:07














          I edited my question with a try to always have te null values at the bottom

          – Couldosh
          Nov 14 '18 at 4:55






          I edited my question with a try to always have te null values at the bottom

          – Couldosh
          Nov 14 '18 at 4:55














          @Couldosh Updated answer.

          – Jai
          Nov 14 '18 at 6:38





          @Couldosh Updated answer.

          – Jai
          Nov 14 '18 at 6:38

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53292696%2fjavafx-tableview-ignore-empty-cells-when-sorting%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

          Museum of Modern and Contemporary Art of Trento and Rovereto