2013-12-21 2 views
1

Я использую TextAreaRenderer для текстового текста в ячейках JTable. Однако спецификации для моего проекта требуют возможности централизовать текст (как по горизонтали, так и по вертикали). Я не могу понять, как это сделать.Центральное выравнивание текста в ячейке JTable с TextAreaRenderer

Поскольку я уже использует TextAreaRenderer какой extends JTextArea, я не могу продлить DefaultTableCellRenderer, который необходим для доступа к setHorizontalAlignment() и setVerticalAlignment() методы (см этот вопрос и ответ: How to center in JTable cell a value?). Я не могу реализовать DefaultTableCellRenderer, потому что это не интерфейс.

SSCCE с TextAreaRenderer я использую:

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

ответ

3

Вы должны иметь средства визуализации, которая использует JTextPane, а не JTextArea, а затем установить атрибуты стиля документа.

т.е.

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

Более подробно см ответ here (и до-голосования) camickr в.

+1

безупречный! Спасибо HFOE. – ryvantage

+0

Я видел ответ camickr, но я использовал 'JTextArea', и он не работал. «JTextPane» сделал трюк. – ryvantage

+0

Одна из последних проблем: мне нужно, чтобы текст был также центрирован ** вертикально **. Есть ли способ сделать это? – ryvantage

Смежные вопросы