Saleh Feek
Saleh Feek

Reputation: 2076

JTable: How to update cell using custom editor by pop-up input dialog box?

I am learning from this oracle tutorial that uses TableDialogEditDemo.java example class

I wrote a custom cell Renderer and Editor for JTable.

I register them to this Oracle TableDialogEditDemo.java class

        ...
        ...
        //Set up renderer and editor for the Favorite Color column.
        table.setDefaultRenderer(Color.class,
                                 new ColorRenderer(true));
        table.setDefaultEditor(Color.class,
                               new ColorEditor());

        TableColumn c = table.getColumnModel().getColumn(2);
        c.setCellRenderer(new CellStringRenderer()); //My custom Renderer
        c.setCellEditor(new CellStringEditor()); // My custom Editor

        //Add the scroll pane to this panel.
        add(scrollPane);
        ...
        ...

(Updated description) When I click on a cell an input dialogue box pops up and that is OK, and when I type a text and click "OK" the cell in the JTable is updated, but text is not displayed/rendered correctly, I have to click on any other cell to make the text content displayed correctly in the cell.

What is the wrong with my code?.

My Renderer

import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class CellStringRenderer extends JLabel implements TableCellRenderer
{

    public CellStringRenderer()
    {
        this.setOpaque(true);
    }


    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
       String stringValue = (String) value;
       this.setText(stringValue);
       return this;
    }

}

My Editor (Updated)

import java.awt.Component;
import javax.swing.*;
import javax.swing.table.TableCellEditor;


public class CellStringEditor extends AbstractCellEditor
        implements TableCellEditor
{

    String input;

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
    {
        if (isSelected)
        {
            JOptionPane dialog = new JOptionPane();
            input = dialog.showInputDialog(null, "new value");
            return dialog;   
        }
        return null;
    }

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

Upvotes: 1

Views: 10443

Answers (1)

Saleh Feek
Saleh Feek

Reputation: 2076

I am The author of this question, and I solved it. I will provide the solution so that others can get help from it.

I was trying to write a custom renderer and a custom editor to use with JTable. The renderer simply uses JLabel to display data. It is already the standard component for JTable. The editor is a dialogue box that appears when clicking on the cell that I want to edit.

Here is the solution:

The classes that will remain unchanged are the three classes from Oracle + my custom renderer class

1.TableDialogEditDemo.java.

2.ColorEditor.java

3.ColorRenderer.java

4.CellStringRenderer class provided above in the question body (my class)

The class that will be updated is the custom editor class (I changed its name from "CellStringEditor" to "DialogStringEditor"

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

public class DialogStringEditor extends AbstractCellEditor
        implements TableCellEditor,
        ActionListener
{

    String newInput;
    String oldValue;
    JButton button;
    static final String EDIT = "edit";

    public DialogStringEditor()
    {
        button = new JButton();
        button.setBackground(Color.WHITE);
        button.setActionCommand(EDIT);
        button.addActionListener(this);
        button.setBorderPainted(false);
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if (EDIT.equals(e.getActionCommand()))
        {
            newInput = JOptionPane.showInputDialog("Edit", oldValue);
            if (newInput == null)
            {
                newInput = oldValue;
            }
            fireEditingStopped();
        }
    }

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

    @Override
    public Component getTableCellEditorComponent(JTable table,
            Object value,
            boolean isSelected,
            int row,
            int column)
    {
        newInput = (String) value;
        oldValue = (String) value;
        return button;
    }
}

This will work ok

You can also make a little update for the renderer class "CellStringRenderer" to control how are selction and unselection colors of the cell appear.

update this method:

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        String stringValue = (String) value;
        this.setText(stringValue);

        if (isSelected)
        {
            this.setBackground(table.getSelectionBackground());
            this.setForeground(table.getSelectionForeground());
        } else
        {
            this.setBackground(table.getBackground());
            this.setForeground(table.getForeground());
        }

        return this;
    }
}

Regards.

Upvotes: 7

Related Questions