Search code examples
javaswingjtablejbuttontablecellrenderer

buttons not getting displayed in Jtable when values are fetched from database


So basically the requirement is to fetch results from database based on the search query. Results are displayed in JTable. The results should have 5 columns. The 4 columns contain values fetched from database. The 5th column is supposed to have buttons . When the button is clicked a popup should appear. Now the search functionality is working fine. I'm getting an error when I need to display a buttons in 5th column. I googled and found out that it can be done by TablCellRenderer. I've also incorporated the code for the same in my code referring this link Now, I get the error as

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at r_search_2$JTableButtonRenderer.getTableCellRendererComponent(r_search_2.java:193)

which lies in this block:-

             else
            {
                button.setForeground(table.getForeground());
                button.setBackground(UIManager.getColor("Button.background"));
            }

If I remove this block from my code the search query runs fine but buttons are not displayed in the 5th column. So where lies the error and how should I correct that ? Thanks !

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.sql.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;


public class r_search_2 extends JFrame implements ActionListener
{

    JFrame frame1;
    JLabel l0, l1, l2;
    JComboBox c1;
    JButton b1;
    Connection con;
    ResultSet rs, rs1;
    Statement st, st1;
    PreparedStatement pst;
    String ids;
    static JTable table  = new JTable(new JTableModel());
   // static JTable table  = new JTable();
    String[] columnNames = {"SECTION NAME", "REPORT NAME", "CONTACT", "LINK","METRICS"};
    String from;
    Vector v = new Vector();
    JMenuBar menu = new JMenuBar();
    JPanel mainPanel = new JPanel(new BorderLayout());
    JPanel topPanel = new JPanel(new FlowLayout(SwingConstants.LEADING, 60,25));
    JScrollPane scroll = new JScrollPane(table);

    r_search_2() 
    {

        l1 = new JLabel("Search");
        b1 = new JButton("submit");
        l1.setBounds(75, 110, 75, 20);
        b1.setBounds(150, 150, 150, 20);
        b1.addActionListener(this);

        topPanel.add(l1,BorderLayout.LINE_START);

        try 
        {

            File dbFile = new File("executive_db.accdb");
                String path = dbFile.getAbsolutePath();
                con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ= " + path);
                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            st = con.createStatement();
            rs = st.executeQuery("select index_name from Index1");
           while (rs.next())
           {
                ids = rs.getString(1);
                v.add(ids);

            }
            c1 = new JComboBox(v);
            c1.setEditable(true);c1.setSelectedItem("");
            c1.setBounds(150, 110, 150, 20);
            topPanel.add(c1,BorderLayout.CENTER);
            topPanel.add(b1,BorderLayout.LINE_END);
            mainPanel.add(topPanel, BorderLayout.PAGE_START);

            st.close();
            rs.close();
        } 
        catch (Exception e)
        {
        }
       // setVisible(true);
    }

    public void actionPerformed(ActionEvent ae) 
    {
        if (ae.getSource() == b1)
        {
            showTableData();
        }
     }

