joepa37
joepa37

Reputation: 23

How to add an image to a custom JTable row button

How to add an image to a custom JTable row button, I have a JTable with a JButton in the first column and I want to put an image but, this only show when I click it.

enter image description here

Here is my image

enter image description here

And here are the JButtonRenderer and JButtonEditor to put a JButton in a JTable row

ButtonRenderer.java

import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;

/**
 *
 * @author joepa37
 */
public class ButtonRenderer extends JButton implements TableCellRenderer {

  public ButtonRenderer() {
    setOpaque(true);
  }

  @Override
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(UIManager.getColor("Button.background"));
    }
    setText((value == null) ? "" : value.toString());
    return this;
  }
}

ButtonEditor.java

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTable;

/**
 *
 * @author joepa37
 */

public class ButtonEditor extends DefaultCellEditor {
  protected JButton button;

  private String label;

  private boolean isPushed;

  public ButtonEditor(JCheckBox checkBox) {
    super(checkBox);
    button = new JButton(new ImageIcon(ButtonEditor.class.getResource("image.png")));
    button.setOpaque(true);
    button.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        fireEditingStopped();
      }
    });
  }

  @Override
  public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    if (isSelected) {
      button.setForeground(table.getSelectionForeground());
      button.setBackground(table.getSelectionBackground());
    } else {
      button.setForeground(table.getForeground());
      button.setBackground(table.getBackground());
    }
    label = (value == null) ? "" : value.toString();
    button.setText(label);
    isPushed = true;
    return button;
  }

  @Override
  public Object getCellEditorValue() {
    if (isPushed) {
      // 
      // 
      JOptionPane.showMessageDialog(button, label + ": Ouch!");
      // System.out.println(label + ": Ouch!");
    }
    isPushed = false;
    return new String(label);
  }

  @Override
  public boolean stopCellEditing() {
    isPushed = false;
    return super.stopCellEditing();
  }

  @Override
  protected void fireEditingStopped() {
    super.fireEditingStopped();
  }
}

imageRowButtonTable.java

import java.awt.Component;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;

/**
 *
 * @author joepa37
 */
public class imageRowButtonTable extends JFrame{
    public imageRowButtonTable(){
        super();

        this.add(getPreview());

        setSize(500,500);
        setVisible(true);
    }

    public static void main(String args[]){
        new imageRowButtonTable();
    }

    public Component getPreview ()
    {
        // Table
        JTable table = new JTable ( new ExampleTableModel () );
        JScrollPane scrollPane = new JScrollPane ( table );

        // Custom column
        TableColumn buttonColumn = table.getColumnModel ().getColumn ( 0 );

        // Custom renderer
        buttonColumn.setCellRenderer(new ButtonRenderer());

        // Custom editor
        buttonColumn.setCellEditor(new ButtonEditor(new JCheckBox()));

        return scrollPane;
    }

    public class ExampleTableModel extends AbstractTableModel
    {
        private String[] columnNames = { "", "Option"};
        private Object[][] data = { { "", "op1"}, 
                                    { "", "op2"}, 
                                    { "", "op3"},
                                };

        public final Object[] longValues = { "", "Option"};

        @Override
        public int getColumnCount ()
        {
            return columnNames.length;
        }

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

        @Override
        public String getColumnName ( int col )
        {
            return columnNames[ col ];
        }

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

        @Override
        public Class getColumnClass ( int c )
        {
            return longValues[ c ].getClass ();
        }

        @Override
        public boolean isCellEditable ( int row, int col )
        {
            return true;
        }

        @Override
        public void setValueAt ( Object value, int row, int col )
        {
            data[ row ][ col ] = value;
            fireTableCellUpdated ( row, col );
        }
    }
}

Upvotes: 1

Views: 2787

Answers (1)

alex2410
alex2410

Reputation: 10994

That happens because you don't set icon in ButtonRenderer, just in ButtonEditor.

1) You can set icon to your renderer JButton as implemented in ButtonEditor

2) You can store Icon in model and set it dinamically to JButton in Renderer/Editor like next:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractCellEditor;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class TestFrame extends JFrame {

    public TestFrame() {
        init();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void init() {
        DefaultTableModel model = new DefaultTableModel(0,2);
        JTable t = new JTable(model);
        t.getColumnModel().getColumn(0).setCellRenderer(new ButtonCell());
        t.getColumnModel().getColumn(0).setCellEditor(new ButtonCell());
        ImageIcon icon = new ImageIcon(TestFrame.class.getResource("1.png"));
        model.addRow(new Object[]{icon,"test"});
        model.addRow(new Object[]{null,"test2"});
        model.addRow(new Object[]{icon,"test3"});

        add(new JScrollPane(t));
    }


    public static void main(String... s){
        new TestFrame();
    }

    private class ButtonCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer{

        private JButton btn;

        ButtonCell(){
            btn = new JButton();
            btn.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("clicked");
                }
            });
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            if(value instanceof Icon){
                btn.setIcon((Icon) value);
            } else {
                btn.setIcon(null);
            }
            return btn;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            if(value instanceof Icon){
                btn.setIcon((Icon) value);
            } else {
                btn.setIcon(null);
            }
            return btn;
        }

    }

}

enter image description here

Upvotes: 3

Related Questions