`
weibaojun
  • 浏览: 98846 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

jtable中表头换行显示

    博客分类:
  • java
阅读更多

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

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

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

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>标记,实现换行显示,代码如下:

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就可以了,如:

HeaderRendererHh renderer = new HeaderRendererHh();
TableColumnModel cmodel = table.getColumnModel();
for (int i = 0; i < cmodel.getColumnCount(); i++) {
	cmodel.getColumn(i).setHeaderRenderer(renderer);
}

 

分享到:
评论
2 楼 gaozi131 2009-12-28  
gaozi131 写道

感谢楼主的分享,刚好解决了我一个项目的问题,哈哈。加油!!!


楼主:你这个只有第一次才有效果吗?当我执行查询或者分页之后,就没有效果了哎!!能帮我分析下吗?谢谢了!
1 楼 gaozi131 2009-12-28  

感谢楼主的分享,刚好解决了我一个项目的问题,哈哈。加油!!!

相关推荐

    JTable自动换行

    在处理`JTable`时,我们有时需要使其单元格内容支持自动换行,以便更好地显示长文本。标题“JTable自动换行”正是指向这个功能,即如何在`JTable`的单元格内实现文本的自动换行。 默认情况下,`JTable`的单元格使用...

    JTable表头排序的两种方法

    在Java Swing库中,`JTable`是用于创建和显示二维数据的重要组件。它提供了丰富的功能,包括排序,使得用户可以方便地对表格中的数据进行升序或降序排列。本篇文章将详细介绍如何实现`JTable`表头的排序功能,并提供...

    netbeans jtable 复杂表头的实现方法

    本篇文章将详细介绍如何在NetBeans中实现`JTable`的复杂表头。 首先,我们需要理解`JTable`的基本结构。`JTable`由行和列组成,而表头(`JTableHeader`)则对应于列标题。默认情况下,`JTableHeader`中的每个单元格...

    JTable表头合并

    而"JTable表头合并"是Swing中的一个高级特性,允许开发者创建具有复杂结构的表头,以更好地呈现和组织数据。这种功能特别适用于那些需要将相关列分组或分类的情况。 表头合并是通过`DefaultTableColumnModel`的`...

    复杂JTable-跨列表头

    "复杂JTable-跨列表头"是一个特殊实现,它扩展了JTable的功能,允许在表头中进行列的合并,这在显示层次结构或分组数据时特别有用。 跨列表头(或合并列头)的概念是将多个列的标题合并为一个大的表头单元格,通常...

    复杂JTable(复杂表头、跨行列表体)

    同时,自定义的渲染器可以帮助我们在表头中显示多层次的信息。 **2. 跨行列表体** 跨行列表体通常涉及到单元格合并,这在`JTable`中可以通过重写`AbstractTableModel`类的`getColumnCount()`、`getRowCount()`、`...

    jtable多级表头

    9. **测试与优化**:最后,确保在不同的操作系统和屏幕分辨率下,多级表头的显示效果正常,并进行性能优化,确保流畅的用户交互。 实现`jtable多级表头`不仅涉及到基本的`JTable`操作,还涉及到图形绘制、事件处理...

    JTble使用不显示表头的问题

    以下将详细分析“JTble使用不显示表头的问题”这一知识点,并提供解决方案。 ### 问题描述 在给定的代码示例中,开发者尝试创建一个包含表头和数据行的`JTable`。代码中初始化了一个`Vector`对象`column`来存储表头...

    jtable 2行表头显示功能

    jtable 2 行表头显示功能 TableHeaderUI SimpleHashMap NewJFrame

    Jtable中加入复选框的两种方法

    JTable中加入复选框的两种方法 在Java中,JTable是一个常用的表格控件,用于显示和编辑表格数据。然而,在JTable中加入复选框是一个常见的需求,但是却不是那么容易实现。本文将介绍JTable中加入复选框的两种方法,...

    JTable添加CheckBox

    本示例探讨如何在`JTable`中添加`CheckBox`,并实现表头的`JCheckBox`全选联动功能。这在需要用户进行多选操作的界面中非常常见,比如在列表中勾选多项进行批量操作。 首先,我们从`CheckTableModle.java`文件开始...

    Swing中JTABLE中添加JBUTTON控件

    在Java的Swing库中,`JTable`是用于创建数据网格视图的重要组件,它允许用户以表格的形式查看和操作数据。而`JButton`则是一个常用的按钮控件,通常用于触发某些动作或事件。将`JButton`添加到`JTable`中可以为用户...

    JTable连接Access并显示

    本教程将深入探讨如何利用JTable与Microsoft Access数据库进行交互,并将数据动态地显示在表格中。这对于开发需要从数据库获取并展示数据的桌面应用来说是至关重要的。 首先,我们需要了解JTable的基本构造。JTable...

    Java的Jtable、从数据库取数据显示在表格中

    #### 二、将查询结果显示在JTable中 1. **初始化表格**: - 在`displayResultSet`方法中,首先检查结果集中是否包含记录 `boolean moreRecords = rs.next(); if (!moreRecords) { ... }`。 - 如果有记录,则初始化...

    java取出mysql中数据,显示在jtable里面

    根据给定的文件信息,我们可以总结出以下关于如何使用Java从MySQL数据库中获取数据并在JTable中显示的相关知识点: ### 一、导入必要的库 在Java程序中操作MySQL数据库及Swing组件,需要导入以下几个包: 1. `java...

    Jtable 中放入多个按钮

    在Java Swing库中,`JTable`是一个非常重要的组件,用于展示二维数据表格。当我们需要在`JTable`中实现更复杂的交互,比如在一个单元格内放置多个按钮时,这通常涉及到自定义`TableCellRenderer`和`TableCellEditor`...

    使用NetBeans用jTable控件实现分页显示数据库记录

    本程序是先通过各个方法统计出数据库记录的总数,然后通过总记录数数计算出总页数和当前页数以及当前页要显示的记录号,最后将记录保存到二维数组中。通过jTable控件显示出来。 PageTable ------------------//源...

    JTable+显示数据库中的记录

    本篇内容将深入讲解如何利用`JTable`来显示数据库中的记录,以及涉及到的相关技术如JDBC(Java Database Connectivity)。 首先,要实现`JTable`与数据库的交互,我们需要了解JDBC,它是Java平台标准版(Java SE)...

    Java SE程序 把Jtable中的数据导出到Excel中

    Java SE程序 把Jtable中的数据导出到Excel中Java SE程序 把Jtable中的数据导出到Excel中Java SE程序 把Jtable中的数据导出到Excel中Java SE程序 把Jtable中的数据导出到Excel中Java SE程序 把Jtable中的数据导出到...

Global site tag (gtag.js) - Google Analytics