Итак, у вас, кажется, есть ряд проблем с компаундированием. Давайте начнем здесь, где вы загружаете данные из базы данных...
while(rs.next())
{
row = new Vector(columnsNumber);
for(int i=1; i<=columnsNumber; i++)
{
// adding the rows in "row vector"
InputStream binaryStream = rs.getBinaryStream(i);
row.add(rs.getString(i));
row.add(rs.getBinaryStream(8));
}
// adding the rows in the database
rowdata.add(row);
}
Таким образом, для каждой строки в ResultSet
вы просматриваете столбцы, НО для каждого столбца вы добавляете значение String
И BLOB-объект из последнего столбца, поэтому BLOB-объект будет добавлен 6 раз (на основе вашего снимка экрана). Это, очевидно, не то, что вам нужно, а также причина, по которой вы получаете java.io.ByteArrayInputStream@1cb63183
в каждом втором столбце.
Вместо этого вы хотите перебрать столбцы 1
-columnsNumbers - 1
, потому что нам не нужен последний столбец, и добавить изображение в последний столбец, может быть, что-то вроде...
while(rs.next())
{
row = new Vector(columnsNumber);
for(int i=1; i < columnsNumber; i++)
{
// adding the rows in "row vector"
InputStream binaryStream = rs.getBinaryStream(i);
row.add(rs.getString(i));
}
row.add(rs.getBinaryStream(8));
// adding the rows in the database
rowdata.add(row);
}
Следующая проблема...
Он по-прежнему печатает java.io.ByteArrayInputStream@1cb63183
в последнем столбце!?
Это просто потому, что все, что вы добавили в row
Vector
, было двоичным потоком, представляющим двоичные данные в базе данных, JTable
не имеет средств для его отображения. Вы должны начать с изучения Концепции: редакторы и визуализаторы и Использование пользовательских средств визуализации для получения дополнительной информации. о том, как можно настроить отрисовку этих компонентов
Во-первых, нам нужно преобразовать двоичные данные в формат изображения, который мы можем использовать.
row.add(ImageIO.read(rs.getBinaryStream(8)));
И используйте что-то похожее на то, что описано в Визуализация BufferedImage в ячейке JTable
or
row.add(new ImageIcon(ImageIO.read(rs.getBinaryStream(8))));
который должен позволить "по умолчанию" TableCellRenderer
отображать его
Запускаемый пример...
Предупреждение. Этот пример немного длинный, потому что мне нужно было создать базу данных и заполнить ее. Он использует автономный ядро базы данных H2 для простоты, но должен быть переведен в большинство других баз данных. . В примере также используется тип столбца blob
, это сделано намеренно, так как это повышает производительность ядра базы данных.
Проблема с отображением изображений в JTable
при использовании DefaultTableModel
заключается в том, что DefaultTableModel
возвращает Object.class
из метода TableModel#getColumnClass
.
Даже в документации DefaultTableModel
отмечается этого...
Внимание! DefaultTableModel
возвращает класс столбца Object
. Когда DefaultTableModel
используется с TableRowSorter
, это приводит к широкому использованию toString
, что для типов данных, отличных от String
, является дорогостоящим. Если вы используете DefaultTableModel
с TableRowSorter
, вам настоятельно рекомендуется переопределить getColumnClass
, чтобы вернуть соответствующий тип.
Я преодолел это, настроив DefaultTableModel
, который я вернул из TestPane#makeTableModel
...
DefaultTableModel model = new DefaultTableModel(new String[]{"Name", "Image"}, 0) {
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 1 ? Icon.class : super.getColumnClass(columnIndex);
}
};
Это позволило JTable
использовать правильный TableCellRenderer
а>
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class Main {
public static void main(String[] args) {
try {
Class.forName("org.h2.Driver");
makeDatabase();
populateDatabase();
new Main();
} catch (ClassNotFoundException | SQLException | IOException exp) {
exp.printStackTrace();
}
}
protected static Connection makeConnection() throws SQLException {
String path = "jdbc:h2:./TestDatabase";
return DriverManager.getConnection(path, "sa", "");
}
protected static void makeDatabase() throws SQLException {
String cmd = "create table if not exists fruits ("
+ "key BIGINT IDENTITY, "
+ "name varchar(128), "
+ "image longblob)";
try (Connection con = makeConnection()) {
try (PreparedStatement stmt = con.prepareStatement(cmd)) {
System.out.println("> Make fruits table");
stmt.executeUpdate();
}
}
}
protected static void populateDatabase() throws SQLException, IOException {
removeAlFruits();
insert("Apple", ImageIO.read(new File("Apple.png")));
insert("Banana", ImageIO.read(new File("Banana.png")));
insert("Cherries", ImageIO.read(new File("Cherries.png")));
insert("Grapes", ImageIO.read(new File("Grapes.png")));
insert("Orange", ImageIO.read(new File("Orange.png")));
insert("Pear", ImageIO.read(new File("Pear.png")));
insert("Pine Apple", ImageIO.read(new File("PineApple.png")));
insert("Strewberry", ImageIO.read(new File("Strewberry.png")));
insert("Water Melon", ImageIO.read(new File("WaterMelon.png")));
}
protected static void insert(String name, BufferedImage image) throws SQLException, IOException {
String cmd = "insert into fruits (name, image) values (?, ?)";
try (Connection con = makeConnection()) {
try (PreparedStatement stmt = con.prepareStatement(cmd)) {
try (InputStream is = convertImageToInputStream(image)) {
System.out.println("> Insert " + name);
stmt.setString(1, name);
stmt.setBinaryStream(2, is);
int rows = stmt.executeUpdate();
System.out.println("> " + rows + " rows updated");
}
}
}
}
protected static InputStream convertImageToInputStream(BufferedImage image) throws IOException {
ByteArrayOutputStream baos = null;
ByteArrayInputStream bais = null;
try {
baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
baos.close();
bais = new ByteArrayInputStream(baos.toByteArray());
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException ex) {
}
}
}
return bais;
}
protected static void removeAlFruits() throws SQLException {
String cmd = "delete from fruits";
try (Connection con = makeConnection()) {
try (PreparedStatement stmt = con.prepareStatement(cmd)) {
System.out.println("> Remove all fruits");
int rows = stmt.executeUpdate();
System.out.println("> " + rows + " rows updated");
}
}
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (SQLException | IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws SQLException, IOException {
setLayout(new BorderLayout());
DefaultTableModel model = makeTableModel();
JTable table = new JTable(model);
table.setRowHeight(100);
add(new JScrollPane(table));
}
protected DefaultTableModel makeTableModel() throws SQLException, IOException {
DefaultTableModel model = new DefaultTableModel(new String[]{"Name", "Image"}, 0) {
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 1 ? Icon.class : super.getColumnClass(columnIndex);
}
};
String cmd = "select name, image from fruits";
try (Connection con = makeConnection()) {
try (PreparedStatement stmt = con.prepareStatement(cmd)) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
String name = rs.getString(1);
Blob blob = rs.getBlob(2);
ImageIcon icon = null;
try (InputStream is = blob.getBinaryStream()) {
BufferedImage img = ImageIO.read(is);
icon = new ImageIcon(img);
}
model.addRow(new Object[]{name, icon});
}
}
}
}
return model;
}
}
}
Альтернативой является использование пользовательского TableCellRender
, как показано в разделе Визуализация BufferedImage в ячейке JTable.
person
MadProgrammer
schedule
28.01.2016
image
иtext
, а неdata
, что исключает возможность узнать, какой тип данных он представляет на самом деле. - person MadProgrammer   schedule 28.01.2016ByteArrayInputStream
, который является двоичным представлением большого двоичного объекта (или изображения) из базы данных, вам нужно использоватьImageIO
, чтобы прочитатьByteArrayInputStream
и преобразовать его обратно вBufferedImage
, который затем можно отобразить в вашемJTable
!!! - person MadProgrammer   schedule 29.01.2016Blob blob = rs.getBlob(8);
иBufferedImage img = ImageIO.read(blob.getBinaryStream());
— это то, что вам нужно, чтобы прочитать последний столбец и преобразовать его в изображение. Но, учитываяByteArrayStream
, вы также можете использовать его, но это немного сложнее - person MadProgrammer   schedule 29.01.2016JTable
, которое станет дубликатом Rendering BufferedImage в JTable. ячейка - person MadProgrammer   schedule 29.01.2016ava.io.ByteArrayInputStream@1034d0b4
, и когда я изменил row.add на BufferedImage, я получил это:BufferedImage@3b7f825e: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@232b985c transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 1000 height = 750 #numDataElements 3 dataOff[0] = 2"
- person rullzing   schedule 29.01.2016TableCellRenderer
использует метод объектовtoString
для его отображения. Вы использовалиImageIO.read
для чтения двоичного потока из базы данных? Вы добавили полученное изображение вrow
Vector
? Вы использовали пользовательскийTableCellRenderer
для отображенияBufferedImage
? - person MadProgrammer   schedule 29.01.2016Exception
, то, что у вас есть, это ошибка - person MadProgrammer   schedule 29.01.2016