Я предлагал совет по захвату изображения табличных данных в Java API или инструменте для преобразования табличных данных в файл изображения PNG - когда OP запросил образец кода. Оказывается, это сложнее, чем я думал! Заголовок JTable
исчезает из PNG, который записывает код.
PNG
Снимок экрана
import javax.swing.*;
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
class TableImage {
public static void main(String[] args) throws Exception {
Object[][] data = {
{"Hari", new Integer(23), new Double(78.23), new Boolean(true)},
{"James", new Integer(23), new Double(47.64), new Boolean(false)},
{"Sally", new Integer(22), new Double(84.81), new Boolean(true)}
};
String[] columns = {"Name", "Age", "GPA", "Pass"};
JTable table = new JTable(data, columns);
JScrollPane scroll = new JScrollPane(table);
JPanel p = new JPanel(new BorderLayout());
p.add(scroll,BorderLayout.CENTER);
JOptionPane.showMessageDialog(null, p);
BufferedImage bi = new BufferedImage(
(int)p.getSize().getWidth(),
(int)p.getSize().getHeight(),
BufferedImage.TYPE_INT_RGB
);
Graphics g = bi.createGraphics();
p.paint(g);
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
ImageIO.write(bi,"png",new File("table.png"));
}
}
Примечание. Я проверил класс camicar Screen Image и включил вызов метода doLayout(Component)
. Метод полезен, если Component
никогда не реализовывался на экране, но не влияет на этот код (который всплывает панель, содержащая таблицу в панели параметров, прежде чем пытаться ее отобразить).
Что необходимо для получения заголовка таблицы?
Обновление 1
Изменение строки.
p.paint(g);
.. to (с соответствующим импортом)..
p.paint(g);
JTableHeader h = table.getTableHeader();
h.paint(g);
.. производит..
Я буду настраивать его.
Обновление 2
kleopatra (стратегия 1) и camickr (стратегия 2) предоставили каждому ответ, оба из которых работают, и ни одно из них не требует добавления JTable
к фиктивной компоненте (что является огромным взломом IMO).
В то время как стратегия 2 будет обрезать (или развернуть) до "только таблицы", первая стратегия захватит панель, содержащую таблицу. Это становится проблематичным, если таблица содержит много записей, отображающих изображение усеченной таблицы со строкой прокрутки.
В то время как стратегия 1 может быть дополнительно изменена, чтобы обойти это, мне действительно нравится аккуратная простота стратегии 2, поэтому она получает тик.
Как указывал Клеопатра, не было необходимости в настройке. Поэтому я попробую еще раз.
Обновление 3
Это изображение, созданное методами, предложенными как camickr, так и kleopatra. Я бы поставил его дважды, но, на мой взгляд, они идентичны (хотя я не сделал сравнения по пикселям за пикселями).
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
class TableImage {
String[] columns = {"Name", "Age", "GPA", "Pass"};
/** Any resemblance to persons living or dead is purely incidental. */
Object[][] data = {
{"André", new Integer(23), new Double(47.64), new Boolean(false)},
{"Jeanie", new Integer(23), new Double(84.81), new Boolean(true)},
{"Roberto", new Integer(22), new Double(78.23), new Boolean(true)}
};
TableImage() {
}
public JTable getTable() {
JTable table = new JTable(data, columns);
table.setGridColor(new Color(115,52,158));
table.setRowMargin(5);
table.setShowGrid(true);
return table;
}
/** Method courtesy of camickr.
https://stackoverflow.com/info/7369814/why-does-the-jtable-header-not-appear-in-the-image/7375655#7375655
Requires ScreenImage class available from..
http://tips4java.wordpress.com/2008/10/13/screen-image/ */
public BufferedImage getImage1(JTable table) {
JScrollPane scroll = new JScrollPane(table);
scroll.setColumnHeaderView(table.getTableHeader());
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JPanel p = new JPanel(new BorderLayout());
p.add(scroll, BorderLayout.CENTER);
BufferedImage bi = ScreenImage.createImage(p);
return bi;
}
/** Method courtesy of kleopatra.
https://stackoverflow.com/info/7369814/why-does-the-jtable-header-not-appear-in-the-image/7372045#7372045 */
public BufferedImage getImage2(JTable table) {
JScrollPane scroll = new JScrollPane(table);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JPanel p = new JPanel(new BorderLayout());
p.add(scroll, BorderLayout.CENTER);
// without having been shown, fake a all-ready
p.addNotify();
// manually size to pref
p.setSize(p.getPreferredSize());
// validate to force recursive doLayout of children
p.validate();
BufferedImage bi = new BufferedImage(p.getWidth(), p.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
p.paint(g);
g.dispose();
return bi;
}
public void writeImage(BufferedImage image, String name) throws Exception {
ImageIO.write(image,"png",new File(name + ".png"));
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
TableImage ti = new TableImage();
JTable table;
BufferedImage bi;
table = ti.getTable();
bi = ti.getImage1(table);
ti.writeImage(bi, "1");
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
table = ti.getTable();
bi = ti.getImage2(table);
ti.writeImage(bi, "2");
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
}
}
Оба достигают цели. Используя метод camickr, вы используете дополнительную силу API ScreenImage. Использование метода kleopatra - около дюжины строк (меньше комментариев и пробелов) чистого J2SE.
В то время как ScreenImage - это класс, который я буду использовать и рекомендовать в будущем, другой подход с использованием ядра J2SE - это то, что я, вероятно, использовал бы для этого точного обстоятельства.
Итак, пока "тик" останется с камикром, щедрость будет клеопатра.