JTable行突出显示基于表格单元格中的值

时间:2011-08-20 14:33:13

标签: java swing jtable

因为我读到不可能编码我的纳瓦霍语言

如何仅将颜色交替/条带化为JTable(例如@camickr)

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableRowRenderingTip extends JPanel {

    private static final long serialVersionUID = 1L;

    public TableRowRenderingTip() {
        Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
        Object[][] data = {
            {"Buy", "IBM", new Integer(1000), new Double(80.5), Boolean.TRUE},
            {"Sell", "Dell", new Integer(2000), new Double(6.25), Boolean.FALSE},
            {"Short Sell", "Apple", new Integer(3000), new Double(7.35), Boolean.TRUE},
            {"Buy", "MicroSoft", new Integer(4000), new Double(27.50), Boolean.FALSE},
            {"Short Sell", "Cisco", new Integer(5000), new Double(20), Boolean.TRUE}
        };
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Alternating", createAlternating(model));
        add(tabbedPane);
    }

    private JComponent createAlternating(DefaultTableModel model) {
        JTable table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                if (!isRowSelected(row)) { //  Alternate row color
                    c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY);
                }
                return c;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        return new JScrollPane(table);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(false);
        JFrame frame = new JFrame("Table Row Rendering");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TableRowRenderingTip());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

我有一个JTable包含一些市场交易(更好地理解我的英语技能不佳),但有些交易只有一条腿,而另一条(例如香草交叉货币掉期)可能有两条腿。如何根据特定TableRows的值(例如名称为DealId的最后一列)高亮显示TableColumn。我尝试用row检查row - 1 && row + 1,但我的空头生成了很多代码,很多想法如何停止复杂简单的事情,如何检查另一行中是否存在重复值(总是严格按照图片中的顺序排列)。不知道如何实现那个

的简单公式

图片展示:

enter image description here
enter image description here enter image description here

从代码生成:

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TablePrepareRenderer extends JFrame {

    private static final long serialVersionUID = 1L;
    private Object[] columnNames = {
        "Buy/Sell", "Type", "SubType", "Ccy1", "Amount1", "Ccy2", "Amount2", "DealId"};
    private Object[][] data = {
        {"Buy&Sell", "Ccy Swap", "A1", "EUR", new Double(1000000.00), "USD", new Double(1439000.00), 50},
        {"Buy&Sell", "Ccy Swap", "A3", "USD", new Double(1438900.00), "EUR", new Double(1000000.00), 50},
        {"Buy&Sell", "Ccy Swap", "A1", "EUR", new Double(500000.00), "CHF", new Double(550000.00), 350},
        {"Buy&Sell", "Ccy Swap", "A1", "CHF", new Double(549800.00), "EUR", new Double(500000.00), 350},
        {"Sell&Buy", "Ccy Swap", "A3", "USD", new Double(1000000.00), "EUR", new Double(749000.00), 2250},
        {"Sell&Buy", "Ccy Swap", "A1", "EUR", new Double(748900.00), "USD", new Double(1000000.00), 2250},
        {"Buy&Sell", "Ccy Swap", "A1", "GBP", new Double(1000000.00), "USD", new Double(1638100.00), 400},
        {"Buy&Sell", "Ccy Swap", "A3", "USD", new Double(1638200.00), "GBP", new Double(1000000.00), 400},
        {"Sell", "Ccy Spot", "A1", "AUD", new Double(343575.0), "EUR", new Double(250000.0), 11990},
        {"Buy", "Ccy Spot", "A1", "EUR", new Double(100000.00), "JPY", new Double(1099000.00), 259},
        {"Sell", "Ccy Fwd", "A3", "DKK", new Double(74889.00), "EUR", new Double(10000.00), 115439},};
    private JTable table;

    public TablePrepareRenderer() {

        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent) c;
                /*if (!isRowSelected(row)) {
                c.setBackground(getBackground());
                int modelRow = convertRowIndexToModel(row);
                String type = (String) getModel().getValueAt(modelRow, 0);
                if (("Buy".equals(type)) && !("Buy&Sell".equals(type))) {
                c.setBackground(Color.orange);
                } else if (("Sell".equals(type)) && !("Sell&Buy".equals(type))) {
                c.setBackground(Color.orange);
                } else if ("Buy&Sell".equals(type)) {
                c.setBackground(Color.yellow);
                } else if ("Sell&Buy".equals(type)) {
                c.setBackground(Color.yellow);
                }
                }*/
                /*if (!isRowSelected(row)) {
                if (row == 0 ||row == 1||row == 4||row == 6||row == 7||row == 9||row == 10) {
                ((JComponent) c).setBackground(Color.orange);
                }  else {
                ((JComponent) c).setBackground(Color.yellow);
                }
                }*/

                if (!isRowSelected(row)) {
                    if (row == 0 || row == 1 || row == 4 || row == 5 || row == 8 || row == 10) {
                        ((JComponent) c).setBackground(Color.orange);
                    } else {
                        ((JComponent) c).setBackground(Color.yellow);
                    }
                }

                if (column == 0 || column == 1 || column == 2 || column == 3 || column == 5) {
                    //setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
                    //c.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
                    //(JComponent) c.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
                }
                return c;
            }

            @Override
            public Class getColumnClass(int column) {
                switch (column) {
                    case 0:
                        return String.class;
                    case 1:
                        return String.class;
                    case 2:
                        return String.class;
                    case 3:
                        return String.class;
                    case 4:
                        return Double.class;
                    case 5:
                        return String.class;
                    case 6:
                        return Double.class;
                    case 7:
                        return Integer.class;
                }
                return null;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        getContentPane().add(scrollPane);
    }

    public static void main(String[] args) {
        TablePrepareRenderer frame = new TablePrepareRenderer();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

编辑:

如何将Alignment的{​​{1}}设置为TableCell

2 个答案:

答案 0 :(得分:4)

  

如何将TableCell的对齐方式设置为prepareRenderer,

这不应该在prepareRenderer代码中完成。应在类的呈现器或列中设置此属性,因为它仅适用于特定的类或呈示器。而是使用:

table.setPreferredScrollableViewportSize(table.getPreferredSize());
DefaultTableCellRenderer stringRenderer = (DefaultTableCellRenderer)table.getDefaultRenderer(String.class);
stringRenderer.setHorizontalAlignment( SwingConstants.CENTER );

对于突出显示代码,我使用的代码假定dealld值对于给定的一组事务是唯一的:

        private Map<Object, Color> rowColor = new HashMap<Object, Color>();
        private Color nextColor = Color.ORANGE;

        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component c = super.prepareRenderer(renderer, row, column);
            JComponent jc = (JComponent) c;

            if (isRowSelected(row)) return c;

            Object value = table.getValueAt(row, 7);
            Color background = rowColor.get(value);

            if (background != null)
            {
                c.setBackground( background );
            }
            else
            {
                rowColor.put(value, nextColor);
                c.setBackground( nextColor );
                nextColor = (nextColor == Color.ORANGE) ? Color.YELLOW : Color.ORANGE;
            }

            return c;
        }

