У меня есть проект с JTable. Внутри этого JTable у меня есть строки, которые я использовал для отображения содержимого, поступающего из моей базы данных MySQL. Теперь у меня есть проблема, когда последний столбец должен быть изображением (или текстом), при нажатии которого открывается диалоговое окно, отображающее изображение, связанное с этой строкой базы данных. Я использую DefaultTableModel для стиля и векторы, которые добавляют строку в JTable. Затем я понял, что не могу иметь строки и изображения внутри вектора — все они должны быть одного типа.
Поэтому я переключился на JLabel, думая, что могу использовать текст для отображения, а затем в изображении/тексте я мог бы использовать всплывающую подсказку, чтобы получить точное местоположение файла изображения. Но теперь мои данные JTable просто отображают: javax.swing.JLabel вместо фактического текста. Я добавляю строку в свой JTable следующим образом:
for (int j = 0; j < receiptData.size(); j++) {
receiptTableModel.addRow(receiptData.get(j));
}
receiptTableModel это DefaultTableModel; receiptData есть Vector<Vector<JLabel>>.
Есть ли что-то, что я упускаю из виду, чтобы достичь этого?




Вы можете иметь изображения или любые другие объекты в модели таблицы. Использование Vector из JLabels в качестве строки в табличной модели — плохая идея. В модели мы должны хранить «данные»; не компоненты пользовательского интерфейса.
Попробуйте нижеприведенный пример. Он использует пользовательский модуль визуализации ячеек и пользовательский редактор ячеек для столбца «изображение».
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.table.*;
import java.awt.Component;
import java.awt.event.*;
import java.util.*;
public class ImageInTable {
public static void main(String[] args) {
ImageIcon icon1 = new ImageIcon("blue_star.png");
ImageIcon icon2 = new ImageIcon("red_star.png");
DefaultTableModel receiptTableModel = new DefaultTableModel(
new Object[][] {},
new Object[] {"Number", "Description", "Icon"});
Vector<Object> row1 = new Vector<>();
row1.add("1234");
row1.add("Receipt 1");
row1.add(icon1);
receiptTableModel.addRow(row1);
Vector<Object> row2 = new Vector<>();
row2.add("5678");
row2.add("Receipt 2");
row2.add(icon2);
receiptTableModel.addRow(row2);
JTable table = new JTable(receiptTableModel);
table.setRowHeight(34); // Set row height according to the height of the image
table.getColumn("Icon").setCellRenderer(new IconRendererAndEditor(table));
table.getColumn("Icon").setCellEditor(new IconRendererAndEditor(table));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(table));
f.setBounds(300, 200, 400, 300);
f.setVisible(true);
}
}
class IconRendererAndEditor extends JLabel implements TableCellRenderer, TableCellEditor {
private Icon icon;
IconRendererAndEditor(JTable table) {
addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(table, icon);
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.icon = (Icon) value;
setIcon(this.icon);
return this;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
this.icon = (Icon) value;
setIcon(this.icon);
return this;
}
@Override
public Object getCellEditorValue() {
return this.icon;
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
return false;
}
@Override
public boolean stopCellEditing() {
return true;
}
@Override
public void cancelCellEditing() {
}
@Override
public void addCellEditorListener(CellEditorListener l) {
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
}
}
Когда вы запустите его, это будет выглядеть так: