Я предлагал совет по захвату изображения табличных данных на Java API или Инструменте для преобразования табличных данных в файл изображения PNG - когда ОП запросил образец кода.Оказывается сложнее, чем я думал!Заголовок 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"));
}
}
Примечание. Я проверил класс изображения Camickr и включил вызов метода doLayout(Component)
.Этот метод полезен в том случае, если Component
никогда не был реализован на экране, но не влияет на этот код (при котором панель, содержащая таблицу, появляется на панели параметров перед попыткой ее визуализации).
Чтонужен для того, чтобы получить заголовок таблицы для рендеринга?
Обновление 1
Изменение строки ..
p.paint(g);
.. на (с соответствующим импортом)..
p.paint(g);
JTableHeader h = table.getTableHeader();
h.paint(g);
.. производит ..
Я буду дорабатывать его.
Обновление 2
kleopatra (стратегия 1) и camickr (стратегия 2) предоставили ответы каждому, оба из которых работают, и ни один из которых не требует добавления JTable
к фиктивному компоненту (который является огромным хаком IMO).
В то время как стратегия 2 обрезает (или расширяет) до «просто стола», 1-я стратегия захватит панель, содержащую таблицу.Это становится проблематичным, если таблица содержит много записей с изображением усеченной таблицы с полосой прокрутки.
В то время как стратегия 1 может быть доработана, Iочень нравится аккуратная простота стратегии 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/questions/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/questions/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.Используя метод Клеопатры - около десятка строк (без комментариев и пробелов) чистого J2SE.
Хотя ScreenImage - это класс, который я буду использовать и рекомендовать в будущем, другой подход, использующий ядро J2SE, - это то, что я, вероятно, использовал бы для этого точного обстоятельства.
Так что, хотя «галочка» будетостаться с camickr, щедрость собирается Клеопатра.