注意:如果需要排序,它将无效。

这是另一种方法,即使需要排序也应该有效(但我没有通过排序对其进行测试);

        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component c = super.prepareRenderer(renderer, row, column);
            JComponent jc = (JComponent) c;
            if (!isRowSelected(row))
            {
                c.setBackground(getRowBackground(row));
            }

            return c;
        }

        private Color getRowBackground(int row)
        {
            boolean isDark = true;

            Object previous = getValueAt(0, 7);

            for (int i = 1; i <= row; i++)
            {
                Object current = getValueAt(i, 7);

                if (! current.equals(previous))
                {
                    isDark = !isDark;
                    previous = current;
                }
            }

            return isDark ? Color.ORANGE : Color.YELLOW;
        }

答案 1 :(得分:2)

这是星期天,天哪,所以无法抗拒显示SwingX版本。这与@camickr 2nd的逻辑相同,谢谢: - )

优点:

  • 代码可以专注于逻辑,因为值检索处理排序/过滤/列自动移动
  • 了解默认ui交替条带颜色(以及切换LAF时的更新)
  • 内置荧光笔支持,无需对表进行子类化,也不需要关心渲染器的错误行为
  • 容易添加额外的荧光笔(大喊大叫卖,卖,卖:-)

代码剪断:

JXTable table = new JXTable(data, columnNames);
HighlightPredicate predicate =  new HighlightPredicate() {

    @Override
    public boolean isHighlighted(Component renderer,
            ComponentAdapter adapter) {
        if (adapter.row == 0) return false;
        return isOddValue(adapter);
    }

    private boolean isOddValue(ComponentAdapter adapter) {
        Object previous = adapter.getFilteredValueAt(0, 7);
        boolean odd = false;
        for (int i = 1; i <= adapter.row; i++) {
            Object current = adapter.getFilteredValueAt(i, 7);
            if (!previous.equals(current)) {
                odd = !odd;
            }
            previous = current;
        }
        return odd;
    }

};
table.addHighlighter(new UIColorHighlighter(predicate));