Java 在自定义JTable中动态显示图像
我正在显示自定义类对象,如JTable中的个人数据。 因此,我的JTable有一个自定义表模型,它为每一列提供相同的对象。因此,在我的自定义单元渲染器中,我希望在特定列中显示的数据由类对象传递。 在这个表中,还有一列用于每个对象的图像,它是从ApacheTomcat数据库获取的。 到目前为止,图片的显示效果非常好,但是如果显示的图片数量较大,我会遇到很多问题。在创建JTable之前加载图像需要花费太多时间。所以我创建了一个特殊的IamgeLoader,它保存了所有的图像,通过将我的对象传递给这个加载程序,我得到了要在表中显示的图像 现在我的问题是:为了获取所有图片,图像加载程序在一个单独的线程中填充了图像,因此我使用了一个SwingWorker,它也可以正常工作。所以问题是如何更新JTable中的图像。我想一步一步地“添加”图像。关于如何获得性能良好的解决方案的任何想法。 也许我完全走错了路,会有一个更简单或更好的方法来做到这一点。 谢谢 编辑:为了让我的问题更清楚,我创建了一个简单的例子。这很简单,我知道有很多东西遗漏了。但也许你能给我一些提示和窍门。这只是我想走的路。fillImages方法应在后台运行,如果有大量图片,则在已创建表时仍将加载图片。那么,更新这些图片的正确方法是什么Java 在自定义JTable中动态显示图像,java,image,swing,jtable,renderer,Java,Image,Swing,Jtable,Renderer,我正在显示自定义类对象,如JTable中的个人数据。 因此,我的JTable有一个自定义表模型,它为每一列提供相同的对象。因此,在我的自定义单元渲染器中,我希望在特定列中显示的数据由类对象传递。 在这个表中,还有一列用于每个对象的图像,它是从ApacheTomcat数据库获取的。 到目前为止,图片的显示效果非常好,但是如果显示的图片数量较大,我会遇到很多问题。在创建JTable之前加载图像需要花费太多时间。所以我创建了一个特殊的IamgeLoader,它保存了所有的图像,通过将我的对象传递给这个
public class TablePerson extends JFrame
{
private JPanel contentPane;
private JTable table;
public static ImageLoader loader_ = null;
public static void main( String [ ] args )
{
TablePerson frame = new TablePerson( );
frame.setVisible( true );
}
public TablePerson( )
{
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setBounds( 100, 100, 450, 300 );
contentPane = new JPanel( );
contentPane.setLayout( new BorderLayout( 0, 0 ) );
setContentPane( contentPane );
Person p1 = new Person( 20, "John", null );
Person p2 = new Person( 25, "David", null );
Person p3 = new Person( 50, "James", null );
Vector< Person > personList = new Vector< Person >( );
personList.add( p1 );
personList.add( p2 );
personList.add( p3 );
loader_ = new ImageLoader( personList );
PersonTableModel model = new PersonTableModel( personList );
table = new JTable( model );
table.getColumnModel( ).getColumn( 0 ).setCellRenderer( new mTableRenderer( loader_ ) );
table.getColumnModel( ).getColumn( 1 ).setCellRenderer( new mTableRenderer( loader_ ) );
table.getColumnModel( ).getColumn( 2 ).setCellRenderer( new mTableRenderer( loader_ ) );
contentPane.add( table, BorderLayout.CENTER );
}
public class Person
{
public int age_ = 0;
public String name_ = null;
public ImageIcon picture_;
public Person( int age, String name, ImageIcon picture )
{
age_ = age;
name_ = name;
picture_ = picture;
}
}
public class PersonTableModel extends AbstractTableModel
{
protected Vector persons_ = new Vector( );
public PersonTableModel( Vector< Person > persons )
{
persons_ = persons;
}
@ Override
public int getColumnCount( )
{
return 3;
}
@ Override
public Object getValueAt( int rowIndex, int columnIndex )
{
return persons_.get( rowIndex );
}
@ Override
public int getRowCount( )
{
return persons_.size( );
}
}
static public class mTableRenderer extends JLabel implements TableCellRenderer
{
private ImageLoader loader_ = null;
public mTableRenderer( ImageLoader loader )
{
this.loader_ = loader;
}
@ Override
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column )
{
Person person = ( Person ) value;
JLabel label = null;
if ( column == 0 )
{
label = new JLabel( person.name_ );
}
else if ( column == 1 )
{
label = new JLabel( Integer.toString( person.age_ ) );
}
else if ( column == 2 )
{
label = new JLabel( "" );
label.setIcon( loader_.getImage( row ) );
}
return label;
}
}
public class ImageLoader
{
private List< ImageIcon > images_ = new ArrayList< ImageIcon >( );
public ImageLoader( Vector< Person > data )
{
fillImages( data );
}
private void fillImages( Vector< Person > data )
{
final Vector< Person > dataFinal = data;
SwingWorker worker = new SwingWorker< List< ImageIcon >, Void >( )
{
@ Override
protected List< ImageIcon > doInBackground( ) throws Exception
{
for ( Person person : dataFinal )
{
// Just a example picture, later here different images
images_.add( new ImageIcon( ImageIO.read( new File(
"C:\\Work\\Eclipse Luna\\TestProject\\src\\me\\testproject\\calendar.png" ) ) ) );
}
return images_;
}
};
worker.execute( );
}
private ImageIcon getImage( int index )
{
return images_.get( index );
}
}
}
公共类TablePerson扩展JFrame
{
私有JPanel内容窗格;
专用JTable表;
公共静态图像加载器uz=null;
公共静态void main(字符串[]args)
{
TablePerson框架=新的TablePerson();
frame.setVisible(true);
}
公众人士()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
立根(100100450300);
contentPane=newjpanel();
setLayout(新的BorderLayout(0,0));
setContentPane(contentPane);
人员p1=新人员(20,“John”,空);
人员p2=新人员(25,“David”,空);
人员p3=新人员(50,“詹姆斯”,空);
VectorpersonList=新的Vector();
personList.add(p1);
personList.add(p2);
个人列表。添加(p3);
loader=新图像加载器(personList);
PersonTableModel=新的PersonTableModel(personList);
表=新JTable(型号);
table.getColumnModel().getColumn(0).setCellRenderer(新的mTableRenderer(loader));
table.getColumnModel().getColumn(1).setCellRenderer(新的mTableRenderer(loader));
table.getColumnModel().getColumn(2).setCellRenderer(新的mTableRenderer(loader));
contentPane.add(表,BorderLayout.CENTER);
}
公共阶层人士
{
公共整数=0;
公共字符串名称\=null;
公共图像图标图片;
公众人物(整数、字符串名称、图像图标图片)
{
年龄=年龄;
姓名=姓名;
图片=图片;
}
}
公共类PersonTableModel扩展了AbstractTableModel
{
受保护的病媒人=新病媒();
公共PersonTableModel(向量<人>人)
{
人=人;
}
@凌驾
public int getColumnCount()
{
返回3;
}
@凌驾
公共对象getValueAt(int行索引、int列索引)
{
返回人员获取(rowIndex);
}
@凌驾
public int getRowCount()
{
返回人的大小();
}
}
静态公共类mTableRenderer扩展了JLabel,实现了TableCellRenderer
{
private-ImageLoader=空;
公共mTableRenderer(ImageLoader)
{
this.loader=加载器;
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、布尔值、,
布尔值(焦点、整数行、整数列)
{
人=(人)价值;
JLabel标签=null;
如果(列==0)
{
标签=新的JLabel(person.name u41;;
}
else if(列==1)
{
label=新的JLabel(Integer.toString(person.age));
}
else if(列==2)
{
标签=新的JLabel(“”);
label.setIcon(loader.getImage(行));
}
退货标签;
}
}
公共类图像加载器
{
私有列表images\uu=newarraylist();
公共图像加载器(矢量数据)
{
填充图像(数据);
}
私有图像(矢量数据)
{
最终向量dataFinal=数据;
SwingWorker worker=新SwingWorker,Void>()
{
@凌驾
受保护列表doInBackground()引发异常
{
for(人员:dataFinal)
{
//只是一个示例图片,后面是不同的图片
图像添加(新图像图标)图像IO.read(新文件(
“C:\\Work\\eclipseluna\\TestProject\\src\\me\\TestProject\\calendar.png”);
}
返回图像;
}
};
worker.execute();
}
私有图像图标getImage(整数索引)
{
返回图像获取(i)