[英]Custom TableCellEditor only working on 1 Column Dispite applied to all
I have a rather complex JTable I'm working on. 我正在处理一个相当复杂的JTable。 The number of rows and columns are build off a list.
行和列的数量基于列表。 Then depending on what column of what row the cell editor needs to change out.
然后,根据单元格编辑器需要更改为哪一行的哪一列。 While Goggling for a solution I found this: http://www.java2s.com/Code/Java/Swing-Components/EachRowwithdifferentEditorExample.htm
搜寻解决方案时,我发现了这一点: http : //www.java2s.com/Code/Java/Swing-Components/EachRowwithdifferentEditorExample.htm
I took that code as it was and run it just to make sure it was working the current Java versions and it did. 我按原样使用该代码并运行它,以确保它可以在当前的Java版本上正常运行。 So i worked it into my JTable i had already build, but what seems to be happening is when I go to apply it to multiple columns it only ends up working for the first column.
因此,我将其应用于已经构建的JTable中,但是似乎正在发生的事情是,当我将其应用于多个列时,它只能在第一列中工作。
I put together a fully executable section of code that I have commented and set up to simulate my database data. 我整理了一段完全可执行的代码,并将其注释并设置为模拟数据库数据。 The code is pretty decently commented so should be easy to follow.
该代码是相当体面的注释,因此应该易于遵循。 This sample does at least for me still produces the problem.
这个样本至少对我而言仍然会产生问题。
If any of you can see whats wrong I would greatly appreciate the help. 如果您有任何发现错误的地方,我将不胜感激。
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class EachRowEditorExample extends JFrame {
public EachRowEditorExample() {
super("EachRow Editor Example");
List<Membership> _Memberships = new ArrayList<Membership>();
DefaultTableModel DataModel;
//Lets Start by simluating the data.
for (int z = -2; z < 10; z++)
{
Membership m = new Membership();
m.setId(z);
if (z == -2)
{
m.setMembership("Employee");
m.setEft(false);
}
else if (z == -1)
{
m.setMembership("NONE");
m.setEft(false);
}
else
{
m.setMembership("Membership " + z);
if (z < 3 )
m.setEft(true);
else
m.setEft(false);
}
_Memberships.add(m);
}
//*******************************************************
// Starts Copy and paste from Program
//*******************************************************
//lets build our Data Model
int size = _Memberships.size();
Object[][] rows = new Object[size][];
String[] cols = new String[size];
int x = 0;
for(Iterator<Membership> i = _Memberships.iterator(); i.hasNext(); )
{
Membership side = i.next();
cols[x] = side.getMembership();
Object[] row = new Object[size];
int b = 0;
for(Iterator<Membership> j = _Memberships.iterator(); j.hasNext(); )
{
Membership top = j.next();
if (side.getId() == top.getId() && (side.isEft() && top.isEft()))
{
row[b] = null;
}
else
row[b] = NUHPADX(side.getId(), top.getId());
b++;
}
rows[x] = row;
x++;
}
DataModel = new DefaultTableModel(rows,cols);
//Now Lets create our JTable and configure it.
JTable table = new JTable(DataModel) {
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
Object t = getValueAt(rowIndex, rowIndex);
if (t == null)
return false;
else
return true;
}
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Component c = super.prepareRenderer(renderer, row, column);
Object t = getValueAt(row, column);
if (t == null)
{
c.setBackground(Color.black);
}
else
{
Color PRIMARY_ROW_COLOR = Color.white;
Color ALTERNATE_ROW_COLOR = new Color(0xA9F1ED);
//even index, selected or not selected
if (row % 2 == 0)
{
if (column % 2 == 0)
c.setBackground(PRIMARY_ROW_COLOR.darker());
else
c.setBackground(PRIMARY_ROW_COLOR);
}
else
{
if (column % 2 == 0)
c.setBackground(ALTERNATE_ROW_COLOR.darker());
else
c.setBackground(ALTERNATE_ROW_COLOR);
}
}
return c;
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getTableHeader().setReorderingAllowed(false);
JList rowHeader = new JList(cols);
rowHeader.setCellRenderer(new RowHeaderRenderer(table));
//Lets Place the new table in a Scroll Pane Since there could be alot of data.
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setRowHeaderView(rowHeader);
getContentPane().add(scrollPane, BorderLayout.CENTER);
//Now lets Build the Cell Editors
int c = 0;
int r = 0;
for(Iterator<Membership> a = _Memberships.iterator(); a.hasNext();)
{
Membership top = a.next();
EachRowEditor rowEditor = new EachRowEditor(table);
for(Iterator<Membership> b = _Memberships.iterator(); b.hasNext();)
{
Membership side = b.next();
if (side.getId() == top.getId() && (side.isEft() && top.isEft()))
{
//rowEditor.setEditorAt(r, null);
}
else if (side.getId() != top.getId() && (side.isEft() && top.isEft()))
{
NuhpadxCell t = new NuhpadxCell(side, top, new DefaultComboBoxModel(new String[] {"N", "U", "D", "A"}));
t.setSelectedItem(NUHPADX(side.getId(), top.getId()));
rowEditor.setEditorAt(r, new DefaultCellEditor(t));
}
else
{
NuhpadxCell t = new NuhpadxCell(side, top, new DefaultComboBoxModel(new String[] {"N", "A", "H", "X", "P"}));
t.setSelectedItem(NUHPADX(side.getId(), top.getId()));
rowEditor.setEditorAt(r, new DefaultCellEditor(t));
}
r++;
}
table.getColumn(top.getMembership()).setCellEditor(rowEditor);
table.revalidate();
c++;
}
table.removeColumn(table.getColumn("NONE"));
//*******************************************************
// Ends Copy and paste from Program
//*******************************************************
setSize(1060, 600);
setVisible(true);
}
//This function jsut simluates a entire class
public String NUHPADX(int side, int top)
{
Random generator = new Random();
int roll = generator.nextInt(7);
switch (roll)
{
case 0:
return "N";
case 1:
return "U";
case 2:
return "H";
case 3:
return "P";
case 4:
return "A";
case 5:
return "P";
case 6:
return "A";
default:
return "N";
}
}
public static void main(String[] args) {
EachRowEditorExample frame = new EachRowEditorExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
//Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1.1) */
class EachRowEditor implements TableCellEditor {
protected Hashtable editors;
protected TableCellEditor editor, defaultEditor;
JTable table;
/**
* Constructs a EachRowEditor. create default editor
*
* @see TableCellEditor
* @see DefaultCellEditor
*/
public EachRowEditor(JTable table) {
this.table = table;
editors = new Hashtable();
defaultEditor = new DefaultCellEditor(new JTextField());
}
/**
* @param row
* table row
* @param editor
* table cell editor
*/
public void setEditorAt(int row, TableCellEditor editor) {
editors.put(new Integer(row), editor);
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
editor = (TableCellEditor) editors.get(new Integer(row));
if (editor == null) {
editor = defaultEditor;
}
return editor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
public Object getCellEditorValue() {
return editor.getCellEditorValue();
}
public boolean stopCellEditing() {
return editor.stopCellEditing();
}
public void cancelCellEditing() {
editor.cancelCellEditing();
}
public boolean isCellEditable(EventObject anEvent) {
selectEditor((MouseEvent) anEvent);
return editor.isCellEditable(anEvent);
}
public void addCellEditorListener(CellEditorListener l) {
editor.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l) {
editor.removeCellEditorListener(l);
}
public boolean shouldSelectCell(EventObject anEvent) {
selectEditor((MouseEvent) anEvent);
return editor.shouldSelectCell(anEvent);
}
protected void selectEditor(MouseEvent e) {
int row;
if (e == null) {
row = table.getSelectionModel().getAnchorSelectionIndex();
} else {
row = table.rowAtPoint(e.getPoint());
}
editor = (TableCellEditor)editors.get(new Integer(row));
if (editor == null) {
editor = defaultEditor;
}
}
}
//*******************************************************
// Starts Copy and paste from Program
//*******************************************************
class RowHeaderRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 4619707414623897299L;
public RowHeaderRenderer(JTable table) {
JTableHeader header = table.getTableHeader();
setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(CENTER);
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText((value == null) ? "" : value.toString());
return this;
}
}
class NuhpadxCell extends JComboBox {
private static final long serialVersionUID = -4464709511574911230L;
private Membership _side;
private Membership _top;
public NuhpadxCell(Membership s, Membership t, DefaultComboBoxModel aModel)
{
_side = s;
_top = t;
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
DoUpdate();
}
});
setModel(aModel);
}
private void DoUpdate() {
// I would then update my database useing the ID of the side and top memberships as keys.
}
}
//*******************************************************
// Ends Copy and paste from Program
//*******************************************************
//A bare Skeleton of the membership class needed to run this code.
class Membership {
protected int id;
protected String membership;
protected boolean eft;
public int getId() {
return id;
}
public void setId(int value) {
this.id = value;
}
public String getMembership() {
return membership;
}
public void setMembership(String value) {
this.membership = value;
}
public boolean isEft() {
return eft;
}
public void setEft(boolean value) {
this.eft = value;
}
}
1.issue came from code line, 1.问题来自代码行,
table.removeColumn(table.getColumn("NONE"));
2.then JTables view
returns different column index
as are stored into TableModel
, you have to call table.convertColumnIndexToModel()
in the prepareRenderer
and Editor
too 2.然后
JTables view
返回存储在TableModel
不同column index
,您也必须在prepareRenderer
和Editor
调用table.convertColumnIndexToModel()
3.remove isCellXxx
from JTable
to the Model
ei 3.将
isCellXxx
从JTable
isCellXxx
到Model
ei
DataModel = new DefaultTableModel(rows, cols) {
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
Object t = getValueAt(rowIndex, rowIndex);
if (t == null) {
return false;
} else {
return true;
}
}
};
4.call table.setPreferredScrollableViewportSize(table.getPreferredSize());
4.调用
table.setPreferredScrollableViewportSize(table.getPreferredSize());
then you can to change setSize(1060, 600);
然后您可以更改
setSize(1060, 600);
to pack();
pack();
5.add there setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
5.在其中添加
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
too 太
6.don't extends JFrame
, create an local variable 6.不要扩展
JFrame
,创建局部变量
7.then your main class should be including InitialThread
7,那么你的主类应该包括
InitialThread
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
EachRowEditorExample frame = new EachRowEditorExample();
}
});
}
EDIT 编辑
1, I just wanted to hide that column not actually completely remove it from the Model, which is what that code should be doing (according to Java Docs).
1,我只是想隐藏该列,而实际上并没有完全将其从Model中删除,这正是该代码应该执行的操作(根据Java Docs)。
table.removeColumn(table.getColumn("NONE"));
remove concrete Column
only from JTables View
more in the API
and JTables tutorial
, this Column
is still presents in the XxxTableModel
, better would be to test that on your side 仅从
JTables View
删除具体的Column
在API
和JTables tutorial
JTables View
更多内容 ,该Column
仍存在于XxxTableModel
,最好是在您这一边进行测试
as for 2, not sure why that really applies.
至于2,不确定为什么真的适用。
this is already answered, more is described in the JTable tutorial (read the next section too) 这已经得到解答, JTable教程中对此进行了更多描述(也请阅读下一节)
Your solution seems awfully complicated for something that looks quite simple. 对于看起来很简单的问题,您的解决方案似乎非常复杂。 You actually only have two different CellEditor which are both based on a JComboBox.
实际上,您只有两个不同的CellEditor,它们都基于JComboBox。
So, a simpler solution would be to extend DefaultCellEditor
with a JComboBox
and override getTableCellEditorComponent(), depending on which row you are on, you update the JComboBox
with the appropriate model and you return the call to super
. 因此,一个更简单的解决方案是使用
JComboBox
扩展DefaultCellEditor
并重写getTableCellEditorComponent(),具体取决于您所在的行,使用适当的模型更新JComboBox
并将调用返回给super
。
Eventually, you set this cell editor on all your columns of the table. 最终,您在表格的所有列上都设置了该单元格编辑器。
Also consider following Java coding conventions (variables and methods starts with a lower case letter, classes starts with an upper case letter, etc...) 还请考虑遵循以下Java编码约定(变量和方法以小写字母开头,类以大写字母开头,等等。)
EDIT: 编辑:
class MyTableCellEditor extends DefaultCellEditor {
private DefaultCellEditor defaultEditor;
private DefaultComboBoxModel nudaModel = new DefaultComboBoxModel(new String[] { "N", "U", "D", "A" });
private DefaultComboBoxModel nahxpModel = new DefaultComboBoxModel(new String[] { "N", "A", "H", "X", "P" });
public MyTableCellEditor() {
super(new JComboBox());
defaultEditor = new DefaultCellEditor(new JTextField());
}
private JComboBox getComboBox() {
return (JComboBox) editorComponent;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
Membership top = _Memberships.get(column);
Membership side = _Memberships.get(row);
if (side.getId() == top.getId() && side.isEft() && top.isEft()) {
return defaultEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
} else if (side.getId() != top.getId() && side.isEft() && top.isEft()) {
getComboBox().setModel(nudaModel);
} else {
getComboBox().setModel(nahxpModel);
}
return super.getTableCellEditorComponent(table, NUHPADX(side.getId(), top.getId()), isSelected, row, column);
}
}
And here is implementation of what your TableModel could look like: 这是TableModel看起来的实现:
class MyDataModel extends AbstractTableModel{
@Override
public int getRowCount() {
return _Memberships.size();
}
@Override
public int getColumnCount() {
return _Memberships.size();
}
@Override
public String getColumnName(int column) {
// Here feel free to return the appropriate column names.
return super.getColumnName(column);
}
@Override
public Object getValueAt(int row, int column) {
return NUHPADX(_Memberships.get(row).getId(), _Memberships.get(column).getId());
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
// Here you can do whatever you want to say that is editable or not
// If it is editable, you need to override setValueAt
return true;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
// Here you need to implement the update of your model
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.