我对java很陌生,所以请原谅我犯的任何愚蠢的错误......
我有一个 2 列的 JTable,其中第 2 列可以有 4 种类型:
- 不能更改值的列
- 可以包含任何文本字符串的列
- 包含 JComboBoxes 的列
- 包含 JCheckBoxes 的列
列类型是动态的,因为它们取决于接收到的数据。
所有类型都可以正常工作,除了 JCheckBox。当我用具有 2 个选项的 JComboBox 替换 JCheckBox 时,它可以正常工作。所以我猜JCheckBox的代码有问题。
问题是 :
- 当 JCheckBox 被选中时,我只需单击 1 次即可取消选中它
- 但是,当未选中 JCheckBox 时,我需要单击它两次(而不是双击)来检查它
编辑
一个示例项目(尽可能小):
import java.awt.Component;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class frmCheck extends JApplet
{
JTable mgrdData;
DefaultTableModel mtableModel;
public void init()
{
mtableModel = new DefaultTableModel();
mtableModel.setColumnCount(2);
mtableModel.setRowCount(4);
mgrdData = new JTable(mtableModel);
mgrdData.getSelectionModel().addListSelectionListener(new RowListener());
add(mgrdData);
for (int i=1;i<mtableModel.getRowCount();i++)
{
addCheck(1);
}
}
private class RowListener implements ListSelectionListener
{
public void valueChanged(ListSelectionEvent event)
{
if (event.getValueIsAdjusting()) return;
}
}
private void addCheck(int intCol)
{
mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
{
JCheckBox rendererComponent = new JCheckBox();
String strVal="";
if (value!=null) strVal = value.toString();
if (strVal.equals("1"))
{
rendererComponent.setSelected(true);
} else
{
rendererComponent.setSelected(false);
}
return rendererComponent;
}
});
DefaultCellEditor cellEditor = new DefaultCellEditor(new JCheckBox());
cellEditor.setClickCountToStart(1);
cellEditor.addCellEditorListener(new CellEditorListener()
{
public void editingCanceled(ChangeEvent e) {}
public void editingStopped(ChangeEvent e)
{
JCheckBox checkBox = (JCheckBox)((DefaultCellEditor)e.getSource()).getComponent();
System.out.println("isSelected = " + checkBox.isSelected());
if (checkBox.isSelected())
{
System.out.println("Sent 0");
} else
{
System.out.println("Sent 1");
}
}
});
mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}
}
我用来查看小程序的 html 页面是:
<html>
<body>
<applet code="frmCheck.class" width="1016" height="822"></applet>
</body>
</html>
要使其成为可执行文件(应用程序),您可以向其中添加以下 main() 函数(在 init() 函数上方,mtableModel 声明下方)
public static void main(String[] args) {
frmCheck myApplet = new frmCheck(); // define applet of interest
Frame myFrame = new Frame("Applet Holder"); // create frame with title
// Call applet's init method (since Java App does not
// call it as a browser automatically does)
myApplet.init();
// add applet to the frame
myFrame.add(myApplet, BorderLayout.CENTER);
myFrame.pack(); // set window to appropriate size (for its elements)
myFrame.setVisible(true); // usual step to make frame visible
}
当您单击未选中的复选框时,控制台会显示:
isSelected = true
Sent 0
之后,当我再次单击该复选框(因此第二次)时,该复选框仍未选中,然后控制台显示:
isSelected = false
Sent 1
复选框在短时间内闪烁为选中状态,然后当我再次单击复选框时再次变为未选中状态(因此第三次),然后它的行为就像第一次被单击
我希望复选框: - 未选中并单击时发送 1 - 选中并单击时发送 0
真正的项目有点复杂:通过检查 JCheckBox,我向设备发送一条消息,该设备以其当前状态进行回答,该状态被处理并显示为选中的 JCheckBox。当我通过另一个通道更改设备中的状态时,处理工作正常,然后 JCheckBox 完美显示当前状态
我希望 JCheckBox 响应 1 单击:
- 当它被选中并单击它时,它应该发送“REG SCH 4 = 0”
- 当它未选中并单击它时,它应该发送“REG SCH 4 = 1”
好的,这是我到目前为止的代码:
JTable 创建如下:
JTable mgrdData;
DefaultTableModel mtableModel;
mtableModel = new DefaultTableModel(null,new String[0]);
mgrdData = new JTable(mtableModel);
mgrdData.getSelectionModel().addListSelectionListener(new RowListener());
mgrdData.setFillsViewportHeight(true);
String[] strHeader = {"Naam","Waarde"};
mtableModel.setColumnIdentifiers(strHeader);
列配置如下:
addReadOnly(0);
// addCombo(1,new String[]{"UIT","AAN"}); //this works fine
addCheck(1);
第 0 列是只读的,第 1 列有 2 个可能的值,其中 addCombo(1,new String[]{"UIT","AAN"}); 完美的作品
函数 addReadOnly 和 addCombo 和 addCheck 如下:
private void addReadOnly(int intCol)
{
JTextField txtField = new JTextField();
txtField.setEditable(false);
DefaultCellEditor cellEditor = new DefaultCellEditor(txtField);
mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}
private void addCombo(int intCol,final String[] strItems)
{
//add combobox
mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
{
JComboBox rendererComponent = new JComboBox(strItems);
if (value!=null) rendererComponent.setSelectedItem(value.toString());
return rendererComponent;
}
});
DefaultCellEditor cellEditor = new DefaultCellEditor(new JComboBox(strItems));
cellEditor.setClickCountToStart(1);
cellEditor.addCellEditorListener(new CellEditorListener()
{
private boolean blnChanged=false;
public void editingCanceled(ChangeEvent e) {}
public void editingStopped(ChangeEvent e)
{
if (blnChanged==true)
{
JComboBox comboBox = (JComboBox)((DefaultCellEditor)e.getSource()).getComponent();
sendVal(String.valueOf(comboBox.getSelectedIndex()));
blnChanged = false;
} else
{
blnChanged = true;
}
}
});
mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}
private void addCheck(int intCol)
{
//add checkbox
mgrdData.getColumnModel().getColumn(intCol).setCellRenderer(new TableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean isFocused,int row,int col)
{
JCheckBox rendererComponent = new JCheckBox();
String strVal="";
if (value!=null) strVal = value.toString();
// if (strVal.equals("AAN"))
if (strVal.equals("1"))
{
rendererComponent.setSelected(true);
} else
{
rendererComponent.setSelected(false);
}
return rendererComponent;
}
});
DefaultCellEditor cellEditor = new DefaultCellEditor(new JCheckBox());
cellEditor.setClickCountToStart(1);
cellEditor.addCellEditorListener(new CellEditorListener()
{
public void editingCanceled(ChangeEvent e) {}
public void editingStopped(ChangeEvent e)
{
JCheckBox checkBox = (JCheckBox)((DefaultCellEditor)e.getSource()).getComponent();
System.out.println("isSelected = " + checkBox.isSelected());
if (checkBox.isSelected())
{
sendVal("0");
System.out.println("Sent 0");
} else
{
sendVal("1");
System.out.println("Sent 1");
}
}
});
mgrdData.getColumnModel().getColumn(intCol).setCellEditor(cellEditor);
}
点击 3 次后的测试结果:
选中 JCheckBox,单击 1 次后的结果:
isSelected = true
Sent : REG SCH 4 = 0
Sent 0
在此之后,未选中 JCheckBox
JCheckBox 未选中,单击 1 次后的结果:
isSelected = true
Sent : REG SCH 4 = 0
Sent 0
在此之后 JCheckBox 仍然未选中
JCheckBox 未选中但已单击一次,第二次单击后的结果:
isSelected = false
Sent : REG SCH 4 = 1
Sent 1
在此之后检查 JCheckBox
我搜索并找到了当您总是需要 2 次点击的解决方案,或者具有固定复选框而不是动态的解决方案,但不是像我这样的情况......
任何人都可以阐明一下吗?