ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java Swing:Render Component incl. LaF进入BufferedImage

2019-06-25 10:47:11  阅读:162  来源: 互联网

标签:java swing


我正在尝试使用以下代码将表头单元格呈现为BufferedImage

Component component = table.getTableHeader().getDefaultRenderer().
        getTableCellRendererComponent( table, value, selected, focused, 0, 0 );

component.setBounds( 0, 0, 
                    table.getColumnModel().getColumn( 0 ).getWidth(), 
                    table.getRowHeight() );

BufferedImage img = new BufferedImage( component.getWidth(), 
                                       component.getHeight(),
                                       BufferedImage.TYPE_INT_ARGB );
Graphics g = img.getGraphics();
g.setColor( component.getForeground() );
g.setFont( component.getFont() );
component.paint( g );

此代码在TableCellRenderer#getTableCellRendererComponent方法中运行.
组件被渲染到BufferedImage中,但之前没有应用Look-and-Feel. LaF已在应用程序启动时设置为系统的默认值.

为了渲染组件的应用LaF,我还需要做什么?

编辑:
@Guillaume Polet:
我运行你的代码,我得到相同的结果,但一旦我渲染整个表,我看到以下内容:
在Linux上:

在Windows上:

在Linux上,代码似乎可以工作,而在Windows中它省略了LaF.
在Windows上我会期望类似于:

我的代码:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Vector;

import javax.swing.CellRendererPane;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

class TestPrint {

public static void main( String[] args ) throws ClassNotFoundException, InstantiationException,
        IllegalAccessException, UnsupportedLookAndFeelException {
    UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
    SwingUtilities.invokeLater( new Runnable() {
        @Override
        public void run() {
            new TestPrint().run();
        }
    } );
}

protected void run() {
    JTable table = new JTable( createData() );
    int column = 1;

    TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();

    Component component = renderer.getTableCellRendererComponent( table, table.getColumnName( column ), false,
            false, -1, column );

    component.setBounds( 0, 0, table.getColumnModel().getColumn( 0 ).getWidth(), table.getRowHeight() );

    BufferedImage img = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB );
    Graphics g = img.getGraphics();
    g.setClip( 0, 0, component.getWidth(), component.getHeight() );
    g.setColor( component.getForeground() );
    g.setFont( component.getFont() );

    CellRendererPane cellRendererPane = new CellRendererPane();
    cellRendererPane.paintComponent( g, component, table, 0, 0, component.getWidth(), component.getHeight() );

    // SwingUtilities.paintComponent( g, component, table,
    // new Rectangle( 0, 0, component.getWidth(), component.getHeight() ) );

    // component.paint( g );

    showTable( table );
    showImage( img );
}

private void showImage( BufferedImage img ) {
    JOptionPane.showMessageDialog( null, new JLabel( new ImageIcon( img ) ), "Test",
            JOptionPane.INFORMATION_MESSAGE, null );
}

private void showTable( JTable table ) {
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setViewportView( table );

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.setLayout( new BorderLayout() );
    frame.add( scrollPane, BorderLayout.CENTER );
    frame.setSize( 400, 300 );
    frame.setVisible( true );
}

private DefaultTableModel createData() {
    DefaultTableModel data = new DefaultTableModel( 0, 6 );

    for ( int i = 0; i < 30; i++ ) {
        Vector v = new Vector();

        for ( int k = 0; k < 6; k++ ) {
            v.add( new Float( k / (float) i ) );
        }

        data.addRow( v );
    }
    return data;
}
}

解决方法:

这似乎对我来说很好(虽然系统L& F和默认系统之间的区别并不明显)

示例(上面是原生L& F,下面是金属):

并创建那些代码(只需注释主要的第一行,看看默认的L& F)

import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class TestPrint {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestPrint().run();
            }
        });
    }

    protected void run() {
        JTable table = new JTable(new Vector<Vector<Object>>(), new Vector<String>(Arrays.asList("Hello", "World")));
        int column = 1;
        Component component = table.getTableHeader().getDefaultRenderer()
                .getTableCellRendererComponent(table, table.getColumnName(column), false, false, -1, column);
        component.setBounds(0, 0, table.getColumnModel().getColumn(0).getWidth(), table.getRowHeight());
        BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();
        g.setColor(component.getForeground());
        g.setFont(component.getFont());
        component.paint(g);
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(img)), "Test", JOptionPane.INFORMATION_MESSAGE, null);
        System.exit(0);
    }
}

编辑:确实Windows“皮肤”没有正确绘制.我不确定为什么它不直接绘画(可能是因为渲染器不是“实时”组件).但是,一个简单的技巧是打印它,是打印整个表头,但使用一个Graphics,它被转换为我们想要的列标题并剪切到列标题的大小:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class TestPrint {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestPrint().run();
            }
        });
    }

    protected void run() {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTable table = new JTable(new Vector<Vector<Object>>(), new Vector<String>(Arrays.asList("Hello", "World")));
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setVisible(true);
        int column = 1;
        Rectangle headerRect = table.getTableHeader().getHeaderRect(column);
        BufferedImage img = new BufferedImage(headerRect.width, headerRect.height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();
        g.translate(-headerRect.width, 0);
        table.getTableHeader().print(g);
        frame.add(new JLabel(new ImageIcon(img)), BorderLayout.SOUTH);
        frame.pack();
    }
}

标签:java,swing
来源: https://codeday.me/bug/20190625/1285319.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有