Search code examples
javaswingmatlabmatlab-uitablejide

How to customise JIDE grids in Matlab


I am using JIDE grids for loading huge data tables in a uitable format. My main reason for using JIDE grid was to have a working filtering and sorting ability. There are filter/sorters available out there which can be hooked with old uitable and are easier to configure but most sort lexically rather than numerically. I believe that is due to Matlab's underlying data class.

So far, JIDEs inbuilt filtering is working well and uitable loads even faster than old version of uitable in Matlab when I load neary 500x35 of mixed data type. But there are a few other things that I would like to configure, to which I have found no referent in JIDE documentation.


1) Does anyone knows how to add row number column in JIDE implementation? (just like row number header in old/new uitable configurations). I have tried to use findobj and inspect (by Yair Altman) utility to find them and switch them on but they seems to be completely missing.Or I am missing something! JIDE Implementation Would like to see similar row headers as in old uitable

2) When we select 'custom filter' from the column dropdown and pick 'is' or 'doesn't equal' or 'is greater than' it shows a date selection tab, how can we remove this tab. If that is not possible or difficult, how can I remove these options? enter image description here


3) Lastly, How can I set the number of decimal places displayed in the grid?


Code to reproduce the issues.

% calling old uitable for performance reasons
f1=figure;
[h_Old,containter] = uitable('v0','data',magic(5),'ColumnNames',{'A','B',...
    'C','D','E'},'Position',[5 5 500 400],'Parent',f1);
set(h_Old,'Units','normalized','Editable',false);

% Anotherway: JIDE grids even faster in setting up uitable with huge data
data=num2cell(magic(5));
jtable=com.jidesoft.grid.SortableTable(data,{'A','B','C','D','E'});
theader = com.jidesoft.grid.AutoFilterTableHeader(jtable);
theader.setAutoFilterEnabled(true)
theader.setShowFilterName(true)
theader.setShowFilterIcon(true)
jtable.setTableHeader(theader)
jscroll = javax.swing.JScrollPane(jtable);
f2=figure;
[h_old_2,container_2] = javacomponent(jscroll,[5,5,500,400],f2)
set(container_2,'Units','norm');

Thanks for your time and help.


Solution

  • Answering for the benefit of the other who might face the same problem.

    1) JIDE does not have a row header automatically. It can be done via TableScrollPane which is unfortunately a lot of more complicated. A simple workaround is to make first column as row header and giving it a 'Look and Feel' of a row header by making changes to DefaultTableCellRenderer. Code below. I guess this is easily maintainable in the long run.

    % Making changes to DefaultTableCellRenderer
    % Give first column a header look, Center data
    cr0 = javax.swing.table.DefaultTableCellRenderer();
    cr0.setHorizontalAlignment(0) % 0 for CENTER, 2 for LEFT and 4 for RIGHT
    cr0.setBackground(java.awt.Color(15790320)); % grey backgroundt
    jtable.getColumnModel.getColumn(0).setCellRenderer(cr0);
    jtable.getColumnModel.getColumn(0).setResizable(false);
    jtable.getColumnModel.getColumn(0).setMaxWidth(32);
    

    2) This can be done by defining jtable column class. Still work in progress. Will update my answer soon.

    3) Decimal places can be set by writing a simple extension to DefautTableCellRenderer in Java. Compile this to get a class > javaaddpath to this class in matlab > replace DefaultTableCellRenderer with your TableCellRenderer. A sample Java Class is below:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.text.DecimalFormat;
    public class CustomCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer
    {
        public Component getTableCellRendererComponent
                (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            JComponent cell = (JComponent) super.getTableCellRendererComponent
                    (table, value, isSelected, hasFocus, row, column);
            // set color
            cell.setBackground(new Color(0xC8C8C8));
            cell.setForeground(new Color(0xFFFFFF));
    
            //set Alignment
            ((JLabel)cell).setHorizontalAlignment(SwingConstants.CENTER);
    
            //set selection colors
            if (isSelected){
                cell.setBackground(new Color(0x3399FF));
                cell.setForeground(new Color(0x000000)); // AM
            }else{
                // set decimals
                DecimalFormat DecimalFormatter = new DecimalFormat("#.00");
                value = DecimalFormatter.format(value);
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }
        return cell;
        }
    
    }
    

    Add this class to Matlab and replace replace DefaultTableCellRenderer with your TableCellRenderer like this.

    data = {8.252,1.528,6.2598; 3.258,5.548,7.698; 4.448,9.5454,2.5644}; 
    cols = {'A','B','C'}
    DTM=javax.swing.table.DefaultTableModel(data,cols);
    jtable = com.jidesoft.grid.SortableTable();
    jtable.setModel(DTM);
    jscroll = javax.swing.JScrollPane(jtable);
    [htable,container] = javacomponent(jscroll,[5,5,500,400]);
    set(container,'Units','norm');
    javaaddpath('\ExternalSources\JavaExtenstions\CustomCellRenderer');
    cr=CustomCellRenderer();
    for i=0:2, jtable.getColumnModel.getColumn(i).setCellRenderer(cr), end;
    jtable.repaint;
    

    Hope this help others facing the same issue.