Java。如何使 Jtable 特定单元格不可选?
Java. How to make Jtable specific cell not selectable?
好的,因为我正在制作房间出租应用程序,而 Jtable 给我带来了困惑,我需要你的帮助。当某个房间被 selected 时,我的 Jtable 应该被更新以不允许用户 select 单元格包含被占用的房间的日期。因此,我需要以某种方式通过传递行索引和列索引来使某些单元格无法 select。我该怎么做?
您可以使用实现 isCellEditable()
功能的 Custom JTable
假设如果我想禁止选择第一列的所有条目,那么我可以将其实现为:
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
}
}
};
然后假设我们在 data[][] array
中有 table data
并且在 headers[]
数组中有 headers
然后我们需要设置 JTable 的 Model
并添加 data
和 headers
到其中,然后我们将实现 TableModelListener
以在单击单元格时调用编辑方法。
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.
}
}
});
现在 UpdateData
函数,您可以使用您的逻辑实现您希望在单击该单元格时对其执行的操作。
public void UpdateData(int row,int col)
{
//Implement the logic to update data
}
所以这是使 JTable 禁止编辑某些单元格的一种方法。您还可以根据需要更改 isCellEditable()
函数的逻辑。
假设我有很多特定的单元格不需要编辑,那么我可以存储这些单元格的索引,并且每次检查单击的单元格是否不存在于不需要编辑的条目中。
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;
}
我在这里使用 Dynamic Structure
来存储索引,假设新条目将添加到 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
这个基本想法听起来不错,但我需要查看您的代码才能知道为什么它不起作用。
下面是使用 TableCellRenderer
显示哪些单元格是 "booked" 的基本示例,它们可以防止 UI 将它们绘制为选中状态,用户仍然可以 click/select 单元格和 table 将生成选择通知,但在视觉上,它们不会显示为已选中。
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.
}
}
}
这里需要注意的重要一点是,渲染绑定到单个渲染器,因此所有渲染逻辑都需要通过这个渲染器执行。
好的,因为我正在制作房间出租应用程序,而 Jtable 给我带来了困惑,我需要你的帮助。当某个房间被 selected 时,我的 Jtable 应该被更新以不允许用户 select 单元格包含被占用的房间的日期。因此,我需要以某种方式通过传递行索引和列索引来使某些单元格无法 select。我该怎么做?
您可以使用实现 isCellEditable()
功能的 Custom JTable
假设如果我想禁止选择第一列的所有条目,那么我可以将其实现为:
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
}
}
};
然后假设我们在 data[][] array
中有 table data
并且在 headers[]
数组中有 headers
然后我们需要设置 JTable 的 Model
并添加 data
和 headers
到其中,然后我们将实现 TableModelListener
以在单击单元格时调用编辑方法。
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.
}
}
});
现在 UpdateData
函数,您可以使用您的逻辑实现您希望在单击该单元格时对其执行的操作。
public void UpdateData(int row,int col)
{
//Implement the logic to update data
}
所以这是使 JTable 禁止编辑某些单元格的一种方法。您还可以根据需要更改 isCellEditable()
函数的逻辑。
假设我有很多特定的单元格不需要编辑,那么我可以存储这些单元格的索引,并且每次检查单击的单元格是否不存在于不需要编辑的条目中。
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;
}
我在这里使用 Dynamic Structure
来存储索引,假设新条目将添加到 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
这个基本想法听起来不错,但我需要查看您的代码才能知道为什么它不起作用。
下面是使用 TableCellRenderer
显示哪些单元格是 "booked" 的基本示例,它们可以防止 UI 将它们绘制为选中状态,用户仍然可以 click/select 单元格和 table 将生成选择通知,但在视觉上,它们不会显示为已选中。
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.
}
}
}
这里需要注意的重要一点是,渲染绑定到单个渲染器,因此所有渲染逻辑都需要通过这个渲染器执行。