4

I have a jTable that I have created to display the names of countries and the flag icons in the cells next to the names. How can I display each icon in the same column but different rows using the ImageIcon class, without displaying just a string?

The following is what I have written to display the France flag icon at a certain place in the jTable but it just displays the string

    ImageIcon icon = new ImageIcon("http://www.stoma.fr/assets/images/French_Flag_Small_Icon.jpg");
    jTable.setValueAt(icon, 1, 2);
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
batussi
  • 55
  • 1
  • 6

1 Answers1

5

This is solved easily by simply making sure that the column for the icons returns Icon.class in the table model's getColumnClass(...) method. Fortunately JTables know how to display icons without any extra work if you do this. For example.

A modification of my code from there uses this table model:

  DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0) {
     @Override
     public Class<?> getColumnClass(int column) {
        if (getRowCount() > 0) {
           Object value = getValueAt(0, column);
           if (value != null) {
              return getValueAt(0, column).getClass(); 
           }
        }

        return super.getColumnClass(column);
     }
  };

The whole program:

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class ImageColumnTest2 {
   public static final String IMAGE_SHEET_PATH = "http://speckycdn.sdm.netdna-cdn.com/"
         + "wp-content/uploads/2010/08/flag_icons_04.jpg";
   public static final String[] COUNTRIES = {
      "Denmark", "China", "Chile", "Canada", "Belgium", "Austria",
      "Argentina", "France", "Malaysina", "Lebanon", "Korea", "Japan",
      "Italy", "Ireland", "India", "Hong Kong", "Greece", "Germany"
   };
   public static final int COLS = 6;
   public static final int ROWS = 3;
   private static final String[] COL_NAMES = {"Country", "Flag"};

   private JTable table = new JTable();
   private JScrollPane mainPane = new JScrollPane(table);

   public ImageColumnTest2() throws IOException {
      DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0) {
         @Override
         public Class<?> getColumnClass(int column) {
            if (getRowCount() > 0) {
               Object value = getValueAt(0, column);
               if (value != null) {
                  return getValueAt(0, column).getClass();
               }
            }

            return super.getColumnClass(column);
         }
      };
      URL url = new URL(IMAGE_SHEET_PATH);
      BufferedImage img = ImageIO.read(url);
      int x1 = 15;  // sorry about the magic numbers
      img = img.getSubimage(x1, 0, img.getWidth() - 2 * x1, img.getHeight());

      int y1 = 20 ;  // ditto!
      int w = img.getWidth() / COLS;
      int h = img.getHeight() / ROWS;
      for (int row = 0; row < ROWS; row++) {
         int y = (row * img.getHeight()) / ROWS;
         for (int col = 0; col < COLS; col++) {
            int x = (col * img.getWidth()) / COLS;
            BufferedImage subImg = img.getSubimage(x, y, w, h);

            subImg = subImg.getSubimage(x1, 0, subImg.getWidth() - 2 * x1, subImg.getHeight() - y1);

            ImageIcon icon = new ImageIcon(subImg);
            String country = COUNTRIES[col + row * COLS];
            Object[] rowData = {country, icon};
            model.addRow(rowData);
         }
      }


      table.setModel(model);
      table.setRowHeight(((ImageIcon)model.getValueAt(0, 1)).getIconHeight());
   }

   public JComponent getMainComponent() {
      return mainPane;
   }

   private static void createAndShowGui() {
      ImageColumnTest2 imgColumnTest = null;
      try {
         imgColumnTest = new ImageColumnTest2();
      } catch (MalformedURLException e) {
         e.printStackTrace();
         System.exit(-1);
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

      JFrame frame = new JFrame("ImageColumnTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(imgColumnTest.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Which displays as:

enter image description here

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • thanks for your answer, but I wanted to ask rather than having all the country images in one image path, how can you do it so that you have an individual path for each country? – batussi Jan 04 '15 at 22:53
  • @batussi: that all depends on how the files are set up. But I'm betting that you're clever enough to figure out that small detail, since it is less of a programming exercise and more of a simple logic exercise. Good luck! – Hovercraft Full Of Eels Jan 04 '15 at 22:57