问题
I implement icon for sorting column in my jTable. I have a button for find result and i implement a default sorting when i launch the worker. Like this :
public void refreshStripedViewTable(final List<FlightBox> boxList,
final List<FlightBoxModel> boxesModels, final String sortBy) {
if (boxList != null && !boxList.isEmpty()) {
stripedViewTableModel.setContent(boxesModels);
tableRenderer.setStripedViewModelList(boxesModels);
final RowSorter<? extends TableModel> sorter = tableFacade
.getTooltipsTable().getRowSorter();
if (sorter != null) {
List<SortKey> sortKeys = new ArrayList<SortKey>();
javax.swing.RowSorter.SortKey sk = new SortKey(getColumnIndex(
sortBy, tableFacade.getTooltipsTable()),
SortOrder.ASCENDING);
sortKeys.add(sk);
sorter.setSortKeys(sortKeys);
tableFacade.getTooltipsTable().setRowSorter(sorter);
tableFacade.getTooltipsTable().validate();
tableFacade.getTooltipsTable().getModelTable()
.fireTableDataChanged();
}
}
}
i add a renderer for setIcon when user click on header on my JTable.
public Component getTableCellRendererComponent(final JTable table,
final Object value, final boolean isSelected, final boolean hasFocus,
final int row, final int column) {
setIcon(null);
super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
setOpaque(false);
setForeground(Color.white);
final RowSorter<?> sorter = table.getRowSorter();
if (sorter != null) {
java.util.List<? extends javax.swing.RowSorter.SortKey> sortKeys = sorter
.getSortKeys();
if (sortKeys.size() > 0) {
javax.swing.RowSorter.SortKey sk = sortKeys.get(0);
// take in account if the user moves the column
if (column == table.convertColumnIndexToView(sk.getColumn())) {
Icon icon = null;
if (sk.getSortOrder() == SortOrder.ASCENDING) {
icon = iconService
.getRessourceIcon(MediaHmiService.TABLE_SORT_ORDER_ASCENDING);
} else if (sk.getSortOrder() == SortOrder.DESCENDING) {
icon = iconService
.getRessourceIcon(MediaHmiService.TABLE_SORT_ORDER_DESCENDING);
}
setIcon(icon);
}
}
}
setHorizontalTextPosition(SwingConstants.LEFT);
return this;
}
I have a problem when i do this : - Found result --> Icon is set on default column sorting OK - Click on header for set icon OK - Relaunch search --> Not icon is visible.KO My renderer don't have sortKeys but i set rowSorter in my methode refreshStripedViewTable().I don't understand why...
Thanks guys for your help. Regards.
回答1:
note there are three types of
SortOrder
ASCENDING
DESCENDING
UNSORTED
f.i.
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class RowSorterDefaults {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame();
private JScrollPane pane = new javax.swing.JScrollPane();
private JTable table = new javax.swing.JTable();
public RowSorterDefaults() {
table.setModel(new javax.swing.table.DefaultTableModel(
new Object[][]{
{"a", "q", "h", "v"}, {"b", "m", "l", "h"},
{"d", "c", "a", "d"}, {"j", "o", "y", "e"}
},
new String[]{
"Col 1", "Col 2", "Col 3", "Col 4"
}) {
private static final long serialVersionUID = 1L;
Class[] types = new Class[]{
String.class, String.class, String.class, String.class
};
@Override
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
});
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
@Override
public void toggleSortOrder(int column) {
if (column >= 0 && column < getModelWrapper().getColumnCount() && isSortable(column)) {
List<SortKey> keys = new ArrayList<SortKey>(getSortKeys());
if (!keys.isEmpty()) {
SortKey sortKey = keys.get(0);
if (sortKey.getColumn()
== column && sortKey.getSortOrder()
== SortOrder.DESCENDING) {//UNSORTED, ASCENDING
setSortKeys(null);
return;
}
}
}
super.toggleSortOrder(column);
}
};
table.setRowSorter(sorter);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setDefaultRenderer(RowSorterDefaults.class, new HeaderRenderer(table));
pane.setViewportView(table);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
class HeaderRenderer implements TableCellRenderer {
final TableCellRenderer renderer;
public HeaderRenderer(JTable table) {
renderer = table.getTableHeader().getDefaultRenderer();
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int col) {
return renderer.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, col);
}
public Icon getIcon(JTable table, int column) {
for (RowSorter.SortKey sortKey : table.getRowSorter().getSortKeys()) {
if (sortKey.getColumn() == column) {
switch (sortKey.getSortOrder()) {
case ASCENDING:
return (UIManager.getIcon("Table.ascendingSortIcon"));
case DESCENDING:
return (UIManager.getIcon("Table.descendingSortIcon"));
}
}
}
return null;
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new RowSorterDefaults();
}
});
}
}
回答2:
I have a problem when i do this : - Found result --> Icon is set on default column sorting OK - Click on header for set icon OK - Relaunch search --> Not icon is visible.KO My renderer don't have sortKeys but i set rowSorter in my methode refreshStripedViewTable().I don't understand why...
Icon are added as defaults to UIManager, then all JTables in current JVM has the same Icons
ASCENDING
DESCENDING
UNSORTED
f.i.
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class RowSorterCustom {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame();
private JScrollPane pane = new javax.swing.JScrollPane();
private JTable table = new javax.swing.JTable();
public RowSorterCustom() {
table.setModel(new javax.swing.table.DefaultTableModel(
new Object[][]{
{"a", "q", "h", "v"}, {"b", "m", "l", "h"},
{"d", "c", "a", "d"}, {"j", "o", "y", "e"}
},
new String[]{
"Col 1", "Col 2", "Col 3", "Col 4"
}) {
private static final long serialVersionUID = 1L;
Class[] types = new Class[]{
String.class, String.class, String.class, String.class
};
@Override
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
});
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
@Override
public void toggleSortOrder(int column) {
if (column >= 0 && column < getModelWrapper().getColumnCount() && isSortable(column)) {
List<SortKey> keys = new ArrayList<SortKey>(getSortKeys());
if (!keys.isEmpty()) {
SortKey sortKey = keys.get(0);
if (sortKey.getColumn()
== column && sortKey.getSortOrder()
== SortOrder.DESCENDING) {//UNSORTED, ASCENDING
setSortKeys(null);
return;
}
}
}
super.toggleSortOrder(column);
}
};
table.setRowSorter(sorter);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
pane.setViewportView(table);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
static class BevelArrowIcon implements Icon {
public static final int UP = 0; // direction
public static final int DOWN = 1;
private static final int DEFAULT_SIZE = 11;
private Color edge1;
private Color edge2;
private Color fill;
private int size;
private int direction;
public BevelArrowIcon(int direction, boolean isRaisedView, boolean isPressedView) {
if (isRaisedView) {
if (isPressedView) {
init(UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
} else {
init(UIManager.getColor("controlHighlight"),
UIManager.getColor("controlShadow"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
} else {
if (isPressedView) {
init(UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
} else {
init(UIManager.getColor("controlShadow"),
UIManager.getColor("controlHighlight"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
}
}
public BevelArrowIcon(Color edge1, Color edge2, Color fill, int size, int direction) {
init(edge1, edge2, fill, size, direction);
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
switch (direction) {
case DOWN:
drawDownArrow(g, x, y);
break;
case UP:
drawUpArrow(g, x, y);
break;
}
}
@Override
public int getIconWidth() {
return size;
}
@Override
public int getIconHeight() {
return size;
}
private void init(Color edge1, Color edge2, Color fill, int size, int direction) {
edge1 = Color.red;
edge2 = Color.blue;
this.edge1 = edge1;
this.edge2 = edge2;
this.fill = fill;
this.size = size;
this.direction = direction;
}
private void drawDownArrow(Graphics g, int xo, int yo) {
g.setColor(edge1);
g.drawLine(xo, yo, xo + size - 1, yo);
g.drawLine(xo, yo + 1, xo + size - 3, yo + 1);
g.setColor(edge2);
g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1);
int x = xo + 1;
int y = yo + 2;
int dx = size - 6;
while (y + 1 < yo + size) {
g.setColor(edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x += 1;
y += 2;
dx -= 2;
}
g.setColor(edge1);
g.drawLine(xo + (size / 2), yo + size - 1, xo + (size / 2), yo + size - 1);
}
private void drawUpArrow(Graphics g, int xo, int yo) {
g.setColor(edge1);
int x = xo + (size / 2);
g.drawLine(x, yo, x, yo);
x--;
int y = yo + 1;
int dx = 0;
while (y + 3 < yo + size) {
g.setColor(edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x -= 1;
y += 2;
dx += 2;
}
g.setColor(edge1);
g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3);
g.setColor(edge2);
g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2);
g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1);
}
}
public static void main(String args[]) {
UIManager.getLookAndFeelDefaults().put("Table.ascendingSortIcon", new BevelArrowIcon(BevelArrowIcon.UP, false, false));
UIManager.getLookAndFeelDefaults().put("Table.descendingSortIcon", new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new RowSorterCustom();
}
});
}
}
来源:https://stackoverflow.com/questions/18529240/rowsorter-not-set-in-renderer