4

テーブルのセルレンダラーとして使用している 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);          
      }

テキスト領域が折り返しスタイルの単語を使用している場合、行が短い場合があります。

この updateSize メソッドを外部から呼び出すと、getTableCellRendererComponent正しく機能します。しかし、大きなテーブルでは、列のサイズが調整されるたびにすべての行でサイズの更新を呼び出すのは遅すぎるため実行できないため、行のレンダリング中にサイズ変更を行う方法を見つけようとしています。

関連する Java バグがあります (これは修正済みとしてマークされていますが、実際には修正されているようには見えません) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4446522ですが、この回避策は機能していないようです。ワードラップを使用する場合。

これを適切に機能させる方法について、誰かが代替案を提供できますか?

4

1 に答える 1

7

代替が適切に機能する

ここに画像の説明を入力

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;
    }
}
于 2012-04-11T07:04:33.830 に答える