Jtable表头换行显示

在jtable渲染表头时,由于有些表头字体较多,需要折行显示,但jtable没有自动折行的功能,所以自己实现表头的渲染器.

有两种方案实现表头的折行渲染:

1、渲染器继承自JTextArea,实现TableCellRenderer接口,具体代码如下:

Java代码   收藏代码
  1. import java.awt.Component;  
  2. import java.awt.Dimension;  
  3. import java.util.Enumeration;  
  4. import java.util.HashMap;  
  5. import java.util.Iterator;  
  6. import java.util.Map;  
  7.   
  8. import javax.swing.JTable;  
  9. import javax.swing.JTextArea;  
  10. import javax.swing.UIManager;  
  11. import javax.swing.table.DefaultTableCellRenderer;  
  12. import javax.swing.table.JTableHeader;  
  13. import javax.swing.table.TableCellRenderer;  
  14. import javax.swing.table.TableColumn;  
  15. import javax.swing.table.TableColumnModel;  
  16.   
  17. public class TextAreaHeaderRenderer extends JTextArea implements  
  18.         TableCellRenderer {  
  19.     private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();  
  20.     /** map from table to map of rows to map of column heights */  
  21.     private final Map cellSizes = new HashMap();  
  22.   
  23.     public TextAreaHeaderRenderer() {  
  24.         setLineWrap(true);  
  25.         setWrapStyleWord(true);  
  26.         setHighlighter(null);  
  27.     }  
  28.   
  29.     public Component getTableCellRendererComponent(  
  30.             //  
  31.             JTable table, Object obj, boolean isSelected, boolean hasFocus,  
  32.             int row, int column) {  
  33.         // 设置表头渲染时的一些属性参数  
  34.         JTableHeader header = table.getTableHeader();  
  35.         setForeground(header.getForeground());  
  36.         setBackground(header.getBackground());  
  37.         setFont(header.getFont());  
  38.         setText(obj.toString());  
  39.         setBorder(UIManager.getBorder("TableHeader.cellBorder"));  
  40.         // This line was very important to get it working with JDK1.4  
  41.         TableColumnModel columnModel = table.getColumnModel();  
  42.         int width = columnModel.getColumn(column).getWidth();  
  43.         setSize(width, 100000);  
  44.         int height_wanted = (int) getPreferredSize().getHeight();  
  45.         addSize(table, column, height_wanted);  
  46.         height_wanted = findTotalMaximumRowSize(table, column);  
  47.         if (height_wanted != header.getHeight()) {  
  48.             // 设置JTextArea的大小  
  49.             this.setSize(new Dimension(width, height_wanted));  
  50.         }  
  51.         return this;  
  52.     }  
  53.   
  54.     private void addSize(JTable table, int column, int height) {  
  55.         Map cols = (Map) cellSizes.get(table);  
  56.         if (cols == null) {  
  57.             cellSizes.put(table, cols = new HashMap());  
  58.         }  
  59.         Map rowheights = (Map) cols.get(new Integer(column));  
  60.         if (rowheights == null) {  
  61.             cols.put(new Integer(column), rowheights = new HashMap());  
  62.         }  
  63.         rowheights.put(new Integer(column), new Integer(height));  
  64.     }  
  65.   
  66.     /** 
  67.      * Look through all columns and get the renderer. If it is also a 
  68.      * TextAreaRenderer, we look at the maximum height in its hash table for 
  69.      * this row. 
  70.      */  
  71.     private int findTotalMaximumRowSize(JTable table, int column) {  
  72.         int maximum_height = 0;  
  73.         Enumeration columns = table.getColumnModel().getColumns();  
  74.         while (columns.hasMoreElements()) {  
  75.             TableColumn tc = (TableColumn) columns.nextElement();  
  76.             TableCellRenderer cellRenderer = tc.getHeaderRenderer();  
  77.             if (cellRenderer instanceof TextAreaHeaderRenderer) {  
  78.                 TextAreaHeaderRenderer tar = (TextAreaHeaderRenderer) cellRenderer;  
  79.                 maximum_height = Math.max(maximum_height, tar  
  80.                         .findMaximumRowSize(table, column));  
  81.             }  
  82.             // System.out.println("aaa");  
  83.         }  
  84.         return maximum_height;  
  85.     }  
  86.   
  87.     private int findMaximumRowSize(JTable table, int column) {  
  88.         Map rows = (Map) cellSizes.get(table);  
  89.         if (rows == null)  
  90.             return 0;  
  91.         Map rowheights = (Map) rows.get(new Integer(column));  
  92.         if (rowheights == null)  
  93.             return 0;  
  94.         int maximum_height = 0;  
  95.         for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {  
  96.             Map.Entry entry = (Map.Entry) it.next();  
  97.             int cellHeight = ((Integer) entry.getValue()).intValue();  
  98.             maximum_height = Math.max(maximum_height, cellHeight);  
  99.         }  
  100.         return maximum_height;  
  101.     }  
  102. }  