    public void showTableData()
    {

        DefaultTableModel model = new DefaultTableModel();
        model.setColumnIdentifiers(columnNames);

        table.setModel(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        table.setFillsViewportHeight(true);

        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        from = (String) c1.getSelectedItem();


        TableCellRenderer buttonRenderer = new JTableButtonRenderer();
        table.getColumn("METRICS").setCellRenderer(buttonRenderer);
        //System.out.println(table.getColumn("METRICS"));
        //table.getColumn("Button2").setCellRenderer(buttonRenderer);
        table.addMouseListener(new JTableButtonMouseListener(table));

        String section_name = "";
        String report_name = "";
        String contact_name = "";
        String link = "";


        try
        {

        pst = con.prepareStatement("select distinct Section.Section_Name,Report.Report_Name,Report.Link,Contact.Contact_Name "
                                        + "FROM (( Section INNER JOIN Report ON Report.Section_ID=Section.Section_ID ) INNER JOIN Contact ON Contact.Contact_ID=Report.Contact_ID )  LEFT JOIN Metrics ON Metrics.Report_ID=Report.Report_ID  "
                                                                + " WHERE Section.Section_Name LIKE '%"+from+"%' OR Report.Report_Name LIKE '%"+from+"%' OR Metrics.Metric_Name LIKE '%"+from+"%' OR Contact.Contact_Name LIKE '%"+from+"%' ");
            ResultSet rs = pst.executeQuery();
            int i = 0;
            while (rs.next()) {
                section_name = rs.getString("Section_Name");
                report_name = rs.getString("Report_Name");
                contact_name = rs.getString("Contact_Name");
                link = rs.getString("Link");
               // String m="apple";

                model.addRow(new Object[]{section_name, report_name, contact_name, link});

                i++;
            }

            if (i < 1)
            {
                JOptionPane.showMessageDialog(null, "No Record Found", "Error", JOptionPane.ERROR_MESSAGE);
            }
            if (i == 1)
            {
                System.out.println(i + " Record Found");
            } else {
                System.out.println(i + " Records Found");
            }
        } 
        catch (Exception ex) 
        {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        mainPanel.add(scroll);

        mainPanel.revalidate();
        mainPanel.repaint();

    }
    private static class JTableButtonRenderer implements TableCellRenderer
    {       
        @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            JButton button = (JButton)value;
            if (isSelected) {
                button.setForeground(table.getSelectionForeground());
                button.setBackground(table.getSelectionBackground());
            } 
            else
            {
                button.setForeground(table.getForeground());
                button.setBackground(UIManager.getColor("Button.background"));
            }
            return button;  
        }
    }

    private static class JTableButtonMouseListener extends MouseAdapter
    {
        private final JTable table;

        public JTableButtonMouseListener(JTable table)
        {
            this.table = table;
        }

        public void mouseClicked(MouseEvent e)
        {
            int column = table.getColumnModel().getColumnIndexAtX(e.getX());
            int row    = e.getY()/table.getRowHeight(); 

            if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0)
            {
                Object value = table.getValueAt(row, column);
                if (value instanceof JButton) 
                {
                    ((JButton)value).doClick();
                }
            }
        }
    }

    public static class JTableModel extends AbstractTableModel 
    {

        private static final long serialVersionUID = 1L;
        //private static final String[] COLUMN_NAMES = new String[] {"Id", "Stuff", "METRICS"};
          String[] columnNames = {"SECTION NAME", "REPORT NAME", "CONTACT", "LINK","METRICS"};
        private static final Class<?>[] COLUMN_TYPES = new Class<?>[] {String.class, String.class,String.class, String.class,  JButton.class};

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

        @Override public int getRowCount()
        {
            return 4;
        }

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

        @Override public Class<?> getColumnClass(int columnIndex)
        {
            return COLUMN_TYPES[columnIndex];
        }

        @Override public Object getValueAt(final int rowIndex, final int columnIndex)
        {
            switch (columnIndex) {
                case 0: //return rowIndex;
                case 1: //return "Text for "+rowIndex;
                case 2: // fall through
                case 3: final JButton button = new JButton(columnNames[columnIndex]);
            //  button.setPreferredSize(new Dimension(100, 100));
                button.setSize(new Dimension(10,10));
                        button.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent arg0) {
                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(button), 
                                        "Button clicked for row "+rowIndex);
                            }
                        });
                        return button;
                default: return "";
            }
        }   
    }


    public static void main(String args[])
    {


                r_search_2 s=new r_search_2();
                //new r_search_2();
                JFrame fr=new JFrame("Search Executive Reports");
                //fr.add(s.getUI());
                fr.add(s.mainPanel);
                fr.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                fr.setLocationByPlatform(true);
                fr.setSize(1000, 400);
                //fr.pack();
                fr.setVisible(true);

      //  new r_search_2();
    }
}

Solution

  • There is something is wrong with below code in JTableButtonRenderer

    JButton button = (JButton)value;

    Most probably "value" is null here. For testing create button as JButton button = new JButton("Button");

    Let me know if that works.