2

enter image description here

I have just started working with JTable. This is my table example. The add row button adds rows to the table. I want to create row headers for this table. How can I achieve this?

Can any one help me please?

The code for the sample table is:

package test;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.table.*;

import test.InsertRows.CellEditor;

public class SampleTable extends JFrame {

JTable table;
JPanel panel;
DefaultTableModel dataModel;

public SampleTable () {
    super("My Table Example");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    onInit();
} 

void onInit()
{
    JButton b=new JButton("Add Row");
    b.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e)
        {
            // TODO Auto-generated method stub
            insertNewRow();

        }


    });

    panel = new JPanel(new BorderLayout());

    String[] columnNames = {
            "Name",
            "OID",
            "Index",
            "Value",
    };
    Object[][] data = {
            {"sysLocation","1.3.6.1.2.1.1.6","0",""},
                {"sysContact","1.3.6.1.2.1.1.4","0",""},
                    {"sysDescr","1.3.6.1.2.1.1.1","0",""}

    };

    dataModel = new DefaultTableModel();
    for (int col = 0; col < columnNames.length; col++) {
        dataModel.addColumn(columnNames[col]);
    }
    for (int row = 0; row < 3; row++) {
        dataModel.addRow(data[row]);
    }

    table = new JTable(dataModel);
    table.setDefaultEditor(Object.class, new CellEditor(this, table));
    table.setPreferredScrollableViewportSize(new Dimension(600, 120));
    table.setFillsViewportHeight(true);

    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);

    //Add the scroll pane to this panel.
    panel.add(scrollPane,BorderLayout.CENTER);
    panel.add(b,BorderLayout.SOUTH);
    panel.setOpaque(true); //content panes must be opaque
    setContentPane(panel);

    //Display the window.
    pack();
    setVisible(true);
}
public static void main(String[] args) {
    SampleTable myFrame = new SampleTable();
} 
private void insertNewRow()
{

    if(vaidCheck(table)){
        dataModel.insertRow(table.getRowCount(),
                new Object[] {"", "", "", ""}
                );
        dataModel.fireTableRowsInserted(
                dataModel.getRowCount(),
                dataModel.getRowCount()
        );
    }
    else{
        JOptionPane.showMessageDialog(null,"Field is empty");                                                                            
    }

}
public boolean vaidCheck(JTable table)
{
      if(table.getCellEditor()!=null){
          table.getCellEditor().stopCellEditing();
      }
      for(int row=0;row< table.getRowCount();row++){
          for (int col=0;col<table.getColumnCount();col++){
              String om=table.getValueAt(row,col).toString();
              if(om.trim().length()==0){
                  return false;
              }
          }
      }
      return true;
 }

 public class CellEditor extends DefaultCellEditor
  {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private JTable m_Table = null;
        public CellEditor(JFrame parentFrame, JTable table) { 
            super(new JTextField());
            super.setClickCountToStart(1);
            m_Table = table;
        }
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, int column)
        {
            if(column == 0){
                 Object[] objectArray = {"Nikhil","Nijil"};
                    JComboBox comboBox = new JComboBox(objectArray);
                    comboBox.setEditable(true);
                    comboBox.setSelectedItem(value);

                    ItemListener itemListener = new ItemListener() {
                        public void itemStateChanged(ItemEvent e) {
                            if(e.getStateChange() == ItemEvent.SELECTED) {
                                if(null != m_Table.getCellEditor()){ 
                                    m_Table.getCellEditor().stopCellEditing();
                                }

                                m_Table.setValueAt(e.getItem(), row, 0);
                            }
                        }
                    };
                    comboBox.addItemListener(itemListener);
                    return comboBox;
            }
            if(column == 2){

            }
            JTextField textField = (JTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
            return textField;

        }
  }
} 

enter image description here

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Nikhil
  • 2,857
  • 9
  • 34
  • 58
  • Take a look at [How to Use Scroll Panes](http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html) and [`JScrollPane#setRowHeaderView`](http://docs.oracle.com/javase/7/docs/api/javax/swing/JScrollPane.html#setRowHeaderView%28java.awt.Component%29) – MadProgrammer Nov 01 '12 at 04:33
  • I don't understand the example. It already has rows and a header in it when it first appears. Changing `if(vaidCheck(table)){` to `if (true) {` and new rows will appear. A scroll bar is shown when there are too many rows for the visible area. What is the expected end result? What is the actual problem? – Andrew Thompson Nov 01 '12 at 04:41
  • the vaildCheck() is used to check the rows are empty or not. I want row headers. – Nikhil Nov 01 '12 at 04:58
  • [for example](http://stackoverflow.com/a/8187799/714968) link to the better example in comment – mKorbel Nov 01 '12 at 07:06

1 Answers1

5

I hope my interpretation of the question is correct. To display a row header you need to create a new cell renderer and set it on the required column. For example, here is a basic renderer that mocks a table header:

static class RowHeaderRenderer extends DefaultTableCellRenderer {
    public RowHeaderRenderer() {
        setHorizontalAlignment(JLabel.CENTER);
    }

    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row,
            int column) {
        if (table != null) {
            JTableHeader header = table.getTableHeader();

            if (header != null) {
                setForeground(header.getForeground());
                setBackground(header.getBackground());
                setFont(header.getFont());
            }
        }

        if (isSelected) {
            setFont(getFont().deriveFont(Font.BOLD));
        }

        setValue(value);
        return this;
    }
}

To set it up you can do the following:

table.getColumnModel().getColumn(0).setCellRenderer(new RowHeaderRenderer());

Here is how it looks like based on the posted code:

enter image description here

tenorsax
  • 21,123
  • 9
  • 60
  • 107
  • 1
    This is not m actual requirement. but i accept it because from this i can achieve it. thank u. – Nikhil Nov 01 '12 at 05:45
  • can i see that image i posted. – Nikhil Nov 01 '12 at 05:56
  • That is my actual requirement. Can i block that raw header from editing. Only that row header? is it possible and can i set an image to that row header? – Nikhil Nov 01 '12 at 05:57
  • @Nikhil, yes, don't call `setDefaultEditor`, set editors for particular columns through `TableColumnModel`. Also, extend table model and override `isCellEditable` to return `false` for this particular column. – tenorsax Nov 01 '12 at 06:02
  • @Nikhil also note that your editor has hardcoded columns and it has a special case for column 0. – tenorsax Nov 01 '12 at 06:15