我想,这个夏天不是真正的夏天。 一杯咖啡让我觉得夏天很艰难(笑)。
我有一个有点调皮的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 单元格 后使其不可见,因此我尝试在按下 后执行我的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 无法更改其图标(图像),也无法更改其可见性。是模型导致了这一切吗? 注意:我的单元格数据是在模型创建不同后添加的。
最佳答案
在我看来,您想要做的就是将所有表格单元格留空,除了用户点击的单元格,应该出现一些标记图标的地方,对吧?
如果是这样,您的表模型不应包含 JLabel
实例。 JLabel 是一个可视化组件,用于以图形方式呈现一些数据。数据本身不是 JLabel。在你的情况下,我认为它应该是一个 boolean 值(当用户点击时为真,否则为假)。
现在您可以使用自定义渲染器(尽管 boolean 值的默认渲染器也可以)来显示您的 boolean 值。此渲染器将是 DefaultTableCellRenderer
的子类,它本身是 JLabel 的子类。如果要呈现的 boolean 值为真,渲染器(配置为使用此渲染器的所有单元格的相同实例)将只显示一个标记图标,以及一个未标记图标(或根本没有图标)当要呈现的 boolean 值为 false 时。
然后,您的点击处理程序将只有一项任务:使被点击的单元格包含 true 而不是 false。为此,它只需更改表模型中的适当值。
回顾一下:表模型用于保存数据。将其视为您在数据库中找到的数据。你会在数据库中保存一个 JLabel 吗?不,你会持有一个 boolean 值、一个字符串或一个整数。表格可以随心所欲地渲染这些数据,这就是渲染器的使命。
旁注:停止使用匈牙利符号:它在 Java 中没有意义。它使代码难以阅读。除了原始类型之外的所有东西都是一个对象,你不能为每个可能的类型分配一个有意义的前缀。相反,使用可读且有意义的英文名称:tableModel
而不是 o_dtb
,correctAnswer
而不是 s_questAns
, userAnswer
而不是 s_userAns
。
关于java - JTable、JLabel 和它的图标(JLabel 不能用图标自定义)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7137114/