作为单元格渲染器的JTextArea似乎不适用于换行样式字

时间:2012-04-11 00:21:11

标签: java swing jtable jtextarea renderer

我有一个JTextArea,我用它作为表格的单元格渲染器。在getTableCellRenderercomponent方法中我有:

    setText(getTextForCell());
    setSize(table.getColumnModel().getColumn(column).getWidth(), 0);
    getUI().getRootView(textArea).setSize(textArea.getWidth(), 0f);
    updateSize();


    private void updateSize() {
       int prefHeight = textArea.getPreferredSize().height;
       int currHeight = table.getRowHeight(r);
       if (prefHeight > currHeight) {
        table.setRowHeight(row, prefHeight);          
      }

当文本区域使用换行样式字时,它有时会短一行。

如果我从getTableCellRendererComponent外部调用此updateSize方法,那么它可以正常工作。但是对于一个大表,每当列大小调整时调用所有行的更新大小都是不可行的,因为它太慢了,所以我一直试图找到一种方法在行渲染期间进行调整大小。

有一个相关的Java错误(标记为已修复,但它似乎并非如此)http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4446522,但这种解决方法在使用自动换行时似乎不起作用。

任何人都可以提供如何使其正常工作的替代方案吗?

1 个答案:

答案 0 :(得分:7)

替代方案正常运作

enter image description here

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

public class AutoWrapInJTable {

    public AutoWrapInJTable() {
        String[] columnNames = {"TextAreaCellRenderer"};
        Object[][] data = {
            {"123456789012345678901234567890"},
            {"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"},
            {"----------------------------------------------0"},
            {">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|"},};
        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();
            }//http://tips4java.wordpress.com/2008/10/26/text-utilities/

            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);
        JPanel p = new JPanel(new BorderLayout());
        p.add(sp);
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.add(p);
        //f.pack();
        f.setSize(200, 200);
        f.setLocation(150, 150);
        f.setVisible(true);
    }

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

            @Override
            public void run() {
                AutoWrapInJTable autoWrapInJTable = new AutoWrapInJTable();
            }
        });
    }
}

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;
    }
}