这可能是一个模糊的查询,所以请原谅我。
自定义JTable(我修改了查询并将根据提供的SSCCE进行讨论)。我将创建一个JTable,根据JTable中选中的复选框提供授权
此JTable的目的是向用户显示应用程序的所有菜单选项。这个JTable有三列: 第一栏:Bollean类(复选框) 第二列:类String(主菜单项) 第三列:类String(子菜单项)
要提供授权,用户应选择与子菜单项对应的复选框,最后选择“授权”按钮(由于我的授权功能正常,我没有包含授权按钮)
现在UI要求是在JTable的第一列中,我应该只显示与子菜单项对应的复选框,而不是在第一列的每个单元格中显示复选框(换句话说,它不应该显示与主菜单对应的复选框)菜单项)
下面的图片是预期输出(虽然我的第一列中的所有单元格都带有复选框)
public class SwingSolution extends JPanel {
public SwingSolution() {
super(new GridLayout(1,0));
String[] columnNames = {"", "Main Menu", "Sub Menu"};
Object[][] data = {
{false, "File", ""},
{false, "", "New"},
{false, "", "Save"},
{false, "", "Close"},
{false, "Edit", ""},
{false, "", "Delete"},
{false, "", "Format"},
{false, "Project", ""},
{false, "", "Create New"},
{false, "", "Delete"},
{false, "", "Build"},
{false, "", "Properties"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
final JTable table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
switch (column) {
case 0:
return Boolean.class;
case 1:
return String.class;
case 2:
return String.class;
default:
return Boolean.class;
}
}
};
table.getColumnModel().getColumn(0).setMaxWidth(30);
table.getColumnModel().getColumn(1).setMaxWidth(100);
table.getColumnModel().getColumn(2).setMaxWidth(120);
table.setPreferredScrollableViewportSize(new Dimension(250, 195));
table.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
SwingSolution newContentPane = new SwingSolution();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
我尝试使用单元格渲染器进行各种操作,并使用google搜索JTable和自定义单元格,但无法弄明白。任何帮助将不胜感激
答案 0 :(得分:5)
基本上,你将为你提供细胞渲染器和编辑器。
在这种情况下,我将第一列值/类型更改为int
。这使我能够提供boolean
以外的其他含义。
如果列值为0
,则该单元格不是“可选”,取消选中1
,则会检查2
。
我还修改了isCellEditable
的{{1}}方法,只允许“有效”单元格可编辑。
TableModel
我没有完成编辑,但基本概念是一样的......
答案 1 :(得分:2)
重写getCellRenderer()
方法以返回适当的渲染器。类似的东西:
@Override
public TableCellRenderer getCellRenderer(int row, int column)
{
int modelColumn = convertColumnIndexToView(column);
if (modelColumn == 0 && getValueAt(row, column).equals(""))
return getDefaultRenderer(String.class);
else
return super.getCellRenderer(row, column);
}
您还需要更改模型中的数据:
{"", "File", ""},
最后,您还可以覆盖isCellEditable()
方法,使空单元格不可编辑。
然后,您可以使用默认的布尔渲染器/编辑器来显示列中的其他行。
答案 2 :(得分:2)
您可以使用Boolean
包装类而不是原始类型编写自己的TableCellRenderer
并覆盖getTableCellRendererComponent(..)
方法。
public class CustomTableCellRenderer extends DefaultTableCellRenderer
{
public CustomTableCellRenderer()
{
super();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(value instanceof Boolean)
{
if(value != null)
{
JCheckBox jcb = new JCheckBox();
jcb.setSelected((Boolean) value);
return jcb;
}
return new JPanel();
}
return this;
}
}
然后只需设置infos.setDefaultRenderer(Boolean.class, new CustomTableCellRenderer());
并使用new Boolean(true)
替换数组中的原始类型。如果您不想拥有JCeckBox
,则会显示null
而不是Boolean
,并且会显示空的JPanel
。