RowSorter not set in renderer

醉酒当歌 提交于 2019-12-12 02:53:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!