我正在显示自定义类对象,例如JTable中的个人数据。 因此,我的JTable有一个自定义表模型,它为每列提供相同的对象。因此,在我的自定义单元格渲染器中,我想要在特定列中显示的数据由类对象传递。 在此表中,还是每个对象的图像列,该列从apache tomcat数据库中获取。 到目前为止,图片的显示效果非常好,但是我得到的图像数量更多。在创建JTable之前加载图像需要花费太多时间。所以我创建了一个特殊的IamgeLoader来保存所有的图像,并将我的对象传递给这个加载器,我得到的图像显示在表中。
现在我的问题:要获取所有图片,图像加载器在一个单独的线程中填充图像,因此我使用SwingWorker也可以正常工作。所以问题是如何更新JTable中的图像。我希望图像被“添加”一步一步。任何想法如何获得具有良好性能的解决方案。 也许我完全走错了方向,并且会有更简单或更好的方法来做到这一点。 感谢
编辑:为了让我的问题更清楚,我创建了一个简单的例子。这很简单,我知道有很多东西缺失。但也许你可以给我一些提示和技巧。这只显示了我想要的方式。 fillImages方法应该在后台运行,并且在创建表格时,仍然会有大量图片加载图片。那么,正确的方式是什么更新这些图片?
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 );
}
}
}