JTable Calls Custom Cell Renderer Method… Continuously

前端 未结 3 535
一整个雨季
一整个雨季 2020-11-28 15:19

Compilable source can be found at: http://www.splashcd.com/jtable.tar

I\'m new to the language, so I\'m not sure if this is acceptable behavior or not.

I cre

相关标签:
3条回答
  • 2020-11-28 15:52

    The problem seems to stem from having JTable's setRowHeight() inside the custom cell renderer, as it calls the custom cell renderer, throwing it into an infinite loop.

    I had to add in a check to see if the current row height matched the calculated word wrapped row height. If it did, I didnt try to setRowHeight() again.

    Corrected Code:

    import java.awt.Component;
    
    import javax.swing.JTable;
    import javax.swing.JTextArea;
    import javax.swing.UIManager;
    import javax.swing.table.TableCellRenderer;
    
    //custom cell renderer for word wrapping, but if you use, you have to
    //implement zebra striping functionality which the default renderer has
    public class LineWrapCellRenderer extends JTextArea implements TableCellRenderer
    {
        private int numOfTimesCalled;
        @Override
        public Component getTableCellRendererComponent(
                JTable table,
                Object value,
                boolean isSelected,
                boolean hasFocus,
                int row,
                int column)
        {
            System.out.println("Line Wrap Cell Renderer Called: " + numOfTimesCalled++);
            System.out.println("row:"+ row + ", col:" + column);
    //set up the row size based on the number of newlines in the text in the cell
            int fontHeight = this.getFontMetrics(this.getFont()).getHeight();
            int numWraps = value.toString().split("\r\n|\r|\n").length;
            int rowHeight = fontHeight * numWraps;
    //if the calculated rowHeight is the same as the row height of row,
    // then don't call setRowHeight again, as doing so will throw us into
    // an infinite loop
            if(rowHeight != table.getRowHeight(row))
            {
                table.setRowHeight(row, rowHeight);
    
    //configure word wrapping
                setWrapStyleWord(true);
                setLineWrap(true);
    //use the table's font
                setFont(table.getFont());
            }
    //zebra striping, because whatever cell uses this renderer loses the
    //default cell renderer zebra striping
            if(isSelected)
            {
                setBackground(table.getSelectionBackground());
            }
            else
            {
                if(row%2 == 1)
                {
                    setBackground(UIManager.getColor("Table.alternateRowColor"));
                }
                else
                {
                    setBackground(table.getBackground());
                }
            }
            this.setText(value.toString());
            return this;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 15:57

    To get the most performance out of a TableCellRenderer, make sure you're not creating a new instance of a component every time getTableCellRenderer is called. Make the components once and save them as fields of the class.

    Also, you'll want to make sure each of the Components you use have the following methods overridden to do nothing:

    • validate
    • invalidate
    • revalidate
    • repaint
    • firePropertyChange

    (and you probably want to hard code isOpaque).

    For more information see: http://docs.oracle.com/javase/6/docs/api/javax/swing/tree/DefaultTreeCellRenderer.html

    0 讨论(0)
  • 2020-11-28 16:00
    • aaaaach

    • you need doLayout(),

    • next level :-), then there you can to set Maximum visible rows for JTextComponents too, with little effort

    enter image description here

    doLayout()

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.text.*;
    //http://tips4java.wordpress.com/2008/10/26/text-utilities/
    public class AutoWrapTest {
    
        public JComponent makeUI() {
            String[] columnNames = {" Text Area Cell Renderer "};
            Object[][] data = {
                {"123456789012345678901234567890"},
                {"ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdx"},
                {"----------------------------------------------0"},
                {">>>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffffffd"
                    + "ffffdffffddxffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdd"
                    + "ffffdffffdffffffffdx>>>>>>>>>>>>>>>>>>>>>>>>>|"},
                {">>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffd"
                    + "ffffdffffdx>>>>>>>>>>>>>>>>>>>>>>>>>>|"},
                {"a|"},
                {">>>>>>>>bbbb>>>>>>>>>>>>>>>>>>>|"},
                {">>>>>>>>>>>>>>>>>>|"},
                {">>>>>>>>>>>>>ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffffffd"
                    + "ffffdffffddxffffdffffdffffdffffffffd123456789012345678901234567890ffffdffffd"
                    + "ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddx>>>>>>>>>>>>>>>>>>>>"
                    + ">>>>>|"},
                {">>>>>>>>>>>>>ffffdffffdffffdffffffffd123456789012345678901234567890ffffdffffd"
                    + "ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffddxffffdffffdffffdffffffffd123456"
                    + "789012345678901234567890ffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdffffdd"
                    + "ffffffffd123456789012345678901234567890ffffddx>>>>>>>>>>>>>>>>>>"
                    + ">>>>>>>|"},};
            TableModel model = new DefaultTableModel(data, columnNames) {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            };
            JTable table = new JTable(model) {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public void doLayout() {
                    TableColumn col = getColumnModel().getColumn(0);
                    for (int row = 0; row < getRowCount(); row++) {
                        Component c = prepareRenderer(col.getCellRenderer(), row, 0);
                        if (c instanceof JTextArea) {
                            JTextArea a = (JTextArea) c;
                            int h = getPreferredHeight(a) + getIntercellSpacing().height;
                            if (getRowHeight(row) != h) {
                                setRowHeight(row, h);
                            }
                        }
                    }
                    super.doLayout();
                }
    
                private int getPreferredHeight(JTextComponent c) {
                    Insets insets = c.getInsets();
                    View view = c.getUI().getRootView(c).getView(0);
                    int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS);
                    return preferredHeight + insets.top + insets.bottom;
                }
            };
            table.setEnabled(false);
            table.setShowGrid(false);
            table.setTableHeader(null);
            table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer());
            //table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane sp = new JScrollPane(table);
            sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
            sp.setPreferredSize(new Dimension(250, 533));
            JPanel p = new JPanel(new BorderLayout());
            p.add(sp);
            return p;
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    
        public static void createAndShowGUI() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            f.getContentPane().add(new AutoWrapTest().makeUI());
            f.setLocation(100, 100);
            f.pack();
            f.setVisible(true);
        }
    }
    
    class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
    
        private static final long serialVersionUID = 1L;
        private final Color evenColor = new Color(230, 240, 255);
    
        public TextAreaCellRenderer() {
            super();
            setLineWrap(true);
            setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        }
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
                setBackground((row % 2 == 0) ? evenColor : getBackground());
            }
            setFont(table.getFont());
            setText((value == null) ? "" : value.toString());
            return this;
        }
    }
    
    0 讨论(0)
提交回复
热议问题