简体   繁体   English

使用TextAreaRenderer在JTable单元格中居文本对齐

[英]Center text alignment in JTable cell with TextAreaRenderer

I am using a TextAreaRenderer to word-wrap text within my JTable cells. 我正在使用TextAreaRenderer在我的JTable单元格中自动换行文本。 However, specifications for my project call for the ability to center the text (both horizontally and vertically). 但是,我的项目规范要求能够使文本居中(水平和垂直)。 I cannot figure out how to do this. 我无法弄清楚如何做到这一点。

Because I am already using a TextAreaRenderer which extends JTextArea , I am unable to extend DefaultTableCellRenderer which is necessary to access the setHorizontalAlignment() and setVerticalAlignment() methods (see this question and answer: How to center in JTable cell a value? ). 因为我已经在使用extends JTextAreaTextAreaRenderer ,所以我无法扩展DefaultTableCellRenderer ,这是访问setHorizontalAlignment()setVerticalAlignment()方法所必需的(请参阅此问题和答案: 如何在JTable单元格中居中一个值? )。 I can't implement DefaultTableCellRenderer because it is not an interface. 我无法实现DefaultTableCellRenderer因为它不是一个接口。

SSCCE with the TextAreaRenderer I am using: 我正在使用的TextAreaRenderer SSCCE:

import java.awt.Component;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class Test {

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        JTable table = new JTable();
        JScrollPane jsp = new JScrollPane(table);
        Object[][] data = new Object[2][2];
        data[0][0] = 1;
        data[0][1] = "Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. Super long text just to illustrate word wrap. ";
        data[1][0] = 2;
        data[1][1] = "Two Lines / Two Lines";
        String[] headers = new String[]{"Digit", "Text"};
        table.setModel(new DefaultTableModel(data, headers) {

            @Override
            public Class<?> getColumnClass(int columnIndex) {
                switch(columnIndex){
                    case 1: return Integer.class;
                    case 2: return String.class;
                    default: return Object.class;
                }
            }
        });
        table.getColumnModel().getColumn(1).setCellRenderer(new TextAreaRenderer());
        frame.add(jsp);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }



    static class TextAreaRenderer extends JTextArea implements TableCellRenderer {

        private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
        /** map from table to map of rows to map of column heights */
        private final Map cellSizes = new HashMap();


        public TextAreaRenderer() {
            setLineWrap(true);
            setWrapStyleWord(true);
        }

        public Component getTableCellRendererComponent(
                JTable table, Object obj, boolean isSelected,
                boolean hasFocus, int row, int column) {

            // set the colours, etc. using the standard for that platform
            adaptee.getTableCellRendererComponent(table, obj,
                    isSelected, hasFocus, row, column);
            setForeground(adaptee.getForeground());
            setBackground(adaptee.getBackground());
            setBorder(adaptee.getBorder());
            setFont(adaptee.getFont());
            setText(adaptee.getText());


            // This line was very important to get it working with JDK1.4
            TableColumnModel columnModel = table.getColumnModel();
            setSize(columnModel.getColumn(column).getWidth(), 100000);
            int height_wanted = (int) getPreferredSize().getHeight();
            addSize(table, row, column, height_wanted);
            height_wanted = findTotalMaximumRowSize(table, row);
            if (height_wanted != table.getRowHeight(row)) {
                table.setRowHeight(row, height_wanted);
            }
            return this;
        }

        @SuppressWarnings("unchecked")
        private void addSize(JTable table, int row, int column, int height) {
            Map rows = (Map) cellSizes.get(table);
            if (rows == null) {
                cellSizes.put(table, rows = new HashMap());
            }
            Map rowheights = (Map) rows.get(new Integer(row));
            if (rowheights == null) {
                rows.put(new Integer(row), rowheights = new HashMap());
            }
            rowheights.put(new Integer(column), new Integer(height));
        }

        /**
         * Look through all columns and get the renderer.  If it is
         * also a TextAreaRenderer, we look at the maximum height in
         * its hash table for this row.
         */
        private int findTotalMaximumRowSize(JTable table, int row) {
            int maximum_height = 0;
            Enumeration columns = table.getColumnModel().getColumns();
            while (columns.hasMoreElements()) {
                TableColumn tc = (TableColumn) columns.nextElement();
                TableCellRenderer cellRenderer = tc.getCellRenderer();
                if (cellRenderer instanceof TextAreaRenderer) {
                    TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
                    maximum_height = Math.max(maximum_height,
                            tar.findMaximumRowSize(table, row));
                }
            }
            return maximum_height;
        }

        private int findMaximumRowSize(JTable table, int row) {
            Map rows = (Map) cellSizes.get(table);
            if (rows == null) {
                return 0;
            }
            Map rowheights = (Map) rows.get(new Integer(row));
            if (rowheights == null) {
                return 0;
            }
            int maximum_height = 0;
            for (Iterator it = rowheights.entrySet().iterator();
                    it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                int cellHeight = ((Integer) entry.getValue()).intValue();
                maximum_height = Math.max(maximum_height, cellHeight);
            }
            return maximum_height;
        }
    }
}

You need to have a renderer that uses a JTextPane, not a JTextArea, and then set the Document's style attributes. 您需要一个使用JTextPane而不是JTextArea的渲染器,然后设置Document的样式属性。

ie,

static class TextAreaRenderer extends JTextPane implements TableCellRenderer {

  private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
  /** map from table to map of rows to map of column heights */
  private final Map cellSizes = new HashMap();

  public TextAreaRenderer() {
     // !! setLineWrap(true);
     // setWrapStyleWord(true);

     StyledDocument doc = getStyledDocument();
     SimpleAttributeSet center = new SimpleAttributeSet();
     StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
     doc.setParagraphAttributes(0, doc.getLength(), center, false);
  }

For more, see (and up-vote) camickr's answer here . 如需更多信息,请参阅(和赞成票)camickr的答案在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM