Как добавить изображение к пользовательской кнопке строки JTable

Как добавить изображение к пользовательской кнопке строки JTable, у меня есть JTable с JButton в первом столбце, и я хочу поместить изображение, но это отображается только при нажатии на него.

введите здесь описание изображения

Вот мое изображение

введите здесь описание изображения

А вот JButtonRenderer и JButtonEditor для размещения JButton в строке JTable.

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 );
        }
    }
}

person joepa37    schedule 26.11.2014    source источник
comment
Почему бы просто не установить значение значка средства визуализации/редактора? Значение которого должно быть получено из значения, установленного для столбца модели столбца, которое может быть строкой или другим описательным значением, что позволит визуализаторам и редакторам принимать решение о том, какую иконку загружать.   -  person MadProgrammer    schedule 26.11.2014
comment
Как я могу это сделать? Не могли бы вы привести пример?   -  person joepa37    schedule 26.11.2014
comment
Вызовите setIcon в рендерере/редакторе, но применяемое значение будет зависеть от ваших данных, которых у нас нет.   -  person MadProgrammer    schedule 27.11.2014


Ответы (1)


Это происходит потому, что вы не устанавливаете значок в ButtonRenderer, а только в ButtonEditor.

1) Вы можете установить значок для вашего рендерера JButton, как это реализовано в ButtonEditor

2) Вы можете сохранить Icon в модели и динамически установить JButton в Renderer/Editor, как показано ниже:

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;
        }

    }

}

введите здесь описание изображения

person alex2410    schedule 27.11.2014