我是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才会显示。如何仅为特定单元打开按钮和滑块的可见性?
谢谢。
答案 0 :(得分:0)
不知怎的,我设法解决了它。感谢@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);
}
}
<强> CustomerJPanelRenderer 强>
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);
}
}