import java.awt.Component;
import java.awt.Dimension;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class TextAreaHeaderRenderer 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 TextAreaHeaderRenderer() {
		setLineWrap(true);
		setWrapStyleWord(true);
		setHighlighter(null);
	}

	public Component getTableCellRendererComponent(
			//
			JTable table, Object obj, boolean isSelected, boolean hasFocus,
			int row, int column) {
		// 设置表头渲染时的一些属性参数
		JTableHeader header = table.getTableHeader();
		setForeground(header.getForeground());
		setBackground(header.getBackground());
		setFont(header.getFont());
		setText(obj.toString());
		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
		// This line was very important to get it working with JDK1.4
		TableColumnModel columnModel = table.getColumnModel();
		int width = columnModel.getColumn(column).getWidth();
		setSize(width, 100000);
		int height_wanted = (int) getPreferredSize().getHeight();
		addSize(table, column, height_wanted);
		height_wanted = findTotalMaximumRowSize(table, column);
		if (height_wanted != header.getHeight()) {
			// 设置JTextArea的大小
			this.setSize(new Dimension(width, height_wanted));
		}
		return this;
	}

	private void addSize(JTable table, int column, int height) {
		Map cols = (Map) cellSizes.get(table);
		if (cols == null) {
			cellSizes.put(table, cols = new HashMap());
		}
		Map rowheights = (Map) cols.get(new Integer(column));
		if (rowheights == null) {
			cols.put(new Integer(column), 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 column) {
		int maximum_height = 0;
		Enumeration columns = table.getColumnModel().getColumns();
		while (columns.hasMoreElements()) {
			TableColumn tc = (TableColumn) columns.nextElement();
			TableCellRenderer cellRenderer = tc.getHeaderRenderer();
			if (cellRenderer instanceof TextAreaHeaderRenderer) {
				TextAreaHeaderRenderer tar = (TextAreaHeaderRenderer) cellRenderer;
				maximum_height = Math.max(maximum_height, tar
						.findMaximumRowSize(table, column));
			}
			// System.out.println("aaa");
		}
		return maximum_height;
	}

	private int findMaximumRowSize(JTable table, int column) {
		Map rows = (Map) cellSizes.get(table);
		if (rows == null)
			return 0;
		Map rowheights = (Map) rows.get(new Integer(column));
		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;
	}
}

 此种渲染器的缺点是没有办法实现居中对齐。

2、因为JLabel可以解析html中的br,所以利用这个特点,可以动态构建显示的标题,在换行处添加<br>标记,实现换行显示,代码如下:

Java代码   收藏代码
  1. import java.awt.Component;  
  2. import java.awt.Dimension;  
  3. import java.awt.FontMetrics;  
  4.   
  5. import javax.swing.JLabel;  
  6. import javax.swing.JTable;  
  7. import javax.swing.UIManager;  
  8. import javax.swing.table.DefaultTableCellRenderer;  
  9. import javax.swing.table.JTableHeader;  
  10. import javax.swing.table.TableColumnModel;  
  11.   
  12. public class HeaderRendererHh extends DefaultTableCellRenderer {  
  13.   
  14.     public Component getTableCellRendererComponent(JTable table, Object value,  
  15.             boolean isSelected, boolean hasFocus, int row, int column) {  
  16.   
  17.         JTableHeader header = table.getTableHeader();  
  18.         setForeground(header.getForeground());  
  19.         setBackground(header.getBackground());  
  20.         setFont(header.getFont());  
  21.         setOpaque(true);  
  22.         setBorder(UIManager.getBorder("TableHeader.cellBorder"));  
  23.   
  24.         // 得到列的宽度  
  25.         TableColumnModel columnModel = table.getColumnModel();  
  26.         int width = columnModel.getColumn(column).getWidth();  
  27.   
  28.         value = getShowValue(value.toString(), width);  
  29.         setText(value.toString());  
  30.         setSize(new Dimension(width, this.getHeight()));  
  31.   
  32.         setHorizontalAlignment(JLabel.CENTER);  
  33.   
  34.         return this;  
  35.     }  
  36.   
  37.     private Object getShowValue(String value, int colWidth) {  
  38.         // 根据当前的字体和显示值得到需要显示的宽度  
  39.         FontMetrics fm = this.getFontMetrics(this.getFont());  
  40.         int width = fm.stringWidth(value.toString());  
  41.         int test = fm.stringWidth("好");  
  42.         System.out.println(test * value.length());  
  43.         System.out.println(width);  
  44.         if (width < colWidth) {  
  45.             return value;  
  46.         }  
  47.         StringBuffer sb = new StringBuffer("<html>");  
  48.         char str;  
  49.         int tempW = 0;  
  50.         for (int i = 0; i < value.length(); i++) {  
  51.             str = value.charAt(i);  
  52.             tempW += fm.charWidth(str);  
  53.             if (tempW > colWidth) {  
  54.                 sb.append("<br>");  
  55.                 tempW = 0;  
  56.             }  
  57.             sb.append(str);  
  58.         }  
  59.         sb.append("</html>");  
  60.         return sb.toString();  
  61.     }  
  62. }  
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

public class HeaderRendererHh extends DefaultTableCellRenderer {

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

		JTableHeader header = table.getTableHeader();
		setForeground(header.getForeground());
		setBackground(header.getBackground());
		setFont(header.getFont());
		setOpaque(true);
		setBorder(UIManager.getBorder("TableHeader.cellBorder"));

		// 得到列的宽度
		TableColumnModel columnModel = table.getColumnModel();
		int width = columnModel.getColumn(column).getWidth();

		value = getShowValue(value.toString(), width);
		setText(value.toString());
		setSize(new Dimension(width, this.getHeight()));

		setHorizontalAlignment(JLabel.CENTER);

		return this;
	}

	private Object getShowValue(String value, int colWidth) {
		// 根据当前的字体和显示值得到需要显示的宽度
		FontMetrics fm = this.getFontMetrics(this.getFont());
		int width = fm.stringWidth(value.toString());
		int test = fm.stringWidth("好");
		System.out.println(test * value.length());
		System.out.println(width);
		if (width < colWidth) {
			return value;
		}
		StringBuffer sb = new StringBuffer("<html>");
		char str;
		int tempW = 0;
		for (int i = 0; i < value.length(); i++) {
			str = value.charAt(i);
			tempW += fm.charWidth(str);
			if (tempW > colWidth) {
				sb.append("<br>");
				tempW = 0;
			}
			sb.append(str);
		}
		sb.append("</html>");
		return sb.toString();
	}
}

 

