如何在 DefaultTableModel/JTable 中合并单元格?
Posted
技术标签:
【中文标题】如何在 DefaultTableModel/JTable 中合并单元格?【英文标题】:How to merge cell in DefaultTableModel/JTable? 【发布时间】:2014-03-18 09:09:06 【问题描述】:我搜索了很多并得到了这个 Q 的一些答案。但其中许多都提到了给出 404 错误的链接。 我想做这样的表:
java中有什么方法可以解决这个问题吗?
【问题讨论】:
在我的一个项目中,我使用that SpanTable。在另一个我使用来自that SO answer 的组头。试试看。 你应该检查this和/或this。 @Qui 异常在线程“main”java.lang.***Error @QuisetColumnIdentifiers(columnNames);
导致问题
【参考方案1】:
MultiSpanCellTableExample 演示如何通过创建自定义TableUI
来合并单元格。此示例中似乎存在导致***Error
的问题,至少在Java 6 中是这样。要解决此问题,请在AttributiveCellTableModel.setDataVector()
中替换:
setColumnIdentifiers(columnNames);
与:
this.columnIdentifiers = columnNames;
IE:
public void setDataVector(Vector newData, Vector columnNames)
if (newData == null)
throw new IllegalArgumentException(
"setDataVector() - Null parameter");
dataVector = new Vector(0);
// setColumnIdentifiers(columnNames);
this.columnIdentifiers = columnNames;
dataVector = newData;
cellAtt = new DefaultCellAttribute(dataVector.size(),
columnIdentifiers.size());
newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
问题是setColumnIdentifiers
调用setDataVector
从而触发***Error
。修复后,示例如下所示:
JIDE 也有现成的解决方案,不幸的是它不是免费的。例如CellSpanTable
:
【讨论】:
我已经使用 JIDE 多年了。 API 非常丰富,也就是说,如果你负担得起的话。我相信他们可能有学生版。不确定。为 jidesoft 做一个谷歌。【参考方案2】:MultiCellSpanTableExample 很好,但是如果你的表有太多列,它有一个小问题可能会成为一个大问题。正如您在tenorsax 给出的example 中看到的那样,显然每个表格列的宽度都有一个额外的像素。这些额外的像素加起来,使得每一列都比上一列位移更多。
我可以通过替换行来解决这个问题:
cellFrame.width = aColumn.getWidth() + columnMargin;
与:
cellFrame.width = aColumn.getWidth() + columnMargin - 1;
我知道没有人问过,但我希望这对某人有所帮助。 :)
【讨论】:
谢谢!在发现问题之前找到解决方案是最好的!【参考方案3】:使用自定义 TableCellRenderer
import java.awt.Color;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class HeaderRenderer extends DefaultTableCellRenderer
private static final long serialVersionUID = 1L;
TableCellRenderer renderer;
public HeaderRenderer(JTable table)
renderer = table.getTableHeader().getDefaultRenderer();
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col)
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
switch (col)
case 0:
setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, Color.LIGHT_GRAY));
break;
case 1:
setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, Color.LIGHT_GRAY));
break;
default:
setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
break;
return this;
from oracle doc
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class SimpleTableDemo extends JPanel
private static final long serialVersionUID = 1L;
public SimpleTableDemo()
super(new GridLayout(1, 0));
String[] columnNames = "First Name", "Last Name", "Sport", "# of Years", "Vegetarian" ;
Object[][] data = "Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false) , "John", "Doe", "Rowing", new Integer(3), new Boolean(true) , "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) , "Jane", "White", "Speed reading", new Integer(20), new Boolean(true) , "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) ;
JTable table = new JTable(data, columnNames);
TableCellRenderer myRenderer = new HeaderRenderer(table);
table.getTableHeader().setDefaultRenderer(myRenderer);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
private static void createAndShowGUI()
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SimpleTableDemo newContentPane = new SimpleTableDemo();
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();
);
【讨论】:
以上是关于如何在 DefaultTableModel/JTable 中合并单元格?的主要内容,如果未能解决你的问题,请参考以下文章
如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?