TableModel: Wo werden die RowSorter gespeichert?

Wie

:stuck_out_tongue_winking_eye:

Mit einer kleinen Änderung am SortOrderTableHeaderCellRenderer.

Der gordische Knoten war hier, dass ich in dem Model getColumnClass() nicht überschrieben hatte. :sweat_smile: Nun funktioniert es. Danke. Aber den Tipp hättest du (jemand) auch schon eher geben können, das hätte diese lange Diskussion erspart.

Hier kann dann zu.

Ja, schämen sollte ich mich. Oder jemand. :roll_eyes:

Vielleicht hattest du das nicht auf dem Schirm. Vielleicht aber doch. Vielleicht dachtest du, dass muss er aber selber wissen. Vielleicht auch, den ärgere ich (Schadenfreunde), dass er das nicht weiß, obwohl es doch eigentlich einfach ist. Vielleicht auch, der soll gefälligst mal die Docs komplett lesen, und nicht so blöde Fragen stellen. Vielleicht, vielleicht - man weiß es nicht. :eyes:

Fakt ist, es kann ganz einfach sein, wenn man weiß, wie:

  private interface ModelValue extends Comparable<Object> {
    void setValue(String value);
  }

  private static class ModelValueString implements ModelValue {
    private String value = "";

    @Override
    public void setValue(String value) {
      this.value = value;
    }

    @Override
    public int compareTo(Object o) {
      return value.compareTo(((ModelValueString) o).value);
    }

    @Override
    public boolean equals(Object o) {
      if (o == null || getClass() != o.getClass()) return false;

      ModelValueString that = (ModelValueString) o;
      return value.equals(that.value);
    }

    @Override
    public int hashCode() {
      return value.hashCode();
    }

    @Override
    public String toString() {
      return value;
    }
  }

  private static class ModelValuePercent implements ModelValue {
    private String value;
    private double doubleValue;

    @Override
    public void setValue(String value) {
      this.value = value;
      doubleValue = Double.parseDouble(value.substring(0, value.length() - 1));
    }

    @Override
    public int compareTo(Object o) {
      return Double.compare(doubleValue, ((ModelValuePercent) o).doubleValue);
    }

    @Override
    public boolean equals(Object o) {
      if (o == null || getClass() != o.getClass()) return false;

      ModelValuePercent that = (ModelValuePercent) o;
      return Double.compare(doubleValue, that.doubleValue) == 0;
    }

    @Override
    public int hashCode() {
      return Double.hashCode(doubleValue);
    }

    @Override
    public String toString() {
      return value;
    }
  }

  private static class ModelValueByte implements ModelValue {
    private String value;
    private long longValue;

    @Override
    public void setValue(String value) {
      this.value = value;
      Object[][] temp = {
        {"KiB", 1024L},
        {"MiB", 1024L * 1024L},
        {"GiB", 1024L * 1024L * 1024L},
        {"kB", 1000L},
        {"MB", 1000L * 1000L},
        {"GB", 1000L * 1000L * 1000L},
        {"B", 1L},
        {"", 1L}
      };
      for (Object[] os : temp) {
        if (value.endsWith((String) os[0])) {
          longValue =
              (long)
                  (Double.parseDouble(
                          value.substring(0, value.length() - ((String) os[0]).length()))
                      * (Long) os[1]);
          break;
        }
      }
    }

    @Override
    public int compareTo(Object o) {
      return Long.compare(longValue, ((ModelValueByte) o).longValue);
    }

    @Override
    public boolean equals(Object o) {
      if (o == null || getClass() != o.getClass()) return false;

      ModelValueByte that = (ModelValueByte) o;
      return longValue == that.longValue;
    }

    @Override
    public int hashCode() {
      return Long.hashCode(longValue);
    }

    @Override
    public String toString() {
      return value;
    }
  }

  private static class ModelRow {
    private final ModelValueString containerId = new ModelValueString();
    private final ModelValueString name = new ModelValueString();
    private final ModelValuePercent cpu = new ModelValuePercent();
    private final ModelValueByte memUsage = new ModelValueByte();
    private final ModelValueByte limit = new ModelValueByte();
    private final ModelValuePercent mem = new ModelValuePercent();
    private final ModelValueByte netI = new ModelValueByte();
    private final ModelValueByte netO = new ModelValueByte();
    private final ModelValueByte blockI = new ModelValueByte();
    private final ModelValueByte blockO = new ModelValueByte();
    private final ModelValueByte pid = new ModelValueByte();
    private final ModelValueString run = new ModelValueString();

    public ModelRow(String line) {
      setValues(line);
    }

    private void setValues(String line) {
      String[] rowData = line.split("\\s{2,}");
      String[] temp1 = rowData[3].split(" / ");
      String[] temp2 = rowData[5].split(" / ");
      String[] temp3 = rowData[6].split(" / ");
      containerId.setValue(rowData[0]);
      name.setValue(rowData[1]);
      cpu.setValue(rowData[2]);
      memUsage.setValue(temp1[0]);
      limit.setValue(temp1[1]);
      mem.setValue(rowData[4]);
      netI.setValue(temp2[0]);
      netO.setValue(temp2[1]);
      blockI.setValue(temp3[0]);
      blockO.setValue(temp3[1]);
      pid.setValue(rowData[7]);
      run.setValue("0".equals(rowData[7]) ? "No" : "Yes");
    }

    public Object getValueAt(int columnIndex) {
      return switch (columnIndex) {
        case 0 -> containerId;
        case 1 -> name;
        case 2 -> cpu;
        case 3 -> memUsage;
        case 4 -> limit;
        case 5 -> mem;
        case 6 -> netI;
        case 7 -> netO;
        case 8 -> blockI;
        case 9 -> blockO;
        case 10 -> pid;
        case 11 -> run;
        default -> throw new IllegalArgumentException("Unexpected column value: " + columnIndex);
      };
    }
  }

  private static class MyTableModel extends AbstractTableModel {
    private final String[] columnNames = {
      "CONTAINER ID",
      "NAME",
      "CPU %",
      "MEM USAGE",
      "LIMIT",
      "MEM %",
      "NET I",
      "NET O",
      "BLOCK I",
      "BLOCK O",
      "PIDS",
      "RUNS"
    };

    private final ArrayList<ModelRow> data = new ArrayList<>();

    public void update() {
      data.clear();
      String[] tableArray = getTableArray();
      for (String line : tableArray) {
        addRow(line);
      }
      fireTableDataChanged();
    }

    private void addRow(String line) {
      if (line.startsWith("CONTAINER ID")) {
        return;
      }
      data.add(new ModelRow(line));
    }

    @Override
    public int getRowCount() {
      return data.size();
    }

    @Override
    public int getColumnCount() {
      return columnNames.length;
    }

    @Override
    public String getColumnName(int column) {
      return columnNames[column];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
      return data.get(rowIndex).getValueAt(columnIndex);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
      return ModelValue.class;
    }
  }

und

    MyTableModel model = new MyTableModel();
    JTable table = new JTable(model);
    table.setAutoCreateRowSorter(true);

Eigentlich straight forward.

Oder … immer noch falsch?