Search code examples
javaswingjtableprogress-bartablecellrenderer

How to display progress column in Java Table


So I am creating a project which has three columns; one is a check box column the second one is string (words form a neo4j database) and the third for progress bars.

All the columns are displayed and work fine but the progress bar column is invisible as it seems. Here is some code:

    //CONSTRUCTOR
        public BiogramTableJSedit2Jan9()
        {   
            //*************************************************
            //* SETTING UP THE FORM                      *                                          
            //*************************************************
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(200,200,800,300);
            setTitle("Netword Data Table");
            getContentPane().setLayout(null);

            //*************************************************


        //********************************************
                //CREATING TABLE BLOCK                       *
                //********************************************

                //ADD SCROLLPANE
                JScrollPane scroll=new JScrollPane();
                scroll.setBounds(70,80,600,200);
                getContentPane().add(scroll);

                //THE TABLE
                final JTable table=new JTable();
                scroll.setViewportView(table);


                //THE MODEL OF THE TABLE
                DefaultTableModel model=new DefaultTableModel()  
                {
                    //****************************************
                    //* SETTING TABLE COLUMNS BLOCK          * 
                    //****************************************
                    public Class<?> getColumnClass(int column)  
                    {
                        switch(column)
                        {
                        case 0:                             // |This is the first column
                            return Boolean.class;           // |First column is set to Boolean as it will contain check boxes
                        case 1:                             // |This is the second column
                            return String.class;            // |Second column set to String as it will contain strings
                        case 2:
                            return JProgressBar.class;      // |This is for the progress bar column (IN PROGRESS - NOT DISPLAYED YET...) 

                        default:
                            return String.class;            // |The table is set to String as default 
                        }
                    }
                };


                //Create and run the query in the table         
                neoQuery= Q1();
                resultVariable = session.run(neoQuery.get());   



                //ASSIGN THE MODEL TO TABLE 
                table.setModel(model);

                model.addColumn("Select");                  // |Column for check boxes
                model.addColumn("Bigrams");                 // |Column for Bigrams

                table.getColumn("Status").setCellRenderer(new ProgressCellRender());

                //**********************************************
ProgressWorker worker = new ProgressWorker(model); //HAVE AN ERROR HERE
worker.execute();

This is the progress renderer class:

//a table cell renderer that displays a JProgressBar
public class ProgressCellRender extends JProgressBar implements TableCellRenderer {

  @Override
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      int progress = 0;
      if (value instanceof Float) {
          progress = Math.round(((Float) value) * 100f);
      } else if (value instanceof Integer) {
          progress = (int) value;
      }
      setValue(progress);
      return this;
  }
}

Now you can see that I am using getColumn in order to display this column but when I run it you can see the first and second but not the progress bar column. I want it to look similar to this:

JTable with progress bar column example

I also has a progress worker class that is not fully implemented.

private static class ProgressWorker extends SwingWorker<Void, Integer> 
    { //Swing worker class for updating the progress bar

        private BiogramTableJSedit2Jan9 model;

        private final JProgressBar progress; //declaration for progress bar

        public ProgressWorker(JProgressBar model)
        { 
            this.progress = model;

        }

        @Override
        protected Void doInBackground() throws Exception {

            return null;
        }

I would appreciate if anyone can explain to me why the thirst column is not being displayed. Thanks for any replies in advance.


Solution

  • Because your posted code was not self-contained I set up a minimal test together with your already posted ProgressCellRender class.

    The important bugfix is in method getColumnClass of the DefaultTableModel. It needs to return Integer.class or Float.class because only those can be handled by your ProgressCellRender.

    And of course, the actual data in that column need to be Integer or Float.

    public class Main {
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(Main::initGUI);
        }
    
        private static void initGUI() {
            JFrame frame = new JFrame("TableModel JProgressBar Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            JScrollPane scroll = new JScrollPane();
            frame.getContentPane().add(scroll);
    
            final JTable table = new JTable();
            scroll.setViewportView(table);
    
            DefaultTableModel model = new DefaultTableModel() {
                public Class<?> getColumnClass(int column) {
                    switch (column) {
                    case 0:
                        return Boolean.class;
                    case 1:
                        return String.class;
                    case 2:
                        return Integer.class;  // !!!!
                    default:
                        return String.class;
                    }
                }
            };
            table.setModel(model);
    
            model.addColumn("Active");
            model.addColumn("Name");
            model.addColumn("Progress");
    
            table.getColumn("Progress").setCellRenderer(new ProgressCellRender());
    
            model.addRow(new Object[] { true, "aaaa", 14 });
            model.addRow(new Object[] { false, "bbbbbbbb", 0 });
            model.addRow(new Object[] { true, "ccccc", 2 });
    
            frame.pack();
            frame.setVisible(true);
        }
    }
    

    Then the JProgressBars are rendered correctly in the table:

    enter image description here

    In your ProgessCellRender you may want to add setStringPainted(true); to get the percentage also rendered as text.