多行标题的JTable标题文字换行(自定义TableCellRenderer) [英] JTable header text wrapping for multiline header (custom TableCellRenderer)

查看:43
本文介绍了多行标题的JTable标题文字换行(自定义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/

为JTable创建多行标头

Java JTable标头自动换行

以上解决方案都建议使用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.

如何更改JTable标头高度?

按照上述解决方案手动设置页眉高度仅是我要执行的操作的一半,因为这样文本仍无法正确换行并且无法确定高度.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