Jtable表头换行显示
2011-11-15 13:47
302 查看
在jtable渲染表头时,由于有些表头字体较多,需要折行显示,但jtable没有自动折行的功能,所以自己实现表头的渲染器.
有两种方案实现表头的折行渲染:
1、渲染器继承自JTextArea,实现TableCellRenderer接口,具体代码如下:
Java代码
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代码
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代码
HeaderRendererHh renderer = new HeaderRendererHh();
TableColumnModel cmodel = table.getColumnModel();
for (int i = 0; i < cmodel.getColumnCount(); i++) {
cmodel.getColumn(i).setHeaderRenderer(renderer);
}
下面方法是根据上面第二中方法来做的,因为我的表头换行的时候加了换行符号\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、渲染器继承自JTextArea,实现TableCellRenderer接口,具体代码如下:
Java代码
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; } }
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代码
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();
}
}
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代码
HeaderRendererHh renderer = new HeaderRendererHh();
TableColumnModel cmodel = table.getColumnModel();
for (int i = 0; i < cmodel.getColumnCount(); i++) {
cmodel.getColumn(i).setHeaderRenderer(renderer);
}
下面方法是根据上面第二中方法来做的,因为我的表头换行的时候加了换行符号\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
相关文章推荐
- 利用JLabel能够解析HTML的特性实现JTable表头换行
- Showing JTable Header Without Using JScrollPane java中的JTable不显示表头的原因
- 让 JTable 不显示表头
- JTable中怎样显示表头
- 关于java代码jtable不显示表头的解决
- GridView自动生成列时,利用DIV控制显示长宽 控件数据行和表头文字不换行
- 让JTable不显示表头
- JTable表头显示问题以及如何让某行选中
- [JAVA] 设置图标,设置字体,设置界面风格,JTable显示表头且设置不可编辑
- JTable&nbsp;表头不显示问题&nbsp;…
- JTable(swing)不显示表头
- JTable不能正常显示表头
- [Swing]JTable 表头显示问题
- JAVA的JTable表头不显示的解决办法
- jqgrid--表头换行显示
- java JTable表头自动换行
- GridView自动生成列时,利用DIV控制显示长宽 控件数据行和表头文字不换行
- GridView自动生成列时,利用DIV控制显示长宽 控件数据行和表头文字不换行
- 关于JTable不能显示表头的问题(个人小结)
- JaveSE-JTable 表头、数据居中显示