两种方法在使用时只要给对应的列添加headerRenderer就可以了,如:

Java代码   收藏代码
  1. HeaderRendererHh renderer = new HeaderRendererHh();  
  2. TableColumnModel cmodel = table.getColumnModel();  
  3. for (int i = 0; i < cmodel.getColumnCount(); i++) {  
  4.     cmodel.getColumn(i).setHeaderRenderer(renderer);  
  5. }  


下面方法是根据上面第二中方法来做的,因为我的表头换行的时候加了换行符号\n,方法如下:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

public class HeaderRendererHh extends DefaultTableCellRenderer {

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

    JTableHeader header = table.getTableHeader();
    setForeground(header.getForeground());
    setBackground(header.getBackground());
    // setFont(header.getFont());
    setFont(new Font(null, Font.BOLD, 13));
    setOpaque(true);
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));

    // 得到列的宽度
    TableColumnModel columnModel = table.getColumnModel();
    int width = columnModel.getColumn(column).getWidth();

    value = getShowValue(value.toString(), width);
    setText(value.toString());
    setSize(new Dimension(width, this.getHeight()));
    setHorizontalAlignment(JLabel.CENTER);

    return this;
  }

  private Object getShowValue(String value, int colWidth) {
    // 根据当前的字体和显示值得到需要显示的宽度
    FontMetrics fm = this.getFontMetrics(this.getFont());
    int width = fm.stringWidth(value.toString());

    StringBuffer sb = new StringBuffer("<html>");
    char str;
    int tempW = 0;
    for (int i = 0; i < value.length(); i++) {
      str = value.charAt(i);
      tempW += fm.charWidth(str);
      char linebreak = '\n';
      if (str == linebreak) {
        sb.append("<br>");
        tempW = 0;
      }
      sb.append(str);
    }
    sb.append("</html>");
    return sb.toString();
  }
}

在java文件中使用以上方法代码如下
HeaderRendererHh headrenderer = new HeaderRendererHh();// 设置Head居中
    TableColumnModel cmodel = tabledata.getColumnModel();
    for (int i = 0; i < cmodel.getColumnCount(); i++) {
      cmodel.getColumn(i).setHeaderRenderer(headrenderer);
    }

http://weibaojun.iteye.com/blog/524507
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值