AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79553464
Accepted
Starkvell
Starkvell
Asked: 2025-04-04 00:06:46 +0800 CST2025-04-04 00:06:46 +0800 CST 2025-04-04 00:06:46 +0800 CST

Como classificar uma coluna por dados de outra coluna no JTable

  • 772

Preciso classificar a coluna com "Data de criação do arquivo", mas se a coluna "Tipo de arquivo" == FyleType.DIRECTORY, essa linha deve estar no topo. Ou seja, a primeira classificação deve ser por tipo e, depois, por data.

Minha JTable:


Tipo Nome do arquivo Data
DIRETÓRIO nomedoarquivo1 2025.04.03
DIRETÓRIO nomedoarquivo2 2025.02.01
ARQUIVO nomedoarquivo3.txt 2025.01.01
ARQUIVO nomedoarquivo4.txt 2025.02.03

Eu tentei usar

TableRowSorter<FileTableModel> tableRowSorter = new TableRowSorter<>(tableModel);
tableRowSorter.setComparator(2, ((o1, o2) -> {}

Comparador, mas ele só obtém o valor da célula atual e não consigo obter o tipo de arquivo porque a data não é única

java
  • 2 2 respostas
  • 44 Views

2 respostas

  • Voted
  1. Best Answer
    aterai
    2025-04-04T13:49:48+08:002025-04-04T13:49:48+08:00

    Outra opção é criar um JTableque contenha uma Filecópia de cada coluna de dados. Dessa forma, você precisaria alterar o TableCellRendererpara exibir o tipo de arquivo, nome do arquivo ou data de criação do arquivo a partir do Filedependendo da coluna, mas os comparadores para cada coluna seriam capazes de obter o tipo de arquivo e a data de criação do arquivo a partir do Fileao mesmo tempo.

    import java.awt.*;
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.attribute.BasicFileAttributes;
    import java.nio.file.attribute.FileTime;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    import java.util.Optional;
    import javax.swing.*;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    import javax.swing.table.TableRowSorter;
    
    public class GroupDirectoriesFirstComparatorTest {
      private Component makeUI() {
        String[] columnNames = {"Type", "Filename", "Date"};
        DefaultTableModel model = new DefaultTableModel(columnNames, 0) {
          @Override
          public Class<?> getColumnClass(int column) {
            return File.class;
          }
        };
        JTable table = new JTable(model);
        table.setAutoCreateRowSorter(true);
        table.setDefaultRenderer(File.class, new FileCellRenderer());
        RowSorter<? extends TableModel> sorter = table.getRowSorter();
        if (sorter instanceof TableRowSorter) {
          TableRowSorter<? extends TableModel> rs =
              (TableRowSorter<? extends TableModel>) sorter;
          for (int i = 0; i < model.getColumnCount(); i++) {
            rs.setComparator(i, new GroupDirectoriesFirstComparator(table, i));
          }
        }
        JButton button = new JButton("Choose directory");
        button.addActionListener(e -> {
          JFileChooser chooser = new JFileChooser();
          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
          int ret = chooser.showOpenDialog(button.getRootPane());
          if (ret == JFileChooser.APPROVE_OPTION) {
            model.setRowCount(0);
            File[] files = chooser.getSelectedFile().listFiles();
            if (files != null) {
              Arrays.stream(files)
                  .map(f -> Collections.nCopies(3, f).toArray())
                  .forEach(model::addRow);
            }
          }
        });
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(table));
        p.add(button, BorderLayout.SOUTH);
        return p;
      }
    
      public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          frame.getContentPane().add(
              new GroupDirectoriesFirstComparatorTest().makeUI());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
        });
      }
    }
    
    class FileCellRenderer extends DefaultTableCellRenderer {
      private final DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
    
      @Override
      public Component getTableCellRendererComponent(
          JTable table, Object value,
          boolean isSelected, boolean hasFocus,
          int row, int column) {
        Component c = super.getTableCellRendererComponent(
            table, value, isSelected, hasFocus, row, column);
        if (c instanceof JLabel && value instanceof File) {
          JLabel l = (JLabel) c;
          l.setHorizontalAlignment(LEFT);
          File file = (File) value;
          switch (table.convertColumnIndexToModel(column)) {
            case 0:
              l.setText(file.isDirectory() ? "DIRECTORY" : "FILE");
              break;
            case 1:
              l.setText(file.getName());
              break;
            case 2:
              l.setHorizontalAlignment(RIGHT);
              try {
                BasicFileAttributes attr =
                    Files.readAttributes(file.toPath(), BasicFileAttributes.class);
                l.setText(dateFormat.format(attr.creationTime().toMillis()));
              } catch (IOException e) {
                throw new RuntimeException(e);
              }
              break;
            default:
              break;
          }
        }
        return c;
      }
    }
    
    class FileComparator implements Comparator<File> {
      private final int column;
    
      public FileComparator(int column) {
        this.column = column;
      }
    
      @Override
      public int compare(File a, File b) {
        switch (column) {
          case 0: return getWeight(a) - getWeight(b);
          case 2: return Long.compare(getCreationTime(a), getCreationTime(b));
          default: return a.getName().compareToIgnoreCase(b.getName());
        }
      }
    
      public int getColumn() {
        return column;
      }
    
      public static int getWeight(File file) {
        return file.isDirectory() ? 1 : 2;
      }
    
      public static Long getCreationTime(File file) {
        BasicFileAttributes attr;
        try {
          attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
        return Optional.ofNullable(attr)
            .map(BasicFileAttributes::creationTime)
            .map(FileTime::toMillis)
            .orElse(0L);
      }
    }
    
    // https://java-swing-tips.blogspot.com/2011/11/jtable-group-directories-first-sorting.html
    class GroupDirectoriesFirstComparator extends FileComparator {
      private final JTable table;
    
      public GroupDirectoriesFirstComparator(JTable table, int column) {
        super(column);
        this.table = table;
      }
    
      @Override
      public int compare(File a, File b) {
        int v = getWeight(a) - getWeight(b);
        return v == 0 ? super.compare(a, b) : v * getSortOrderDirection();
      }
    
      private int getSortOrderDirection() {
        int dir = 1;
        List<? extends RowSorter.SortKey> keys = table.getRowSorter().getSortKeys();
        if (!keys.isEmpty()) {
          RowSorter.SortKey sortKey = keys.get(0);
          if (sortKey.getColumn() == getColumn() &&
              sortKey.getSortOrder() == SortOrder.DESCENDING) {
            dir = -1;
          }
        }
        return dir;
      }
    }
    
    • 1
  2. ControlAltDel
    2025-04-04T00:41:38+08:002025-04-04T00:41:38+08:00

    Você precisa criar um comparador (deve ser uma classe não estática em ou com acesso ao seu modelo de tabela) para definir em seu RowSorter, como

    class MyComparator implements Comparator<date> {
      if (row1.column1 = "DIRECTORY" && row2.column1 != "DIRECTORY) {
        return -1;
      }
      else if (row2.column1 == "DIRECTORY") {
        return 1;
      } else {
        return MyDateComparator.compareTo (row1.column4, row2.column4);
      }
    }
    
    • 0

relate perguntas

  • Lock Condition.notify está lançando java.lang.IllegalMonitorStateException

  • Resposta de microsserviço Muitos para Um não aparece no carteiro

  • Validação personalizada do SpringBoot Bean

  • Os soquetes Java são FIFO?

  • Por que não é possível / desencorajado definir um lado do servidor de tempo limite de solicitação?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve