多行标题的JTable标题文字换行(自定义TableCellRenderer) [英] JTable header text wrapping for multiline header (custom TableCellRenderer)
问题描述
如何获取多行JTable标头,使标头列正确放大以适合某些文本,然后换行到新行?
How can I obtain a multiline JTable header where the header column correctly enlarges to fit some text and then wraps to a new line?
如下所示:
当前搜索上述要求会返回很多解决方案,但这些解决方案都无法真正解决问题:
Currently searching for the above requirements returns a lot of solutions of which none really solves the problem:
http://www.javarichclient.com/multiline-column-header/
以上解决方案都建议使用HTML代码,例如:
The above solutions all propose using HTML code, for instance:
String[] columnNames = {
"<html><center>Closing<br>Date</html>",
"<html><center>Open<br>Price</html>",
"<html>Third<br>column</html>"
};
该解决方案不太好,原因有两个,主要是因为在使用可变列名的情况下,我需要将字符串传递给一个函数,该函数将去除空格并用<br>
符号替换它们,但是,如果列文本包含一行很短的文字.
That solution is not elegant for a couple of reasons, mainly because in the case of variable columns names I need to pass the string to a function which strips spaces and subtitutes them with <br>
symbols, however if the column text contains very short text that appears in a line of its own.
我需要确定一列的最小和最大长度,然后才能使文本居中成为可能,上述解决方案很快变得过度工程化且难以管理.
I would need to decide a minimum and a maximum length of a column and then be able to make text centering possible, the above solution quickly becomes overengineered and unmanageable.
http://www.java2s.com/Code/Java /Swing-Components/MultiLineHeaderTable.htm
http://www.java2s.com/Code/Java /Swing-Components/MultiLineHeaderExample.htm
以上解决方案需要手动创建标题数组,其中单词已正确分割,如下所示:
Above solutions require manually creating a header array with words already correctly split up as in:
public static Object[][] tableHeaders = new Object[][] {
new String[] { "Currency" },
new String[] { "Yesterday's", "Rate" },
new String[] { "Today's", "Rate" },
new String[] { "Rate", "Change" } };
-或-
DefaultTableModel dm = new DefaultTableModel();
dm.setDataVector(
new Object[][] { { "a", "b", "c" }, { "A", "B", "C" } },
new Object[] { "1st\nalpha", "2nd\nbeta", "3rd\ngamma" });
仍然不够优雅,因为列名中的可变文本不可行.
Still not elegant because variable text in the column names would not be feasible.
按照上述解决方案手动设置页眉高度仅是我要执行的操作的一半,因为这样文本仍无法正确换行并且无法确定高度.
Manually setting the header height as in the above solutions is only half of what I want to do, because then text would still not correctly wrap and deciding the height is still not feasible.
当前,我所能做的就是创建一个自定义TableCellRenderer,但还没有解决方案:
Currently all I was able was to create a custom TableCellRenderer but yet no solution:
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import javax.swing.*;
import javax.swing.table.*;
/**
* @version 1.0 11/09/98
*/
public class MultiLineHeaderExample extends JFrame
{
MultiLineHeaderExample()
{
super("Multi-Line Header Example");
DefaultTableModel dm = new DefaultTableModel();
dm.setDataVector(new Object[][]
{
{
"a", "b", "c"
},
{
"A", "B", "C"
}
},
new Object[]
{
"My First Column, Very Long But Space Separated", "short col", "VeryLongNoSpaceSoShouldSomeHowWrap"
});
JTable table = new JTable(dm);
MultiLineHeaderRenderer renderer = new MultiLineHeaderRenderer();
Enumeration enumK = table.getColumnModel().getColumns();
while (enumK.hasMoreElements())
{
((TableColumn) enumK.nextElement()).setHeaderRenderer(renderer);
}
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
setSize(400, 110);
setVisible(true);
}
public static void main(String[] args)
{
MultiLineHeaderExample frame = new MultiLineHeaderExample();
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
class MultiLineHeaderRenderer extends JList implements TableCellRenderer
{
public MultiLineHeaderRenderer()
{
ListCellRenderer renderer = getCellRenderer();
((JLabel) renderer).setHorizontalAlignment(JLabel.CENTER);
setCellRenderer(renderer);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
setFont(table.getFont());
String str = (value == null) ? "" : value.toString();
BufferedReader br = new BufferedReader(new StringReader(str));
String line;
Vector v = new Vector();
try
{
while ((line = br.readLine()) != null)
{
v.addElement(line);
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
setListData(v);
return this;
}
}
推荐答案
此处还使用JTextArea
并在调整表大小时还调整了标题高度.正确计算表格标题高度的关键是setSize(width, getPreferredSize().height);
This here also uses JTextArea
and also resizes the header height when the table is resized. The key to the correct calculation of the table header height is setSize(width, getPreferredSize().height);
class MultiLineTableHeaderRenderer extends JTextArea implements TableCellRenderer
{
public MultiLineTableHeaderRenderer() {
setEditable(false);
setLineWrap(true);
setOpaque(false);
setFocusable(false);
setWrapStyleWord(true);
LookAndFeel.installBorder(this, "TableHeader.cellBorder");
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
int width = table.getColumnModel().getColumn(column).getWidth();
setText((String)value);
setSize(width, getPreferredSize().height);
return this;
}
}
这篇关于多行标题的JTable标题文字换行(自定义TableCellRenderer)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!