我是JTable
的新手。
我使用JPanel制作了自己的自定义渲染器和编辑器。但是,每当我尝试编辑CustomJPanel时,表格单元格都将变为空白。
第二件事是,底部的按钮仅用于显示第二行的控件(JPanel中的滑块和按钮)。但是事实证明,它显示了所有JPanel的控件。
我完整的代码如下:
CustomJTableTest.java
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class CustomJTableTest extends JPanel
{
TableModel customRendererEditorTableModel = new TableModel();
JTable table;
public CustomJTableTest()
{
setLayout(new BorderLayout());
table = new JTable(customRendererEditorTableModel);
table.setRowSelectionAllowed(false);
table.setRowHeight(300);
table.getColumnModel().getColumn(1).setCellRenderer(new CustomJPanelRendererEditor());
table.getColumnModel().getColumn(1).setCellEditor(new CustomJPanelRendererEditor());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
JButton showControl = new JButton("Show Second Row Controls");
showControl.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
TableCellRenderer tableCellRenderer = (CustomJPanelRendererEditor) table.getCellRenderer(1, 1);
java.awt.Component component = table.prepareRenderer(tableCellRenderer, 1, 1);
if (component instanceof CustomJPanel)
{
CustomJPanel customJPanel = (CustomJPanel) component;
customJPanel.setControlsVisible(true);
}
}
});
add(new JScrollPane(showControl), BorderLayout.SOUTH);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Custom JPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new CustomJTableTest();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
CustomJPanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.Color;
public class CustomJPanel extends JPanel
{
JPanel colorPanel = new JPanel(new BorderLayout());
JButton jButton = new JButton("Button inside CustomPanel");
JSlider jSlider = new JSlider(JSlider.VERTICAL);
public CustomJPanel()
{
setLayout(new BorderLayout());
setSize(new Dimension(5, 300));
setBackground(Color.BLACK);
add(colorPanel, BorderLayout.CENTER);
add(jButton, BorderLayout.SOUTH);
add(jSlider, BorderLayout.EAST);
jSlider.setVisible(false);
jButton.setVisible(false);
}
public void setControlsVisible(boolean visible)
{
jSlider.setVisible(visible);
jButton.setVisible(visible);
repaint();
revalidate();
}
}
CustomerJPanelRendererEditor.java
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class CustomJPanelRendererEditor extends AbstractCellEditor implements TableCellRenderer, TableCellEditor
{
CustomJPanel customJPanel = new CustomJPanel();
@Override
public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
return customJPanel;
}
@Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
return customJPanel;
}
@Override
public Object getCellEditorValue()
{
return null;
}
}
TableModel.java
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel
{
private String[] columnNames =
{
"First Column",
"Custom JPanel",
};
private Object[][] data =
{
{"Foo", new CustomJPanel()},
{"Bar", new CustomJPanel()}
};
public int getColumnCount()
{
return columnNames.length;
}
public int getRowCount()
{
return data.length;
}
public String getColumnName(int col)
{
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col)
{
return col >= 1;
}
public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
有人知道怎么了吗?
谢谢。对不起我的英语不好。
更新:
我很傻我改变了
TableCellRenderer tableCellRenderer = (CustomJPanelRendererEditor) table.getCellRenderer(1, 1);
java.awt.Component component = table.prepareRenderer(tableCellRenderer, 1, 1);
至
TableCellEditor tableCellEditor = (CustomJPanelRendererEditor) table.getCellEditor(1, 1);
java.awt.Component component = table.prepareEditor(tableCellEditor, 1, 1);
在CustomJTableTest.java中。滑块和按钮现在可以使用了。请参见GIF。
现在我的问题是CustomJPanel仅在单击该单元格时显示。以及如何仅为特定单元格打开按钮和滑块的可见性?
谢谢。
最佳答案
我以某种方式设法解决了它。感谢@Oliver Watkins的帮助。
作为我的修正的摘要,我添加了
getTableCellRendererComponent()和getTableCellEditorComponent()的rendererJPanel = (CustomJPanel) value;
填写代码:
CustomJTableTest.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class CustomJTableTest extends JPanel
{
TableModel customRendererEditorTableModel = new TableModel();
JTable table;
public CustomJTableTest()
{
setLayout(new BorderLayout());
table = new JTable(customRendererEditorTableModel);
table.setPreferredScrollableViewportSize(new Dimension(500, 600));
table.setRowSelectionAllowed(false);
table.setRowHeight(300);
table.getColumn("Custom JPanel").setCellRenderer(new CustomJPanelRenderer());
table.getColumn("Custom JPanel").setCellEditor(new CustomJPanelEditor());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
JButton showControl = new JButton("Show Controls");
showControl.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// row 2
TableCellEditor tableCellEditor = table.getColumnModel().getColumn(1).getCellEditor();
java.awt.Component component = table.prepareEditor(tableCellEditor, 1, 1);
if (component instanceof CustomJPanel)
{
CustomJPanel customJPanel = (CustomJPanel) component;
customJPanel.setControlsVisible(true);
}
// row 1
java.awt.Component component2 = table.prepareEditor(tableCellEditor, 0, 1);
if (component2 instanceof CustomJPanel)
{
CustomJPanel customJPanel = (CustomJPanel) component2;
customJPanel.setControlsVisible(true);
}
customRendererEditorTableModel.fireTableDataChanged();
}
});
add(new JScrollPane(showControl), BorderLayout.SOUTH);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Custom JPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new CustomJTableTest();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
CustomJPanel.java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class CustomJPanel extends JPanel
{
JPanel colorPanel = new JPanel(new BorderLayout());
JButton jButton = new JButton("Change Color");
JSlider jSlider = new JSlider(JSlider.VERTICAL);
public CustomJPanel()
{
jButton.setOpaque(true);
jButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(4);
switch (randomInt)
{
case (0):
colorPanel.setBackground(Color.BLUE);
break;
case (1):
colorPanel.setBackground(Color.BLACK);
break;
case (2):
colorPanel.setBackground(Color.CYAN);
break;
default:
colorPanel.setBackground(Color.GREEN);
break;
}
}
});
jSlider.setOpaque(true);
setLayout(new BorderLayout());
add(colorPanel, BorderLayout.CENTER);
add(jButton, BorderLayout.SOUTH);
add(jSlider, BorderLayout.EAST);
jSlider.setVisible(false);
jButton.setVisible(false);
}
public void setControlsVisible(boolean visible)
{
jSlider.setVisible(visible);
jButton.setVisible(visible);
}
}
客户JPanelRenderer
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class CustomJPanelRenderer implements TableCellRenderer
{
CustomJPanel rendererJPanel;
public CustomJPanelRenderer()
{
rendererJPanel = new CustomJPanel();
}
@Override
public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
rendererJPanel = (CustomJPanel) value;
return rendererJPanel;
}
}
CustomJPanelEditor.java
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class CustomJPanelEditor extends AbstractCellEditor implements TableCellEditor
{
CustomJPanel customJPanel;
public CustomJPanelEditor()
{
customJPanel = new CustomJPanel();
}
@Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
customJPanel = (CustomJPanel) value;
return customJPanel;
}
@Override
public Object getCellEditorValue()
{
return customJPanel;
}
}
TableModel.java
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel
{
private String[] columnNames =
{
"First Column",
"Custom JPanel",
};
private Object[][] data =
{
{"Foo", new CustomJPanel()},
{"Bar", new CustomJPanel()}
};
public int getColumnCount()
{
return columnNames.length;
}
public int getRowCount()
{
return data.length;
}
public String getColumnName(int col)
{
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col)
{
return col >= 1;
}
public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}