解决方案 »
- 这段程序中的bonnie和clyde从何而来?
- 帮帮忙:swing中做一段文字的滚动(上下方向)
- UIResource在LookAndFeel中起什么作用,如何使用?
- 对于同步概念还不大清晰:这种情况需要加synchronized关键字吗?
- 如何获取异常堆栈消息?
- graphics对象为空?
- 通过response重定向页面的参数值乱码问题。
- com.ibm.db2.jdbc.app.DB2Driver从哪里可以下载 ?
- 请问在JAVA里将小写字母换为大写字母是用什么函数,大写转成小写又是用哪个函数?
- 如何把Date变成byte[](String也行),然后又能把byte[]变回一个Date??? 求救!!!
- 关于Boolean传值的一个问题,不明白?大家帮助一下!
- JAVA怎么处理这样的XML文件,IE中已经可以正常显示
....
JCheckBox cb = (JCheckBox) ce.getComponent();
cb.setSelected(true); //
cb.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
jCheckBox1ItemStateChanged(evt);
}
});
.....
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object[][] { { new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null }, { new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null } }, new String[] { "Title 1",
"Title 2", "Title 3", "Title 4" }) {
public void setValueAt(Object value, int row, int col) {
super.setValueAt(value, row, col);
if (value instanceof Boolean) {
if ((Boolean)value) {
for(int x = 0, y = jTable1.getRowCount(); x < y; x++) {
System.out.println(jTable1.getValueAt(x, 0));
}
System.out.println("----------------------------");
}
}
}
});
然后把你给cb加的那个listener去掉
public void actionPerformed(ActionEvent arg0) {
for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
System.out.println(jTable1.getValueAt(x, 0));
}
System.out.println("----------------------------");
}});
但是还存在一个问题,就是打印的结果总是落后一步,打印的是上一次的结果。
因为该监听器总是在celleditor想JTable写入之前调用。
修改后的代码如下:import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableColumn;public class AccountMode extends javax.swing.JFrame {
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1; public AccountMode() {
initComponents();
} private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object[][] { { new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null } },
new String[] { "Title 1", "Title 2", "Title 3", "Title 4" }) {
//***********看这里 看这里 看这里***************************
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
super.setValueAt(aValue, rowIndex, columnIndex);
for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
System.out.println(jTable1.getValueAt(x, 0));
}
System.out.println("----------------------------");
}
});
// 将boolean转为jcheckbox
TableColumn tc = jTable1.getColumnModel().getColumn(0);
tc.setCellEditor(jTable1.getDefaultEditor(Boolean.class));
tc.setCellRenderer(jTable1.getDefaultRenderer(Boolean.class)); jScrollPane1.setViewportView(jTable1);
// 这里是关于布局,可以不看start
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addContainerGap(15, Short.MAX_VALUE)
.addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE, 375,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap()));
layout.setVerticalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE, 275,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(15, Short.MAX_VALUE)));
// 这里是关于布局,可以不看end
pack();
} public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AccountMode().setVisible(true);
}
});
}
}
我没有叫你去掉jcheckbox,只是叫你去掉你自己新加的监听方法,
然后重载系统已经默认存在的监听方法
这个jcheckbox的事件,直接触发了TableModel的setValueAt()方法
可以翻译成这样,在你生成了这样一个TableModel后,
jcheckbox已经有了一个默认存在的ItemListener
jcheckbox.addItemListener(ItemListener() {
public void itemStateChanged(ItemEvent evt) {
……
setValueAt();
……
}
});
你只要把你自己先实现的代码放到setValueAt();里面,就实现了对jcheckbox的事件监听
对JDK研究一段时间后,你可以发现很多的东西都是互通的
不要限死自己的思维,JDK给实现一个目标留下了无数的入口
你从哪个入口进去都可以,关键是看从哪个入口进去对你来说最方便
这个监听会在更改model的数据之前被触发。此时的数据,尚未更改,因此,你看起来就好像打印出的数据总是落后一个步骤一样,但是实际上,你所打印的,的确是更改前的数据。不了解你的想法,要在这里做些什么。但是一般很少这样去做这个监听。
对于表格里面的东西,
第一,可以如上述各位所言,在model里面setvalueat方法之后去做。这个可以保证取到的值一定是最新的同步数据。而且可以得到表格更改的row,column,value信息。但是这样,可能结构不太好,代码看起来不太齐整。第二,你可以在编辑器里面做文章。不知你有没有发现,如果你点鼠标,按下,抬起,这会触发两个itemstatechanged事件。一个就是你写的selected,另一个当然是unselected。只有当你完成按下又抬起的过程,才算是完成了一次编辑。这之后才会更新model的数据,你从model取得的才会是新值。可是你仔细看一下你的过程,原先选中的,你按下鼠标的时候就已经打印了,可是这时候根问没有完成编辑过程啊。
上面有人说,在监听里面调用setvalueat方法,不可取。这样,相当于你的这个操作过程,改变了两次model的值,而第一次,是不对的。你可以写一个自己的editor,其中有stopCellEditing()方法。在stopCellEditing之后你再调用即可保证获得同步数据。
第三,既然可以通过观察是否结束编辑来确定是否数据已经跟新,自然可以给编辑器加监听。但是,幸运的是,JTable自己已经实现了CellEditorListener这个接口,也就是说,JTable自身就是这样的一个很好的监听器。你没有写自己的editor,那么第二种方法我也就不多说了,留待你日后体会。你看一下这种方法:import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableColumn;public class AccountMode extends javax.swing.JFrame {
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1; public AccountMode() {
initComponents();
} private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable() {
@Override
public void editingStopped(ChangeEvent e) {
// TODO Auto-generated method stub
super.editingStopped(e); for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
System.out.println(jTable1.getValueAt(x, 0));
}
System.out.println("----------------------------");
}
}; setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object[][] { { new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null },
{ new Boolean("true"), null, null, null } },
new String[] { "Title 1", "Title 2", "Title 3", "Title 4" }));
// 将boolean转为jcheckbox
TableColumn tc = jTable1.getColumnModel().getColumn(0);
tc.setCellEditor(jTable1.getDefaultEditor(Boolean.class));
tc.setCellRenderer(jTable1.getDefaultRenderer(Boolean.class)); DefaultCellEditor ce = (DefaultCellEditor) jTable1
.getDefaultEditor(Boolean.class);
JCheckBox cb = (JCheckBox) ce.getComponent();
cb.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
jCheckBox1ItemStateChanged(evt);
}
}); jScrollPane1.setViewportView(jTable1);
// 这里是关于布局,可以不看start
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap(15,
Short.MAX_VALUE).addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE, 375,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap()));
layout.setVerticalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
layout.createSequentialGroup().addContainerGap().addComponent(
jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE,
275, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(15, Short.MAX_VALUE)));
// 这里是关于布局,可以不看end
pack();
} private void jCheckBox1ItemStateChanged(java.awt.event.ItemEvent evt) { // if (evt.getStateChange() == ItemEvent.SELECTED) {
// for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
// System.out.println(jTable1.getValueAt(x, 0));
// }
// System.out.println("----------------------------");
// }
} public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AccountMode().setVisible(true);
}
});
}
}
有没有JTable 单键编辑,而且带光标的方法?谢谢。