简体   繁体   中英

Java. How to make Jtable specific cell not selectable?

OK since Im making room renting app and Jtable brings me confusion I need your help. When certain room is selected my Jtable should be updated to not let user select cell which contains day of taken room. So somehow I need to make certain cell non selectable by passing rowindex and columnindex. How do I do this?

You can use Custom JTable which implements isCellEditable() function and Suppose if I want to disallow all entries of First Column to be selected then I can implement this as:

JTable  table=new JTable()
{
    public boolean isCellEditable(int rowindex, int colindex)
    {
        if(colindex==0)
        {
            return false; // Disallow Column 0
        } 
        else 
        {
            return true;  // Allow the editing
        }
    }        
};

Then Suppose we have table data in data[][] array and headers in headers[] array then We need to set Model of JTable and also add data and headers into it and then we will implement TableModelListener to call edit method whenever a cell is clicked.

table.setModel(tableModel);            
table.getModel().addTableModelListener(new TableModelListener() 
{
    public void tableChanged(TableModelEvent e)
    {
        if(e.getType()==TableModelEvent.UPDATE)
        {
            int col = e.getColumn();
            int row=e.getFirstRow();
            UpdateData(row,col); //This function will be called whenever a cell is clicked.
        }
    }
});

Now UpdateData function you can implement with your logic that what you want to do with that cell whenever it is clicked.

public void UpdateData(int row,int col) 
{ 
    //Implement the logic to update data
}

So this is one way to make JTable to disallow some cells to be edited. You can also change the logic of isCellEditable() functions according to your requirement.

Suppose I have many some specific cells to be not edited then I can store the indexes of such cells and every time check that the cell clicked doesn't exist in the entries not to be edited.

ArrayList<Integer> row_index=new ArrayList<Integer>();
ArrayList<Integer> column_index=new ArrayList<Integer>();

row_index.add(4);column_index.add(3);
row_index.add(1);column_index.add(3);
row_index.add(2);column_index.add(2);

now implmentation of `isCellEditable()` function:

public boolean isCellEditable(int rowindex, int colindex)
{
    for(int i=0;i<row_index.size();i++)
    {
        int row=row_index.get(i);
        int column=column_index.get(i);

        if(row==rowindex && column=columnindex) //If the entry exists 
            return false;
    }

    return true;
} 

I have used here Dynamic Structure here to store the indexes assuming that new entries will be added in JTable .

hey hi actually yes I will be making changes to cell colors but problem is I have cell renderer class but Only way I managed to change colors using this table.getColumnModel().getColumn( 0 ).setCellRenderer( tce ); but its not good since this requires mouse click to change color so I have no idea how to show which cell to paint (by row and column) without any clicking because color must be changed once room selected from combobox. So yeah I stuck with this. Maybe you can help me with this I would be really grateful. Its so hard to work with tables

This basic idea sounds right, but I'd need to see your code to know why it's not working.

Below is a basic example of using a TableCellRenderer to display which cells are "booked", they prevent the UI from painting them as selected, the user can still click/select the cell and the table will generate selection notifications, but visually, they won't appear selected.

选择不突出

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.Vector;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Cell {

        private boolean isBooked;

        public Cell() {
            isBooked = Math.random() > 0.5 ? true : false;
        }

        public boolean isBooked() {
            return isBooked;
        }
    }

    public static class CellTableCellRenderer extends DefaultTableCellRenderer {

        private static Color BOOKED_COLOR = Color.DARK_GRAY;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (value instanceof Cell) {
                Cell cell = (Cell) value;
                if (cell.isBooked) {
                    setBackground(BOOKED_COLOR);
                } else if (isSelected) {
                    setBackground(table.getSelectionBackground());
                } else {
                    setBackground(table.getBackground());
                }
            }
            return this;
        }

    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());

            DefaultTableModel model = new DefaultTableModel(0, 10) {
                @Override
                public Class<?> getColumnClass(int columnIndex) {
                    return Cell.class;
                }

            };
            for (int row = 0; row < 10; row++) {
                Vector<Cell> cells = new Vector<>(10);
                for (int col = 0; col < 10; col++) {
                    cells.add(new Cell());
                }
                model.addRow(cells);
            }

            JTable table = new JTable(model);
            table.setDefaultRenderer(Cell.class, new CellTableCellRenderer());
            add(new JScrollPane(table));
        }

    }

    public class RowSelectionModel extends DefaultListSelectionModel {

        @Override
        public void setSelectionInterval(int index0, int index1) {
            System.out.println("Row-setSelectionInterval-" + index0 + "-" + index1);
            super.setSelectionInterval(index0, index1); //To change body of generated methods, choose Tools | Templates.
        }
    }

    public class ColumnSelectionModel extends DefaultListSelectionModel {

        @Override
        public void setSelectionInterval(int index0, int index1) {
            System.out.println("Column-setSelectionInterval-" + index0 + "-" + index1);
            super.setSelectionInterval(index0, index1); //To change body of generated methods, choose Tools | Templates.
        }
    }
}

What's important to note here is, the rendering is tied to a single renderer, so ALL the logic for rendering needs to be carried through this single render.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM