今年夏天不是真正的夏天,我想。 一杯咖啡让我觉得这是一个夏天,坚韧(笑)。
我有点顽皮的JTable。我的天啊。 下面是我的JTable使用我自己的自定义TableModel。您可以在 getColumnClass ()的方法中看到它,那里......它仅用于返回 JLabel 。 然后,我还自定义 DefaultRenderer 。
jtbl_inGameEasy = new javax.swing.JTable();
jtbl_inGameEasy.setFont(new java.awt.Font("squeaky chalk sound", 0, 14)); // NOI18N
jtbl_inGameEasy.setForeground(new java.awt.Color(255, 255, 255));
jtbl_inGameEasy.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"null", "null", "null", "null", "null"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
public Class getColumnClass(int columnIndex) {
return JLabel.class;
}
});
jtbl_inGameEasy.setDefaultRenderer(JLabel.class, new JLabelTableRenderer());
jtbl_inGameEasy.setFocusable(false);
jtbl_inGameEasy.setOpaque(false);
jtbl_inGameEasy.setRowHeight(55);
jtbl_inGameEasy.setShowHorizontalLines(false);
jtbl_inGameEasy.setShowVerticalLines(false);
jtbl_inGameEasy.setTableHeader(null);
jtbl_inGameEasy.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
jtbl_inGameEasyMousePressed(evt);
}
});
JTableRenderer 在哪里?这里... 这是我的自定义渲染器......
public class JLabelTableRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
if (value instanceof JLabel) {
//This time return only the JLabel without icon
return (JLabel) value;
} else {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}
然后,我需要在每个Cell内部使用JLabel。 我开始使用此代码在 JTable 的单元格内添加一些JLabel内部的数组; (这没问题)。
DefaultTableModel o_dtb = jtbl_inGameEasy.getModel();
o_dtb.addRow(myArrayCustomizedObjectofJLabel);
我猜,一切正常。但是因为我的目的是--->要在用户单击上JTable 单元格时放置图标或使其不可见,因此II尝试执行 MouseEvent 一旦按下并调用这些代码行;
private void jtbl_inGameEasyMousePressed(java.awt.event.MouseEvent evt) {
// Checking inGameEasy Table Ans
javax.swing.JTable source = (javax.swing.JTable) evt.getSource();
int row = source.rowAtPoint(evt.getPoint());
int column = source.columnAtPoint(evt.getPoint());
DefaultTableModel o_dtb = (DefaultTableModel) jtbl_inGameEasy.getModel();
String s_questAns = "" + Game.getCurrentQuestion().getResult();
String s_userAns = "" + o_dtb.getValueAt(row, column);
// These two lines below are not Working, why yaa??
((JLabel) o_dtb.getValueAt(row, column)).setVisible(false);
((JLabel) o_dtb.getValueAt(row, column)).setIcon(myIcon);
if (s_questAns.equals(s_userAns)) {
Game.correct();
System.err.println("nice ans!");
} else {
jll_txtMiss.setText("Miss : " + Game.wrong());
System.err.println("nope!");
}
nextQuestion();
}
在我看来,上面的标记(在评论下方)代码无效。 是的,JLabel铸造不能改变它的Icon(图像),也不能改变它的可见性。它是模型导致所有这些吗? 注意:在模型创建方式不同之后,我的单元格数据会被添加。
答案 0 :(得分:4)
在我看来,您想要做的只是将所有表格单元格留空,除了用户点击的单元格,其中应该出现一些标记图标,对吧?
如果是这样,您的表模型不应包含JLabel
个实例。 JLabel是一个可视组件,用于以图形方式呈现一些数据。数据本身不是JLabel。在你的情况下,我认为它应该是一个布尔值(当用户点击时为true,否则为false)。
现在你可以使用自定义渲染器(虽然布尔值的默认渲染器也可以),以显示你的布尔值。此渲染器将是DefaultTableCellRenderer
的子类,它本身是JLabel的子类。渲染器(配置为使用此渲染器的所有单元格的相同实例)只显示标记图标(如果要渲染的布尔值为true),并且未标记图标(当渲染的布尔值为false时,(或根本没有图标)。
然后,您的点击处理程序将只有一个任务:使单击的单元格包含true而不是false。为此,只需更改表模型中的适当值即可。
回顾一下:表模型用于保存数据。可以将其视为数据库中的数据。你会在数据库中持有JLabel吗?不,你会持有布尔值,字符串或整数。该表可以根据需要呈现此数据,这是渲染器的任务。
旁注:用匈牙利语表示法停止:在Java中没有意义。它使代码难以阅读。除基本类型之外的所有内容都是对象,并且您不能为每个可能的类型分配有意义的前缀。相反,使用可读且有意义的英文名称:tableModel
而不是o_dtb
,correctAnswer
而不是s_questAns
,userAnswer
而不是s_userAns
。