animation in JTable

2019-08-30 10:49发布

问题:

I am trying to put gif image(animated) to a JTable cell, but it's not being displayed. As I have read, JTable component is static and it's required to rewrite rendering.

The point is that I have a thread which calculates some data and pastes it to a table cell, while calculating I want to display some rotating wheel. Moreover, I add rows to the table from another separate thread. So, one thread adds a row with some data and another thread calculates data for a cell in the row.

Is it possible to add an animation icon into the same cell in each added row? Has anyone ideas how to do it?

Upd: Now I can create a row with animated gif, but can't add such rows to a table from a thread

public class AnimatedIconTableExample extends JFrame {

    private static final long serialVersionUID = -1038271613549995183L;

    public AnimatedIconTableExample() {
        super("AnimatedIconTable Example");

        final Object[][] data = new Object[][] {
                { "", "", new ImageIcon("src/loading.gif"),
                        "text" } };
        final Object[] column = new Object[] { "First", "Second", "Third", "Fourth" };

        DefaultTableModel model = new DefaultTableModel() {

            private static final long serialVersionUID = 31150076182704312L;

            public int getColumnCount() {
                return column.length;
            }

            public int getRowCount() {
                return data.length;
            }

            public String getColumnName(int col) {
                return (String) column[col];
            }

            public Object getValueAt(int row, int col) {
                return data[row][col];
            }

            public Class<?> getColumnClass(int col) {
                return ImageIcon.class;
            }
        };

        JTable table = new JTable(model);
        setImageObserver(table);
        JScrollPane pane = new JScrollPane(table);
        getContentPane().add(pane);

        for (int i = 0; i < 5; i++) {
            new TableUpdater(model, data).start();
        }

    }

    private void setImageObserver(JTable table) {
        TableModel model = table.getModel();
        int colCount = model.getColumnCount();
        int rowCount = model.getRowCount();
        for (int col = 0; col < colCount; col++) {
            if (ImageIcon.class == model.getColumnClass(col)) {
                for (int row = 0; row < rowCount; row++) {
                    Object obj = model.getValueAt(row, col);
                    ImageIcon icon = null;
                    if (obj instanceof ImageIcon)
                        icon = (ImageIcon) model.getValueAt(row, col);
                    if (icon != null) {
                        icon.setImageObserver(new CellImageObserver(table, row,
                                col));
                    }
                }
            }
        }
    }

    class CellImageObserver implements ImageObserver {
        JTable table;
        int row;
        int col;

        CellImageObserver(JTable table, int row, int col) {
            this.table = table;
            this.row = row;
            this.col = col;
        }

        public boolean imageUpdate(Image img, int flags, int x, int y, int w,
                int h) {
            if ((flags & (FRAMEBITS | ALLBITS)) != 0) {
                Rectangle rect = table.getCellRect(row, col, false);
                table.repaint(rect);
            }
            return (flags & (ALLBITS | ABORT)) == 0;
        }
    }

    public static void main(String[] args) {
        AnimatedIconTableExample frame = new AnimatedIconTableExample();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setSize(300, 150);
        frame.setVisible(true);
    }
}

public class TableUpdater extends Thread {

    private DefaultTableModel model;
    private Object[][] data;

    public TableUpdater(DefaultTableModel model, Object[][] data) {
        this.model = model;
        this.data = data;
    }

    public void run() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        model.addRow(data);
    }
}

回答1:

Is it possible to add an animation icon into the same cell in each added row?,

  • have look at Renderer,

  • but for animated Gif will be better, confortable and easier to use arrays of JLabels, layed by GridLayout



回答2:

Read about Editors and Renderers.

JTable allows you to put Images and Icons.

You need to override your getColumnClass method.



回答3:

The link above to "this example" from MadProgrammer is broken. However, I've found it here, and it helped: AnimatedIconTableExample.java

/* (swing1.1.1beta2) */
//package jp.gr.java_conf.tame.swing.examples;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.table.*;


/**
 * @version 1.0 06/19/99
 */
public class AnimatedIconTableExample extends JFrame {

  public AnimatedIconTableExample(){
    super( "AnimatedIconTable Example" );

    final Object[][] data =  new Object[][]{
      {new ImageIcon("images/3-40.gif"),new ImageIcon("images/3-119.gif")},
      {new ImageIcon("images/3-41.gif"),new ImageIcon("images/3-6.gif")}};
    final Object[] column = new Object[]{"Boy and Girl","Dog and Cat"};

    AbstractTableModel model = new AbstractTableModel() {
      public int getColumnCount() { return column.length; }
      public int getRowCount()    { return data.length; }
      public String getColumnName(int col) {
       return (String)column[col]; 
      }
      public Object getValueAt(int row, int col) { 
        return data[row][col]; 
      }
      public Class getColumnClass(int col) {
        return ImageIcon.class;
      }
    };

    JTable table = new JTable( model );
    table.setRowHeight(50);
    setImageObserver(table);
    JScrollPane pane = new JScrollPane(table);
    getContentPane().add(pane);
  }

  private void setImageObserver(JTable table) {
    TableModel model = table.getModel();
    int colCount = model.getColumnCount();
    int rowCount = model.getRowCount();
    for (int col=0;col<colCount;col++) {
      if (ImageIcon.class == model.getColumnClass(col)) {
        for (int row=0;row<rowCount;row++) {
          ImageIcon icon = (ImageIcon)model.getValueAt(row,col);
          if (icon != null) {
            icon.setImageObserver(new CellImageObserver(table, row, col));
          }
        }
      }
    }
  }

  class CellImageObserver implements ImageObserver {
    JTable table;
    int row;
    int col;

    CellImageObserver(JTable table,int row, int col) {
      this.table = table;
      this.row   = row;
      this.col   = col;
    }

    public boolean imageUpdate(Image img, int flags,
                   int x, int y, int w, int h) {
      if ((flags & (FRAMEBITS|ALLBITS)) != 0) {
        Rectangle rect = table.getCellRect(row,col,false);
        table.repaint(rect);
      }
      return (flags & (ALLBITS|ABORT)) == 0;
    }
  }

  public static void main(String[] args) {
    AnimatedIconTableExample frame = new AnimatedIconTableExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize( 300, 150 );
    frame.setVisible(true);
  }
}