Usando uma coluna vazia como divisor em um jtable
Pergunta
Estou tentando usar uma coluna vazia como divisor entre pares de colunas em um JTable
. Aqui está uma imagem e um código para o que tenho até agora. Eu sei que posso mudar a aparência usando um personalizado TableCellRenderer
. Antes de seguir esse caminho, existe uma maneira melhor de fazer isso? Quaisquer idéias apreciadas.
import javax.swing.*;
import javax.swing.table.*;
public class TablePanel extends JPanel {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame("TablePanel");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(new TablePanel());
f.pack();
f.setVisible(true);
}
});
}
public TablePanel() {
TableModel dataModel = new MyModel();
JTable table = new JTable(dataModel);
table.getColumnModel().getColumn(MyModel.DIVIDER).setMaxWidth(0);
JScrollPane jsp = new JScrollPane(table);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(jsp);
}
private static class MyModel extends AbstractTableModel {
private static final int DIVIDER = 2;
private final String[] names = { "A1", "A2", "", "B1", "B2" };
@Override
public int getRowCount() {
return 32;
}
@Override
public int getColumnCount() {
return names.length;
}
@Override
public String getColumnName(int col) {
if (col == DIVIDER) return "";
return names[col];
}
@Override
public Object getValueAt(int row, int col) {
if (col == DIVIDER) return "";
return (row + 1) / 10.0;
}
@Override
public Class<?> getColumnClass(int col) {
if (col == DIVIDER) return String.class;
return Number.class;
}
}
}
Solução
Sobre o problema dessa abordagem, o usuário precisará "guiar" a coluna do divisor. Você poderia usar o Tabbing de tabela sugestão para torná -la mais amigável.
Ou, se a tabaga entre as duas tabelas não for importante, talvez você possa usar duas tabelas e colocar qualquer divisor que desejar entre os dois. O modelo de seleção pode compartilhar, se necessário.
Editar:
Como sugeri acima, o compartilhamento de modelos é mais fácil do que escrever ouvintes personalizados. Para manter a rolagem em sincronia, o código seria:
jspa.getVerticalScrollBar().setModel( jspb.getVerticalScrollBar().getModel() );
Você também pode fazer o mesmo com o modelo de seleção para que o destaque das linhas esteja sincronizado.
Outras dicas
Eu meio que combinei as duas respostas: usei duas tabelas que compartilham a barra de rolagem. Isso funciona com a classificação, e na verdade simplifica o modelo. Tabbing não importa, mas comparar "A" e "B". Eu acho que estava tentando resolver um problema de "visão" no "modelo". Fiz isso uma resposta separada, porque eu apreciaria quaisquer comentários críticos.
public TablePanel() {
this.setLayout(new GridLayout(1, 0, 8, 0));
JTable tableA = new JTable(new MyModel("A"));
tableA.setPreferredScrollableViewportSize(new Dimension(200, 400));
final JScrollPane jspA = new JScrollPane(tableA);
jspA.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
this.add(jspA);
JTable tableB = new JTable(new MyModel("B"));
tableB.setPreferredScrollableViewportSize(new Dimension(200, 400));
final JScrollPane jspB = new JScrollPane(tableB);
jspB.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(jspB);
tableA.setSelectionModel(tableB.getSelectionModel());
jspA.getVerticalScrollBar().setModel(jspB.getVerticalScrollBar().getModel());
}
Sem saber o que você deseja mostrar nesta tabela, é difícil dizer se você selecionou uma boa solução ou não.
Em relação a esta solução. Esta coluna não parece um divisor. Pinte -o com cinza/outra cor, ou pinte a célula do cabeçalho do divisor em branco.
Mas de qualquer maneira eu preferiria o JScrollPane + duas tabelas dentro dele, em vez dessa solução.
Por favor, dê uma olhada na resposta desta pergunta, uma nova e boa sugestão foi dada lá: Divisores de coluna em jtable ou jxtable