jtable 到图像的转换未正确发生

2024-01-30

我正在尝试从表格创建缓冲图像,当我将表格添加到应用程序框架并设置大小时,我可以正确查看它,但是当我将其转换为图像时,我只能看到表格的第一行其余的在表格之外并且没有标题。

生成表的代码是

  table = new JTable();

    String[] table_header = null;

    TextAreaRenderer textAreaRenderer = new TextAreaRenderer();
    table_model = new DefaultTableModel() {

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };

    table.setModel(table_model);
    table.setSize(300, 700);
    JScrollPane pane = new JScrollPane(table);
    createTableDataSet(input1, input2, varient, headertype);
    TableColumnModel cmodel = table.getColumnModel();
    table_header = obtainTableHeader(headertype);
    for (int i = 0; i < table_header.length; i++) {
        cmodel.getColumn(i).setCellRenderer(textAreaRenderer);
    }


    return table;

生成图像的代码是:

 JTableHeader header =table.getTableHeader();
    int w = Math.max(table.getWidth(), header.getWidth());
    int h = table.getHeight() + header.getHeight();
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    header.paint(g2);
    g2.translate(0, header.getHeight());
    table.paint(g2);
    g2.dispose();
    try {
        ImageIO.write(bi, "png", new File("year.png"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

The image of the table is here

更新1:我可能已经找到问题的原因了。我使用以下代码片段来增加单元格的大小,以便将文本包装到单元格中。包括导致问题的代码 私有最终 DefaultTableCellRenderer 渲染器 = new DefaultTableCellRenderer();

// Column heights are placed in this Map 
private final Map<JTable, Map<Object, Map<Object, Integer>>> tablecellSizes = new HashMap<JTable, Map<Object, Map<Object, Integer>>>(); 

/** 
 * Creates a text area renderer. 
 */ 
public TextAreaRenderer() { 
    setLineWrap(true); 
    setWrapStyleWord(true); 
} 

/** 
 * Returns the component used for drawing the cell.  This method is 
 * used to configure the renderer appropriately before drawing. 
 * 
 * @param table      - JTable object 
 * @param value      - the value of the cell to be rendered. 
 * @param isSelected - isSelected   true if the cell is to be rendered with the selection highlighted; 
 *                   otherwise false. 
 * @param hasFocus   - if true, render cell appropriately. 
 * @param row        - The row index of the cell being drawn. 
 * @param column     - The column index of the cell being drawn. 
 * @return - Returns the component used for drawing the cell. 
 */ 
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 
                                               boolean hasFocus, int row, int column) { 
    // set the Font, Color, etc. 
    renderer.getTableCellRendererComponent(table, value, 
            isSelected, hasFocus, row, column); 
    setForeground(renderer.getForeground()); 
    setBackground(renderer.getBackground()); 
    setBorder(renderer.getBorder()); 
    setFont(renderer.getFont()); 
    setText(renderer.getText()); 

    TableColumnModel columnModel = table.getColumnModel(); 
    setSize(columnModel.getColumn(column).getWidth(), 0); 
    int height_wanted = (int) getPreferredSize().getHeight(); 
    addSize(table, row, column, height_wanted); 
    height_wanted = findTotalMaximumRowSize(table, row); 
    if (height_wanted != table.getRowHeight(row)) { 
        table.setRowHeight(row, height_wanted); 
    } 
    return this; 
} 

/** 
 * @param table  - JTable object 
 * @param row    - The row index of the cell being drawn. 
 * @param column - The column index of the cell being drawn. 
 * @param height - Row cell height as int value 
 *               This method will add size to cell based on row and column number 
 */ 
private void addSize(JTable table, int row, int column, int height) { 
    Map<Object, Map<Object, Integer>> rowsMap = tablecellSizes.get(table); 
    if (rowsMap == null) { 
        tablecellSizes.put(table, rowsMap = new HashMap<Object, Map<Object, Integer>>()); 
    } 
    Map<Object, Integer> rowheightsMap = rowsMap.get(row); 
    if (rowheightsMap == null) { 
        rowsMap.put(row, rowheightsMap = new HashMap<Object, Integer>()); 
    } 
    rowheightsMap.put(column, 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. 
 * 
 * @param table -JTable object 
 * @param row   - The row index of the cell being drawn. 
 * @return row maximum height as integer value 
 */ 
private int findTotalMaximumRowSize(JTable table, int row) { 
    int maximum_height = 0; 
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns(); 
    while (columns.hasMoreElements()) { 
        TableColumn tc = columns.nextElement(); 
        TableCellRenderer cellRenderer = tc.getCellRenderer(); 
        if (cellRenderer instanceof TextAreaRenderer) { 
            TextAreaRenderer tar = (TextAreaRenderer) cellRenderer; 
            maximum_height = Math.max(maximum_height, 
                    tar.findMaximumRowSize(table, row)); 
        } 
    } 
    return maximum_height; 
} 

/** 
 * This will find the maximum row size 
 * 
 * @param table - JTable object 
 * @param row   - The row index of the cell being drawn. 
 * @return row maximum height as integer value 
 */ 
private int findMaximumRowSize(JTable table, int row) { 
    Map<Object, Map<Object, Integer>> rows = tablecellSizes.get(table); 
    if (rows == null) return 0; 
    Map<Object, Integer> rowheights = rows.get(row); 
    if (rowheights == null) return 0; 
    int maximum_height = 0; 
    for (Map.Entry<Object, Integer> entry : rowheights.entrySet()) { 
        int cellHeight = entry.getValue(); 
        maximum_height = Math.max(maximum_height, cellHeight); 
    } 
    return maximum_height; 
} 

这导致单元格无法正确显示。一旦我删除此代码,该表就会通过包含 kleopatra 的代码正确生成。但我遇到了单元格中自动换行的问题。

谢谢, 巴维亚

附:当在我的代码中使用 new JTable(row,fields) 创建表对象时,我使用了上面相同的代码来生成图像,序列化的哈希图被读取并插入到 table_model 中


基本上,你必须做布局工作all您想要绘制到图像的组件,即在本例中是表和 tableHeader,通过设置它们的大小(使用下面的 pref)。

顺便说一句,添加到 JScrollPane 没有帮助(如您所见),除非实现了窗格 - 添加标题是由 addNotify 中的表完成的。

    JTable table = new JTable(new AncientSwingTeam());
    JTableHeader header =table.getTableHeader();
    table.setSize(table.getPreferredSize());
    header.setSize(header.getPreferredSize());
    int w = Math.max(table.getWidth(), header.getWidth());
    int h = table.getHeight() + header.getHeight();
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    header.paint(g2);
    g2.translate(0, header.getHeight());
    table.paint(g2);
    g2.dispose();
    JLabel label = new JLabel(new ImageIcon(bi));
    showInFrame(label, "image of table");

编辑:对 TextArea Renderer 的评论

一般规则是永远不要更改渲染器的 getXXRendererComponent 中的调用表,作为参数给出的表严格被视为只读。违反规则可能会导致丑陋的循环(在绘制时设置新的 rowHeight 会触发新的绘制请求)或伪影(无法保证何时调用渲染器,因此可能已设置或未设置正确的 rowheight),如您在此处看到的。

而是在外面的某个地方进行测量。在检测到可能导致更新大小的变化(例如在模型中)时,遍历行,测量其所有单元格并更新到最大。只需从渲染器中提取所有大小调整代码即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jtable 到图像的转换未正确发生 的相关文章

随机推荐

  • 撤消 git 过滤分支

    我不小心使用 git filter branch 从我的存储库中删除了一个文件 git filter branch f index filter git rm cached ignore unmatch images thumb a JPG
  • 在编译时生成唯一的数字

    我想为标题中的每个类生成唯一的数字 在我的例子中为素数 但我们可以说这应该只是连续的数字 即 1 2 3 4 等 当然我可以对这些进行硬编码 struct A enum ID 1 struct B enum ID 2 struct C en
  • 使用 React Navigation,如何强制抽屉导航器弹出到堆栈顶部?

    我正在使用 React Navigation 并有一个抽屉式导航器 其中包含多个 Stack Navigator 作为其项目 当我打开抽屉导航器并单击某个项目时 它会显示我单击的堆栈中的第一个屏幕 当我转到堆栈中的第二个屏幕 然后打开抽屉并
  • JS:查找对象数组中的最大数字

    找到对象数组中最大数字并返回该对象的最简单方法是什么 var arr num 0 5 num 1 num 0 35 尝试使用 forEach 但除了存储每个数字并比较它们之外无法找到一种方法来做到这一点 任何帮助表示赞赏 提前致谢 redu
  • 尝试了解 Latex、Sweave 和 R 之间的工作流程

    假设我编写了以下小 Rnw 文件 documentclass article usepackage utf8 inputenc usepackage Sweave usepackage tikz usepackage pgf begin d
  • SVG 过滤器无法正常工作直线[重复]

    这个问题在这里已经有答案了
  • Visual Studio 不显示打字稿错误

    我遇到了奇怪的问题 我已经安装了 VS2013 和 typescript 当我点击保存按钮时 ts文件 调用 ts 编译器 但 VS 没有显示任何 ts 错误 如果编译器失败我只会收到一条消息 Input file contained se
  • IronRouter 上的上一页位置

    在 IronRouter 中 有没有办法在转到下一页之前获取上一页位置 我可以使用一个事件来获取此信息吗 提前致谢 由于 Iron Router 使用常用的 History API 因此您可以使用普通的 JS 方法 history go 1
  • 动态类型测试未按预期工作

    这是一个SSCCE http sscce org 我有一个地图容器类 其中内部Map是根据需要创建的set被调用的方法 flow use strict class MapContainer map Map
  • Python 跨不同类的 asyncio.Event()

    我正在编写一个 Python 程序来与基于 CAN 总线的设备进行交互 我正在成功使用 python can 模块来实现此目的 我还使用 asyncio 来响应异步事件 我编写了一个由 CanBusSequencer 类使用的 CanBus
  • .NET Compact Framework 能否获得单元格中包含多行文本的网格?

    是否可以使用 NET Compact 框架在网格单元中显示多行文本 我们需要创建一个网格 其中中间列包含一个地址 我们希望通过多行来显示这一点 并 可能 对最后一行应用一些格式 e g 123 任意街伯明翰 B1 2DU tel 0123
  • PhantomJS 不支持 Javascript 国际化 API

    我有一系列Jasmine针对运行的测试AngularJs使用 ECMAScript 国际化 API 的服务 当我通过 Chrome 运行它们时 它们都运行成功 但是 当我使用PhantomJS通过 Maven 运行它们 它们看起来都失败了P
  • T4 报告编译转换:类、结构中的标记“this”无效

    尝试运行 T4 模板不可变对象图 https github com AArnott ImmutableObjectGraph给出的错误为 Error 5 Compiling transformation Invalid token this
  • 使用 minicolors jquery

    我一直在尝试实施迷你颜色 http www abeautifulsite net blog 2011 02 jquery minicolors a color selector for input controls 一切都很好 我已经按照我
  • 如何在 Angular2 中将 HTML 转换为 pdf?

    我需要将动态生成的 html 表转换为 pdf 并能够打印它 我需要它在 angular2 和 Typescript 中完成 JSPDF 适用于 Angular 2 您需要从 dt 下载定义 将库导入为 import as jsPDF fr
  • instanceof 的模式匹配引发令人困惑的错误:表达式类型 Triple 是模式类型 Triple 的子类型

    我有 Java 19 我正在尝试对我创建的记录进行一些简单的模式匹配 然而 Java 给了我一个非常令人困惑的编译错误 这是我可以做的导致错误的最简单的例子 public class ExpressionTypeIsASubsetOfPat
  • TypeScript - 如何从事件处理程序方法访问类实例

    在下面的代码片段中 我有一个TypeScript 类和实例方法buz是画布的监听器 click event this关键字在buz方法指的是事件的目标对象 画布 如何访问foo实例来自buz method class Foo constru
  • XAML 中的动画按钮背景颜色

    我是 WPF 和 XAML 的新手 所以我有ResourceDictionary 目前一键
  • Android 许可证检查直接进入 applicationError(...)

    我刚刚在我的应用程序中实现了 android 服务器检查 我使用 StrictPolicy 方法是因为我可能对盗版版本的下载量是市场版本的 5 倍感到有点苦恼 无论如何 我基本上将该方法逐字编码到我的源代码中 但是 当我将开发人员控制台上的
  • jtable 到图像的转换未正确发生

    我正在尝试从表格创建缓冲图像 当我将表格添加到应用程序框架并设置大小时 我可以正确查看它 但是当我将其转换为图像时 我只能看到表格的第一行其余的在表格之外并且没有标题 生成表的代码是 table new JTable String tabl