请教高手!!! 谢谢

解决方案 »

  1.   

    自己实现TableHeader,其实就是自己用paint()去画这样的表头,
      

  2.   

    对不起,我说错了,其实是应该自己实现DefaultTableCellRenderer这个类的
      

  3.   


    public class MultiColTableHeader { public static void main(String[] args) {
    JFrame frame = new JFrame("Test Table Header");
    JTable table = new JTable(3,6);
    CustomTableHeaderUI ui = new CustomTableHeaderUI();
    table.getTableHeader().setUI(ui);
    TableRender render = new TableRender();
    table.getTableHeader().setDefaultRenderer(render);
    JScrollPane pane = new JScrollPane(table);
    frame.setContentPane(pane);
    frame.setPreferredSize(new Dimension(500,500));
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
    }

    }
      

  4.   

    可以啊,table.getTableHeader().setDefaultRenderer(render);
      

  5.   

    小弟不才,临时改了一个,没有画成你要的格式,但是,我想,你可以通过以下的代码,明白,表头是怎么出来的!
    /* (swing1.1beta3) */
    //package jp.gr.java_conf.tame.swing.examples;
    package hzpackage.demo.test.JTable.part03;import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.Enumeration;import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.ListCellRenderer;
    import javax.swing.UIManager;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;/**
     * @version 1.0 11/09/98
     */
    public class MultiLineHeaderExample extends JFrame {
    MultiLineHeaderExample() {
    super("Multi-Line Header Example"); DefaultTableModel dm = new DefaultTableModel();
    dm.setDataVector(new Object[][] { { "a", "b", "c" }, { "A", "B", "C" } }, new Object[] { "1st\nalpha",
    "2nd\nbeta", "3rd\ngamma" }); JTable table = new JTable(dm);
    MultiLineHeaderRenderer renderer = new MultiLineHeaderRenderer();
    Enumeration enumList = table.getColumnModel().getColumns();
    while (enumList.hasMoreElements()) {
    ((TableColumn) enumList.nextElement()).setHeaderRenderer(renderer);
    }
    JScrollPane scroll = new JScrollPane(table);
    getContentPane().add(scroll);
    setSize(400, 110);
    setVisible(true);
    } public class MultiLineHeaderRenderer extends JList implements TableCellRenderer {
    public MultiLineHeaderRenderer() {
    setOpaque(true);
    // setForeground(UIManager.getColor("TableHeader.foreground"));
    // setBackground(UIManager.getColor("TableHeader.background"));
    // setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel) renderer).setHorizontalAlignment(JLabel.CENTER);
    setCellRenderer(renderer);
    } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
    boolean hasFocus, int row, int column) {
    // setFont(table.getFont());
    // String str = (value == null) ? "" : value.toString();
    // BufferedReader br = new BufferedReader(new StringReader(str));
    // String line;
    // Vector v = new Vector();
    // try {
    // while ((line = br.readLine()) != null) {
    // v.addElement(line);
    // }
    // } catch (IOException ex) {
    // ex.printStackTrace();
    // }
    // setListData(v);
    // return this; JPanel panel = new JPanel();
    panel.setPreferredSize(new Dimension(100, 30));
    panel.setSize(new Dimension(100, 30));
    panel.setLayout(new BorderLayout());
    panel.setBorder(UIManager.getBorder("TableHeader.cellBorder")); JLabel label = new JLabel("一级");
    label.setPreferredSize(new Dimension(100, 15));
    label.setHorizontalAlignment(JLabel.CENTER);
    label.setForeground(Color.RED);
    label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    JLabel labe2 = new JLabel("二级");
    labe2.setPreferredSize(new Dimension(100, 15));
    labe2.setHorizontalAlignment(JLabel.CENTER);
    labe2.setForeground(Color.BLUE);
    label.setBorder(BorderFactory.createLineBorder(Color.YELLOW)); panel.add(label, BorderLayout.NORTH);
    panel.add(labe2, BorderLayout.CENTER);
    return panel;
    }
    } public static void main(String[] args) {
    MultiLineHeaderExample frame = new MultiLineHeaderExample();
    frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    }
    }我这里都写死在代码里了,随意画了一个不怎么漂亮的表头!根据实际情况,重写 getTableCellRendererComponent(....) 方法,把列的信息封装进去,就可以在这个方法里任意画了!
      

  6.   

    不过10的朋友,这样的结果貌似不对啊,注意看上面的图片,要求是第1列和第2列结合的,
    你的代码是在每个列模型上创建了一个2曾的panel,但是相邻的两列不能结合
      

  7.   


    public class CustomTableHeaderUI extends BasicTableHeaderUI {
    public void paint(Graphics g, JComponent c) {
         if (header.getColumnModel().getColumnCount() <= 0) { 
             return; 
         }
         int count = header.getColumnModel().getColumnCount();
         int x = 0;
         Rectangle rc = new Rectangle();
        for(int column = 0; column < count ; column++) { 
         TableColumn aColumn = header.getColumnModel().getColumn(column);
         Rectangle cellRect = header.getHeaderRect(column);   
    int columnWidth = aColumn.getWidth();
    cellRect.width = columnWidth;
    if (column%2==1) {
    rc.y =0;
    rc.height=16;
    rc.width = cellRect.width+rc.width;
    paintCell(g, rc, column);
    rc.y=16;
    rc.height=16;
    rc.x=cellRect.x;
    rc.width = rc.width - cellRect.width;
    paintCell(g, rc, column);

    } else {
    rc = new Rectangle(cellRect.x,cellRect.y,cellRect.width,cellRect.height);
    rc.y=16;
    rc.height=16;
    paintCell(g, rc, column);
    }
    x += columnWidth;
        }
        } 
      

  8.   

    公司网关有限制,下面的代码是上面那个类的,    private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
         String value = (String)header.getColumnModel().getColumn(columnIndex).getHeaderValue();
         JLabel label = new JLabel(value);
    label.setPreferredSize(new Dimension(cellRect.width,cellRect.height));
    label.setBorder(BorderFactory.createLineBorder(Color.black));
    label.setHorizontalAlignment(JLabel.CENTER);    
            rendererPane.paintComponent(g, label, header, cellRect.x, cellRect.y,
                                cellRect.width, cellRect.height, true);
        }
    }还有一个TableRender的代码没贴,连续发三贴了估计不能继续贴了,
    谁跟贴后再贴吧,结合我留在3楼的代码,这个例子就能完整的跑起来了
      

  9.   

    楼上的真帅。public class TableRender extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    if (row<0||column!=1)
    return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    else {
    JButton label = new JButton("button");
    label.setPreferredSize(new Dimension(table.getColumnModel().getColumn(column).getPreferredWidth(),20));
    return label;
    }
    }
    }
      

  10.   


    package hzpackage.demo.test;import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Vector;import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.border.Border;
    import javax.swing.plaf.basic.BasicTableHeaderUI;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableColumn;
    import javax.swing.table.TableColumnModel;public class MultiLayerTableHeaderDemo extends JFrame { public MultiLayerTableHeaderDemo() {
    super("多层表头测试");

    DefaultTableModel tableModel = new DefaultTableModel();
    tableModel.setDataVector(new Object[10][10],
        new Object[]{"上午","下午","上午","下午","上午","下午",});
        
    JTable table = new JTable(tableModel); TableColumnModel columnModel = table.getColumnModel();
    MultiLayerTableHeader tableHeader = new MultiLayerTableHeader(columnModel);
    tableHeader.setPreferredSize(new Dimension(tableHeader.getWidth(), 40));

    ColumnGroup columnGroup1 = new ColumnGroup("今天");
    columnGroup1.addTableColumn(columnModel.getColumn(0));
    columnGroup1.addTableColumn(columnModel.getColumn(1));

    ColumnGroup columnGroup2 = new ColumnGroup("明天");
    columnGroup2.addTableColumn(columnModel.getColumn(2));
    columnGroup2.addTableColumn(columnModel.getColumn(3));

    ColumnGroup columnGroup3 = new ColumnGroup("后天");
    columnGroup3.addTableColumn(columnModel.getColumn(4));
    columnGroup3.addTableColumn(columnModel.getColumn(5)); tableHeader.addColumnGroup(columnGroup1);
    tableHeader.addColumnGroup(columnGroup2);
    tableHeader.addColumnGroup(columnGroup3);

    table.setTableHeader(tableHeader);
    JScrollPane pane = new JScrollPane(table); this.setContentPane(pane);
    this.setPreferredSize(new Dimension(500, 500));
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    this.pack();
    this.setVisible(true);
    } public class MultiLayerTableHeaderUI extends BasicTableHeaderUI {
    private int layerHeight = 20;//每一层的高度
    public void paint(Graphics g, JComponent c) {
    if (header.getColumnModel().getColumnCount() <= 0) {
    return;
    } if(header instanceof MultiLayerTableHeader){
    MultiLayerTableHeader multiLayTabHead = (MultiLayerTableHeader)header;
    this.layerHeight = multiLayTabHead.getLayerHeight();//每一层的高度
    paintMultiLayerTableHeader(multiLayTabHead, g);
    }else{
    //默认的表头
    int count = header.getColumnModel().getColumnCount();
    TableColumn column;
    String text;
    for (int indexCol = 0; indexCol < count; indexCol++) {
    column = header.getColumnModel().getColumn(indexCol);
    text = (String)column.getHeaderValue();

    Rectangle cellRect = header.getHeaderRect(indexCol);
    paintCell(g, cellRect, text);
    }
    }
    }

    private void paintMultiLayerTableHeader(MultiLayerTableHeader multiLayTabHead, Graphics g){
    Vector columnGroupsVector = multiLayTabHead.getColumnGroups();

    int maxLayers = 1;//表头的层数
    Map columnMap = new HashMap();//被群组的列 的集合
    if(null != columnGroupsVector && columnGroupsVector.size() > 0){
    for(int k = 0; k < columnGroupsVector.size(); k++){
    Object obj = columnGroupsVector.get(k);
    if(obj instanceof ColumnGroup){
    ColumnGroup columnGroup = (ColumnGroup)obj;
    maxLayers = Math.max(maxLayers, columnGroup.getLayers());
    columnMap.putAll(columnGroup.getColumnsMap());
    }
    }
    }

    int count = header.getColumnModel().getColumnCount();
    TableColumn tableColumn;
    String text;
    for (int indexCol = 0; indexCol < count; indexCol++) {
    tableColumn = header.getColumnModel().getColumn(indexCol);
    text = (String)tableColumn.getHeaderValue();

    if(columnMap.containsKey(indexCol)){
    //发现有被群组的第一列,去寻找这个群组
    for(int k = 0; k < columnGroupsVector.size(); k++){
    Object obj = columnGroupsVector.get(k);
    if(obj instanceof ColumnGroup){
    ColumnGroup columnGroup = (ColumnGroup)obj;
    if(columnGroup.getColumnsMap().containsKey(indexCol)){
    //这个群组的基础列的 列号集合中 包含 当前列,就认为是找到这个群组了
    paintColumnGroup(columnGroup, maxLayers, g);

    indexCol += columnGroup.getColumnsMap().size() - 1;
    break;
    }
    }
    }

    }else{
    //没有被群组的 单列
    Rectangle cellRect = header.getHeaderRect(indexCol);
    cellRect.y = 0;
    cellRect.height = layerHeight * maxLayers;
    paintCell(g, cellRect, text);
    }
    }
    }

    private void paintColumnGroup(ColumnGroup columnGroup, int maxLayers, Graphics g){
    int currentLayers = columnGroup.getLayers();
    Vector columnGroupVector = columnGroup.getColumnGroupVector();
    ColumnGroup columnGroupSub;
    TableColumn tableColumn;
    String text;
    for(int k = 0; k < columnGroupVector.size(); k++){
    Object obj = columnGroupVector.get(k);
    if(obj instanceof ColumnGroup){
    columnGroupSub = (ColumnGroup)obj;
    paintColumnGroup(columnGroupSub, maxLayers, g);
    }else if(obj instanceof TableColumn){
    tableColumn = (TableColumn)obj;
    int indexCol = tableColumn.getModelIndex();
    text = (String)tableColumn.getHeaderValue();

    Rectangle cellRect = header.getHeaderRect(indexCol);
    cellRect.y = (maxLayers - 1) * this.layerHeight;
    cellRect.height = this.layerHeight;
    paintCell(g, cellRect, text);
    }
    }

    int leftIndex = columnGroup.getLeftmostColumnIndex();//群组最左边一列的 列号
    Rectangle cellRect = header.getHeaderRect(leftIndex);//主要是用这个列的X坐标
    if(columnGroup.isTopLayer()){
    //如果是最上面一层的群组
    cellRect.y = 0;
    cellRect.height = this.layerHeight + (maxLayers - currentLayers) * this.layerHeight;
    }else{
    cellRect.y = (maxLayers - currentLayers) * this.layerHeight;
    cellRect.height = this.layerHeight;
    }
    cellRect.width = columnGroup.getWidth();
    paintCell(g, cellRect, columnGroup.getColumnGroupText());
    } private void paintCell(Graphics g, Rectangle cellRect, String text) {
    JLabel label = new JLabel(text);
    label.setPreferredSize(new Dimension(cellRect.width, 30));
    label.setBorder((Border) UIManager.get("TableHeader.cellBorder"));
    label.setHorizontalAlignment(JLabel.CENTER);
    rendererPane.paintComponent(g, label, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); // System.out.println("第"+(columnIndex+1)+"列:cellRect:"+cellRect);
    }
    }
      

  11.   


    public class ColumnGroup {
    private Vector columnVector;
    private String text;
    private Map columnsMap;//这个 列的群组 所包含的 基础列 的列号集合
    private boolean isTopLayer = false;//是不是最上面一层的群组 public ColumnGroup(String text) {
    this.text = text;
    } /**
     * 添加基础列
     * @param tableColumn
     */
    public void addTableColumn(TableColumn tableColumn) {
    if (null == columnVector) {
    columnVector = new Vector();
    } columnVector.addElement(tableColumn);

    //添加基础列,列号集合 增加
    if(null == columnsMap){
    columnsMap = new HashMap();
    }
    columnsMap.put(tableColumn.getModelIndex(), tableColumn.getModelIndex());
    }

    /**
     * 添加列的群组
     * @param columnGroup
     */
    public void addColumnGroup(ColumnGroup columnGroup) {
    if (null == columnVector) {
    columnVector = new Vector();
    }

    columnVector.addElement(columnGroup);

    //添加列的群组,列号集合 合并
    // 添加基础列,列号集合 增加
    if(null == columnsMap){
    columnsMap = new HashMap();
    }
    columnsMap.putAll(columnGroup.getColumnsMap());
    }

    /**
     * 返回是否 包含下一级的 群组
     * @return
     */
    public boolean isContainSubColumnGroup(){
    boolean boo = false;
    if(null != columnVector && columnVector.size() > 0){
    for(int k = 0; k < columnVector.size(); k++){
    Object obj = columnVector.get(k);
    if(obj instanceof ColumnGroup){
    return true;
    }
    }
    }else{
    return false;
    }

    return boo;
    }

    /**
     * 返回这个群组的 所有基础列 做左边一列的 列号
     * @return
     */
    public int getLeftmostColumnIndex(){
    int index = 99999;
    if(null != columnVector && columnVector.size() > 0){
    ColumnGroup columnGroupSub;
    TableColumn tableColumn;
    for(int k = 0; k < columnVector.size(); k++){
    Object obj = columnVector.get(k);
    if(obj instanceof ColumnGroup){
    columnGroupSub = (ColumnGroup)obj;
    index = Math.min(index, columnGroupSub.getLeftmostColumnIndex());
    }else if(obj instanceof TableColumn){
    tableColumn = (TableColumn)obj;
    index = Math.min(index, tableColumn.getModelIndex());
    }
    }
    }

    return index;
    }

    public int getWidth(){
    int width = 0;
    if(null != columnVector && columnVector.size() > 0){
    ColumnGroup columnGroupSub;
    TableColumn tableColumn;
    for(int k = 0; k < columnVector.size(); k++){
    Object obj = columnVector.get(k);
    if(obj instanceof ColumnGroup){
    columnGroupSub = (ColumnGroup)obj;
    width += columnGroupSub.getWidth();
    }else if(obj instanceof TableColumn){
    tableColumn = (TableColumn)obj;
    width += tableColumn.getWidth();
    }
    }
    }

    return width;
    }

    public int getLayers(){
    int layers = 1;
    if(null != columnVector && columnVector.size() > 0){
    ColumnGroup columnGroupSub;
    int maxSubLayers = 1;
    for(int k = 0; k < columnVector.size(); k++){
    Object obj = columnVector.get(k);
    if(obj instanceof ColumnGroup){
    columnGroupSub = (ColumnGroup)obj;
    maxSubLayers = Math.max(maxSubLayers, columnGroupSub.getLayers());
    }
    }

    layers += maxSubLayers;
    }

    return layers;
    } public Vector getColumnGroupVector() {
    return this.columnVector;
    }

    public Map getColumnsMap(){
    return this.columnsMap;
    } public String getColumnGroupText() {
    return this.text;
    }

    public boolean isTopLayer() {
    return isTopLayer;
    } public void setTopLayer(boolean isTopLayer) {
    this.isTopLayer = isTopLayer;
    }

    public String toString(){
    return this.text;
    }
    } public class MultiLayerTableHeader extends JTableHeader {
    protected int layerHeight = 20; //默认每一层的高度
    protected int maxLayers = 1;
    protected Vector columnGroups = null; public MultiLayerTableHeader(TableColumnModel model) {
    super(model);
    setUI(new MultiLayerTableHeaderUI());
    setReorderingAllowed(false);//不能移动列
    } public void addColumnGroup(ColumnGroup columnGroup) {
    if (null == columnGroups) {
    columnGroups = new Vector();
    }
    columnGroup.setTopLayer(true);//直接添加在MultiLayerTableHeader中的群组,认为它是最上层的群组
    columnGroups.addElement(columnGroup);
    this.maxLayers = Math.max(this.maxLayers, columnGroup.getLayers());

    super.setPreferredSize(new Dimension(super.getWidth(), this.maxLayers * this.layerHeight));
    }

    public Vector getColumnGroups(){
    return columnGroups;
    } public int getLayerHeight() {
    return layerHeight;
    } public void setLayerHeight(int layerHeight) {
    this.layerHeight = layerHeight;
    }
    } public static void main(String[] args) {
    new MultiLayerTableHeaderDemo();
    }}
      

  12.   

    就是一个多行表头,这个Sun公司网站上有样例代码的,你去查一下。
      

  13.   

    hengxxh 真强啊!
    我找到了更方便的办法,就是导入jide.jar API
    使用NestedTableHeader,TableColumnGroup 两个类 就可以轻松搞定了,哈哈! 
    谢谢各位        NestedTableHeader header = (NestedTableHeader) dataTable.getTableHeader();
            TableColumnGroup inHead = new TableColumnGroup("今天");
            TableColumnModel cm = dataTable.getColumnModel();
            inHead.add(cm.getColumn(0));//上午
            inHead.add(cm.getColumn(1));//下午
            header.addColumnGroup(inHead);