juan
juan

Reputation: 463

Unable to add focus listeners or set font in Jtable with Jtextfields

I am trying to display data (combination of english and Non-english languages) using Jtable. Since i also have Non-english data i am trying to set font for each cell(jtextfield). I also want to edit data in after rendering in Jtable but i am unable to implement (ie., code in focusgained() is not being called) focus listener events on jtext fileds.

I have used the following renderer to display data in jtable with each cell as a text field

DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() {

                @Override
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    JTextField tf=new JTextField();
                    if (value != null) {
                        if (value.startsWith("_")) {
            value=value.substring(1);
                            tf.setFont(fntEng);
                        } else if (fnt_Local != null && fnt_Local.canDisplayUpTo(value.toString()) == -1) {
                            tf.setFont(fnt_Local);
                        }
                        setText(value.toString());
                    } else {
                        tf.setFont(fnt_Local);
                        tf.setText((String) value);
                    }
                    tf.setForeground(Color.BLACK);
                    tf.setBackground(Color.WHITE);
                    tf.setText(value.toString());
                    tf.addFocusListener(new FocusListener() {

                        public void focusGained(FocusEvent e) {
                     JTextField tf1=(JTextField)e.getComponent();
                     tf1.setText("Focusgained");
                        }

                        public void focusLost(FocusEvent e) {

                        }
                    });

                    return tf;
                }
            }; 

Upvotes: 0

Views: 325

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 208984

If I'm understanding your question correctly, you just want the same font for when you are editing as well as the font being rederered. And you can't get the editor to work right.

First off...

Don't mix the concept of editors and renderers. Rendering should be left to the renderer, and editing left to the editors. For further reading, see See How to use Tables: Editors and Renderers

As for your case...

Rendering

No need for custom renderer for something as simple as setting font. Just override prepareRenderer. You can use the column value to determine which column should be which font. For instance

JTable table = new JTable(data, cols) {
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
        Component c = super.prepareRenderer(renderer, row, col);
        if (col == IMPACT_COL) {
            c.setFont(IMPACT_FONT);
        } else if (col == ARIAL_COL) {
            c.setFont(ARIAL_BOLD_FONT);
        }
        return c;
    }
};

Editing

Just set the font to a text field, then set a new cell editor for the column you want, so that it matches the same font you chose to render the column with. This way you will see the same font rendered, as well as while editing. Something like:

private static final int IMPACT_COL = 0;
private static final Font IMPACT_FONT = new Font("impact", Font.PLAIN, 20);
...
JTextField impactField = getFontEditorField(IMPACT_FONT);
TableColumn impactColumn = table.getColumnModel().getColumn(IMPACT_COL);
impactColumn.setCellEditor(new DefaultCellEditor(impactField));
...
public JTextField getFontEditorField(Font font) {
    JTextField field = new JTextField();
    field.setFont(font);
    return field;
}

Complete Example

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class ChangeFontInEditorDemo {
    private static final int IMPACT_COL = 0;
    private static final int ARIAL_COL = 1;
    private static final Font IMPACT_FONT = new Font("impact", Font.PLAIN, 20);
    private static final Font ARIAL_BOLD_FONT = new Font("arial", Font.BOLD, 20);

    public ChangeFontInEditorDemo() {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(getTable()));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTable getTable() {
        String[][] data = { { "Data", "Data" }, { "Data", "Data" } };
        String[] cols = { "Col", "Col" };
        JTable table = new JTable(data, cols) {
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
                Component c = super.prepareRenderer(renderer, row, col);
                if (col == IMPACT_COL) {
                    c.setFont(IMPACT_FONT);
                } else if (col == ARIAL_COL) {
                    c.setFont(ARIAL_BOLD_FONT);
                }
                return c;
            }
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(300, 125);
            }
        };
        table.setRowHeight(20);

        JTextField impactField = getFontEditorField(IMPACT_FONT);
        TableColumn impactColumn = table.getColumnModel().getColumn(IMPACT_COL);
        impactColumn.setCellEditor(new DefaultCellEditor(impactField));

        JTextField arialBoldField = getFontEditorField(ARIAL_BOLD_FONT);
        TableColumn arialColumn = table.getColumnModel().getColumn(ARIAL_COL);
        arialColumn.setCellEditor(new DefaultCellEditor(arialBoldField));

        return table;
    }

    public JTextField getFontEditorField(Font font) {
        JTextField field = new JTextField();
        field.setFont(font);
        return field;
    }

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

Upvotes: 3

Related Questions