如何按字母顺序对JTable进行排序,分隔线显示下一个字母的出现?例如,考虑Windows Media Player 12如何对其进行排序,
此问题的另一个例子是例如Macintosh'Finder'按日期排序最近打开应用程序的方式。我无法弄清楚他们是如何添加额外的行显示日期和包围匹配的行。
有关如何解决此问题的任何想法?
答案 0 :(得分:1)
我会按字母顺序对数据进行分组,然后为我的数据中包含的每个字母创建一个单独的表格。
您可以使用TableCellRenderer自定义标题的显示以获得所需的外观,如果您要添加更多列,如示例所示,您可以将标题替换为另一个组件。
public class MyTableFrame extends JFrame {
MyTableFrame() {
List<String> data = Arrays.asList(
"Alpha1",
"Beta1",
"Alpha2",
"Charlie2",
"Alpha3",
"Beta2",
"Charlie1"
);
// Sort alphabetically
data.sort(String::compareTo);
// Group by first letter
Map<Character, List<String>> collect = data.stream()
.collect(Collectors.groupingBy(string -> string.charAt(0)));
JPanel tablesContainer = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 0;
c.gridy = 0;
// Create a table for each Letter
collect.entrySet().forEach(mapEntry -> {
Character letter = mapEntry.getKey();
List<String> startingWithLetter = mapEntry.getValue();
TableModel tableModel = new TableModel(startingWithLetter, letter);
JTable table = new JTable(tableModel);
// Table header must be added separately since there is no scroll pane
JTableHeader tableHeader = table.getTableHeader();
tablesContainer.add(tableHeader, c);
c.gridy++;
tablesContainer.add(table, c);
c.gridy++;
});
add(tablesContainer);
setVisible(true);
pack();
}
static class TableModel extends AbstractTableModel {
private List<String> data;
private Character columnName;
TableModel(List<String> data, Character columnName) {
this.data = data;
this.columnName = columnName;
}
@Override
public String getColumnName(int column) {
return columnName.toString();
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data.get(rowIndex);
}
}
public static void main(String args[]) {
new MyTableFrame();
}
}
答案 1 :(得分:1)
要使表行显示在JTable通常期望的位置以外的位置,您需要覆盖的JTable中的方法是fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
,rowAtPoint
,当然,{ {1}}。为了支持这些方法,我会跟踪排序地图中部分标题出现的行,并且我会跟踪第二个有序地图中的行位置。
每当表模型或排序列发生更改时,或者每当表因任何原因验证自身时,我都会重新计算这些映射,这意味着分别覆盖tableChanged,sortedChanged和validate方法。
结果并不像您预期的那样冗长:
getCellRect
您可以通过更改标题从数据中派生的方式来调整此类以生成Finder表。仅使用getValueAt检查一个单元格是不够的;相反,您需要translate the sorted row to the corresponding model row,并直接从TableModel获取该行的数据对象。然后,您可以按年龄而不是字符串数据比较行。