JTable 标题中的多个可编辑行

2022-01-11 00:00:00 header java swing jtable

我需要在 JTable 标题中有多个可编辑的行,以便同一个标题列可以同时包含 JTextField 和 JButton.

我已经找到了如何实现可编辑的标题单元格以及如何拆分标题单元格.然而事实证明,这些方法有些不同,我需要将它们融合在一起.

是否已经开发了多个可编辑的 JTable 标题行解决方案,这样我就不需要重新发明自行车了?

<小时>

到目前为止我发现了什么:

<小时>

可编辑的标题行代码取自:

代码:列组类:

import java.util.*;导入 java.awt.*;导入 javax.swing.*;导入 javax.swing.table.*;/*** 列组** @版本 1.0 10/20/98* @作者 Nobuo Tamemasa*/类列组 {受保护的 TableCellRenderer 渲染器;受保护的向量 v;受保护的字符串文本;受保护的int边距=0;公共列组(字符串文本){这(空,文本);}公共列组(TableCellRenderer 渲染器,字符串文本){if (renderer == null) {this.renderer = new DefaultTableCellRenderer() {公共组件 getTableCellRendererComponent(JTable 表,对象值,布尔 isSelected,布尔 hasFocus,int 行,int 列){JTableHeader header = table.getTableHeader();如果(标题!= null){setForeground(header.getForeground());setBackground(header.getBackground());setFont(header.getFont());}setHorizo​​ntalAlignment(JLabel.CENTER);setText((value == null) ? "" : value.toString());setBorder(UIManager.getBorder("TableHeader.cellBorder"));返回这个;}};} 别的 {this.renderer = 渲染器;}this.text = 文本;v = 新向量();}/*** @param obj TableColumn 或 ColumnGroup*/公共无效添加(对象 obj){如果(obj == null){返回;}v.addElement(obj);/*if(obj instanceof JTextField) {this.setHeaderRenderer(渲染器)}*/}/*** @param c 表列* @param v 列组*/公共向量getColumnGroups(表列c,向量g){g.addElement(this);if (v.contains(c)) 返回 g;枚举 e = v.elements();而(e.hasMoreElements()){对象 obj = e.nextElement();if (obj instanceof ColumnGroup) {向量组 =(Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone());if (groups != null) 返回组;}}返回空值;}公共 TableCellRenderer getHeaderRenderer() {返回渲染器;}公共无效 setHeaderRenderer(TableCellRenderer 渲染器){如果(渲染器!= null){this.renderer = 渲染器;}}公共对象 getHeaderValue() {返回文本;}公共维度getSize(JTable表){组件 comp = renderer.getTableCellRendererComponent(表,getHeaderValue(),假,假,-1,-1);int height = comp.getPreferredSize().height;整数宽度 = 0;枚举 e = v.elements();而(e.hasMoreElements()){对象 obj = e.nextElement();if (obj instanceof TableColumn) {TableColumn aColumn = (TableColumn)obj;宽度 += aColumn.getWidth();//宽度+=边距;} 别的 {宽度 += ((ColumnGroup)obj).getSize(table).width;}}返回新维度(宽度,高度);}公共无效 setColumnMargin(int 边距) {this.margin = 边距;枚举 e = v.elements();而(e.hasMoreElements()){对象 obj = e.nextElement();if (obj instanceof ColumnGroup) {((ColumnGroup)obj).setColumnMargin(margin);}}}

GroupableHeader 示例

import java.awt.*;导入 java.awt.event.*;导入 javax.swing.*;导入 javax.swing.table.*;/*** @版本 1.0 11/09/98*/公共类 GroupableHeaderExample 扩展 JFrame {GroupableHeaderExample() {super("可分组标题示例");String[] petStrings = { "鸟", "猫", "狗", "兔子", "猪" };JComboBox petList = new JComboBox(petStrings);DefaultTableModel dm = new DefaultTableModel();dm.setDataVector(新对象[][]{{"foo","ja"},{"bar","en"}},new Object[]{new JTextField(), petList});//"输入框","组合框"});JTable 表 = 新 JTable( dm ) {受保护的 JTableHeader createDefaultTableHeader() {返回新的 GroupableTableHeader(columnModel);}};TableColumnModel cm = table.getColumnModel();ColumnGroup g_name = new ColumnGroup("Title1");g_name.add(cm.getColumn(0));//g_name.add(cm.getColumn(1));ColumnGroup g_lang = new ColumnGroup("Title2");g_lang.add(cm.getColumn(1));/*ColumnGroup g_other = new ColumnGroup("Others");g_other.add(cm.getColumn(4));g_other.add(cm.getColumn(5));g_lang.add(g_other);*/GroupableTableHeader 标头 = (GroupableTableHeader)table.getTableHeader();header.addColumnGroup(g_name);header.addColumnGroup(g_lang);JScrollPane 滚动 = 新 JScrollPane( 表 );getContentPane().add(滚动);设置尺寸(400、120);}公共静态无效主要(字符串[]参数){GroupableHeaderExample 框架 = new GroupableHeaderExample();frame.addWindowListener(new WindowAdapter() {公共无效窗口关闭(WindowEvent e){System.exit(0);}});frame.setVisible(true);}}

GroupableTableHeader 类

import java.util.*;导入 java.awt.*;导入 javax.swing.*;导入 javax.swing.table.*;/*** 分组表头** @版本 1.0 10/20/98* @作者 Nobuo Tamemasa*/公共类 GroupableTableHeader 扩展 JTableHeader {私有静态最终字符串 uiClassID = "GroupableTableHeaderUI";受保护的向量 columnGroups = null;公共 GroupableTableHeader(TableColumnModel 模型) {超级(模型);setUI(new GroupableTableHeaderUI());setReorderingAllowed(false);}公共无效更新UI(){setUI(new GroupableTableHeaderUI());}公共无效 setReorderingAllowed(boolean b) {重新排序允许 = 假;}公共无效 addColumnGroup(ColumnGroup g) {if (columnGroups == null) {columnGroups = 新向量();}columnGroups.addElement(g);}公共枚举 getColumnGroups(TableColumn col) {if (columnGroups == null) 返回空值;枚举 e = columnGroups.elements();而(e.hasMoreElements()){ColumnGroup cGroup = (ColumnGroup)e.nextElement();向量 v_ret = (Vector)cGroup.getColumnGroups(col,new Vector());如果(v_ret!= null){返回 v_ret.elements();}}返回空值;}公共无效 setColumnMargin() {if (columnGroups == null) 返回;int columnMargin = getColumnModel().getColumnMargin();枚举 e = columnGroups.elements();而(e.hasMoreElements()){ColumnGroup cGroup = (ColumnGroup)e.nextElement();cGroup.setColumnMargin(columnMargin);}}}

GroupableTableHeaderUI 类

import java.util.*;导入 java.awt.*;导入 javax.swing.*;导入 javax.swing.border.*;导入 javax.swing.table.*;导入 javax.swing.plaf.basic.*;公共类 GroupableTableHeaderUI 扩展 BasicTableHeaderUI {公共无效油漆(图形g,JComponent c){矩形clipBounds = g.getClipBounds();if (header.getColumnModel() == null) 返回;((GroupableTableHeader)header).setColumnMargin();整数列 = 0;维度大小 = header.getSize();矩形 cellRect = new Rectangle(0, 0, size.width, size.height);哈希表 h = new Hashtable();int columnMargin = header.getColumnModel().getColumnMargin();枚举 enumeration = header.getColumnModel().getColumns();而(枚举.hasMoreElements()){cellRect.height = size.height;单元格矩形.y = 0;TableColumn aColumn = (TableColumn)enumeration.nextElement();枚举 cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn);如果(cGroups!= null){整数组高度 = 0;而(cGroups.hasMoreElements()){ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement();矩形 groupRect = (矩形)h.get(cGroup);if (groupRect == null) {groupRect = 新矩形(cellRect);维度 d = cGroup.getSize(header.getTable());groupRect.width = d.width;groupRect.height = d.height;h.put(cGroup, groupRect);}paintCell(g, groupRect, cGroup);groupHeight += groupRect.height;cellRect.height = size.height - groupHeight;cellRect.y = groupHeight;}}cellRect.width = aColumn.getWidth();//+ columnMargin;if (cellRect.intersects(clipBounds)) {paintCell(g, cellRect, 列);}cellRect.x += cellRect.width;列++;}}私人无效paintCell(图形g,矩形cellRect,int columnIndex){TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);TableCellRenderer 渲染器 = aColumn.getHeaderRenderer();//由Java2s.com修改渲染器 = 新的 DefaultTableCellRenderer(){公共组件 getTableCellRendererComponent(JTable 表,对象值,布尔 isSelected,布尔 hasFocus,int 行,int 列){JLabel 标头 = 新的 JLabel();header.setForeground(table.getTableHeader().getForeground());header.setBackground(table.getTableHeader().getBackground());header.setFont(table.getTableHeader().getFont());header.setHorizo​​ntalAlignment(JLabel.CENTER);header.setText(value.toString());header.setBorder(UIManager.getBorder("TableHeader.cellBorder"));返回标头;}};组件 c = renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex);c.setBackground(UIManager.getColor("控件"));rendererPane.add(c);rendererPane.paintComponent(g, c, header, cellRect.x, cellRect.y,单元格矩形宽度,单元格矩形高度,真);}私人无效paintCell(图形g,矩形cellRect,ColumnGroup cGroup){TableCellRenderer 渲染器 = cGroup.getHeaderRenderer();//由Java2s.com修改//if(renderer == null){//     返回 ;//}组件组件 = renderer.getTableCellRendererComponent(header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1);rendererPane.add(组件);rendererPane.paintComponent(g, 组件, header, cellRect.x, cellRect.y,单元格矩形宽度,单元格矩形高度,真);}私人 int getHeaderHeight() {整数高度 = 0;TableColumnModel columnModel = header.getColumnModel();for(int column = 0; column < columnModel.getColumnCount(); column++) {TableColumn aColumn = columnModel.getColumn(column);TableCellRenderer 渲染器 = aColumn.getHeaderRenderer();//由Java2s.com修改如果(渲染器 == 空){返回 40;}组件 comp = renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), false, false,-1, column);int cHeight = comp.getPreferredSize().height;枚举 e = ((GroupableTableHeader)header).getColumnGroups(aColumn);如果(e!= null){而(e.hasMoreElements()){ColumnGroup cGroup = (ColumnGroup)e.nextElement();cHeight += cGroup.getSize(header.getTable()).height;}}高度 = Math.max(高度,cHeight);}返回高度;}私人维度 createHeaderSize(长宽) {TableColumnModel columnModel = header.getColumnModel();宽度 += columnModel.getColumnMargin() * columnModel.getColumnCount();如果(宽度>整数.MAX_VALUE){宽度 = 整数.MAX_VALUE;}返回新维度((int)宽度,getHeaderHeight());}公共维度 getPreferredSize(JComponent c) {长宽 = 0;枚举 enumeration = header.getColumnModel().getColumns();而(枚举.hasMoreElements()){TableColumn aColumn = (TableColumn)enumeration.nextElement();宽度 = 宽度 + aColumn.getPreferredWidth();}返回 createHeaderSize(宽度);}}

解决方案

  • 只是想在JTableHeader中使用TableCellEditor是错误的,也不是multi_line_header,要买Jide(支持)

  • 使用 JTextField 中的 RowFilter 尽可能简单,

  • 注意不要忘记从视图坐标到模型坐标

.

.

import java.awt.*;导入 javax.swing.*;导入 javax.swing.event.*;导入 javax.swing.table.*;//代码基于@camickr 的帖子公共类 TableFilterRow 实现 TableColumnModelListener {私有静态最终长序列版本UID = 1L;私有 JFrame 框架 = new JFrame();私有 JTable 表 = 新 JTable(3, 5);private JScrollPane scrollPane = new JScrollPane(table);//文本字段面板私有 JPanel filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));公共表过滤器行(){table.setPreferredScrollableViewportSize(table.getPreferredSize());table.getColumnModel().addColumnModelListener(this);filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));for (int i = 0; i < table.getColumnCount(); i++) {filterRow.add(new JTextField(" Sum at -" + i));}columnMarginChanged(new ChangeEvent(table.getColumnModel()));frame.add(scrollPane);frame.add(filterRow, BorderLayout.SOUTH);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}//实现 TableColumnModelListener 方法//(注意:你应该能够而不是实现一个监听器//覆盖 JTable 的 columnMarginChanged 和 columMoved 方法)@覆盖公共无效columnMarginChanged(ChangeEvent e){TableColumnModel tcm = table.getColumnModel();int columns = tcm.getColumnCount();for (int i = 0; i < 列; i++) {JTextField textField = (JTextField) filterRow.getComponent(i);维度 d = textField.getPreferredSize();d.width = tcm.getColumn(i).getWidth();textField.setPreferredSize(d);}SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){filterRow.revalidate();}});}@覆盖公共无效列移动(TableColumnModelEvent e){组件已移动 = filterRow.getComponent(e.getFromIndex());filterRow.remove(e.getFromIndex());filterRow.add(移动,e.getToIndex());filterRow.validate();}@覆盖公共无效列添加(TableColumnModelEvent e){}@覆盖公共无效columnRemoved(TableColumnModelEvent e){}@覆盖公共无效columnSelectionChanged(ListSelectionEvent e){}公共静态无效主要(字符串[]参数){SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){TableFilterRow 框架 = 新 TableFilterRow();}});}}

I need to have multiple editable rows in JTable header, so that the same header column could contain both JTextField and JButton.

I have found how to implement editable header cells and how to split header cells. However it turned out that these approaches are somewhat different and I would need to fuse them into one.

Is there any multiple editable JTable header rows solutions which are already developed and so that I wouldn't need to reinvent the bicycle?


What I have found so far:


Editable Header row code taken from: http://www.java2s.com/Code/Java/Swing-Components/EditableHeaderTableExample2.htm

Code:

import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
* @version 1.0 08/22/99
*/
public class EditableHeaderTableExample2 extends JFrame {

public EditableHeaderTableExample2() {
     super("EditableHeader Example");

     JTable table = new JTable(7, 5);
     TableColumnModel columnModel = table.getColumnModel();
     table.setTableHeader(new EditableHeader(columnModel));

     String[] items = { "Dog", "Cat" };
     JComboBox combo = new JComboBox();
     for (int i = 0; i < items.length; i++) {
       combo.addItem(items[i]);
     }
     ComboRenderer renderer = new ComboRenderer(items);

     EditableHeaderTableColumn col;
     // column 1
     col = (EditableHeaderTableColumn) table.getColumnModel().getColumn(1);
     col.setHeaderValue(combo.getItemAt(0));
     col.setHeaderRenderer(renderer);
     col.setHeaderEditor(new DefaultCellEditor(combo));

     // column 3
     col = (EditableHeaderTableColumn) table.getColumnModel().getColumn(3);
     col.setHeaderValue(combo.getItemAt(0));
     //col.setHeaderRenderer(renderer);
     col.setHeaderEditor(new DefaultCellEditor(combo));

     JScrollPane pane = new JScrollPane(table);
     getContentPane().add(pane);
}

class ComboRenderer extends JComboBox implements TableCellRenderer {

     ComboRenderer(String[] items) {
       for (int i = 0; i < items.length; i++) {
         addItem(items[i]);
       }
     }

     public Component getTableCellRendererComponent(JTable table,
         Object value, boolean isSelected, boolean hasFocus, int row,
         int column) {
       setSelectedItem(value);
       return this;
     }
    }

    public static void main(String[] args) {
     EditableHeaderTableExample2 frame = new EditableHeaderTableExample2();
     frame.addWindowListener(new WindowAdapter() {
       public void windowClosing(WindowEvent e) {
         System.exit(0);
       }
     });
     frame.setSize(300, 100);
     frame.setVisible(true);
    }
}

class EditableHeader extends JTableHeader implements CellEditorListener {
    public final int HEADER_ROW = -10;

    transient protected int editingColumn;

    transient protected TableCellEditor cellEditor;

    transient protected Component editorComp;

    public EditableHeader(TableColumnModel columnModel) {
     super(columnModel);
     setReorderingAllowed(false);
     cellEditor = null;
     recreateTableColumn(columnModel);
    }

    public void updateUI() {
     setUI(new EditableHeaderUI());
     resizeAndRepaint();
     invalidate();
    }

    protected void recreateTableColumn(TableColumnModel columnModel) {
     int n = columnModel.getColumnCount();
     EditableHeaderTableColumn[] newCols = new EditableHeaderTableColumn[n];
     TableColumn[] oldCols = new TableColumn[n];
     for (int i = 0; i < n; i++) {
       oldCols[i] = columnModel.getColumn(i);
       newCols[i] = new EditableHeaderTableColumn();
       newCols[i].copyValues(oldCols[i]);
     }
     for (int i = 0; i < n; i++) {
       columnModel.removeColumn(oldCols[i]);
     }
     for (int i = 0; i < n; i++) {
       columnModel.addColumn(newCols[i]);
     }
    }

    public boolean editCellAt(int index) {
     return editCellAt(index);
    }

    public boolean editCellAt(int index, EventObject e) {
     if (cellEditor != null && !cellEditor.stopCellEditing()) {
       return false;
     }
     if (!isCellEditable(index)) {
       return false;
     }
     TableCellEditor editor = getCellEditor(index);

     if (editor != null && editor.isCellEditable(e)) {
       editorComp = prepareEditor(editor, index);
       editorComp.setBounds(getHeaderRect(index));
       add(editorComp);
       editorComp.validate();
       setCellEditor(editor);
       setEditingColumn(index);
       editor.addCellEditorListener(this);

       return true;
     }
     return false;
    }

    public boolean isCellEditable(int index) {
     if (getReorderingAllowed()) {
       return false;
     }
     int columnIndex = columnModel.getColumn(index).getModelIndex();
     EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel
         .getColumn(columnIndex);
     return col.isHeaderEditable();
    }

    public TableCellEditor getCellEditor(int index) {
     int columnIndex = columnModel.getColumn(index).getModelIndex();
     EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel
         .getColumn(columnIndex);
     return col.getHeaderEditor();
    }

    public void setCellEditor(TableCellEditor newEditor) {
     TableCellEditor oldEditor = cellEditor;
     cellEditor = newEditor;

     // firePropertyChange

     if (oldEditor != null && oldEditor instanceof TableCellEditor) {
       ((TableCellEditor) oldEditor)
           .removeCellEditorListener((CellEditorListener) this);
     }
     if (newEditor != null && newEditor instanceof TableCellEditor) {
       ((TableCellEditor) newEditor)
           .addCellEditorListener((CellEditorListener) this);
     }
    }

    public Component prepareEditor(TableCellEditor editor, int index) {
     Object value = columnModel.getColumn(index).getHeaderValue();
     boolean isSelected = true;
     int row = HEADER_ROW;
     JTable table = getTable();
     Component comp = editor.getTableCellEditorComponent(table, value,
         isSelected, row, index);
     if (comp instanceof JComponent) {
        ((JComponent) comp).setNextFocusableComponent(this);
     }
     return comp;
    }

    public TableCellEditor getCellEditor() {
     return cellEditor;
    }

    public Component getEditorComponent() {
     return editorComp;
    }

    public void setEditingColumn(int aColumn) {
     editingColumn = aColumn;
    }

    public int getEditingColumn() {
     return editingColumn;
    }

    public void removeEditor() {
     TableCellEditor editor = getCellEditor();
     if (editor != null) {
       editor.removeCellEditorListener(this);

       requestFocus();
       remove(editorComp);

       int index = getEditingColumn();
       Rectangle cellRect = getHeaderRect(index);

       setCellEditor(null);
       setEditingColumn(-1);
       editorComp = null;

       repaint(cellRect);
     }
    }

    public boolean isEditing() {
     return (cellEditor == null) ? false : true;
    }

    //
    // CellEditorListener
    //
    public void editingStopped(ChangeEvent e) {
     TableCellEditor editor = getCellEditor();
     if (editor != null) {
       Object value = editor.getCellEditorValue();
       int index = getEditingColumn();
       columnModel.getColumn(index).setHeaderValue(value);
       removeEditor();
     }
    }

    public void editingCanceled(ChangeEvent e) {
     removeEditor();
    }

    //
    // public void setReorderingAllowed(boolean b) {
    //   reorderingAllowed = false;
    // }    
}

class EditableHeaderUI extends BasicTableHeaderUI {

    protected MouseInputListener createMouseInputListener() {
     return new MouseInputHandler((EditableHeader) header);
    }

    public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler {
         private Component dispatchComponent;

         protected EditableHeader header;

         public MouseInputHandler(EditableHeader header) {
           this.header = header;
         }

         private void setDispatchComponent(MouseEvent e) {
           Component editorComponent = header.getEditorComponent();
           Point p = e.getPoint();
           Point p2 = SwingUtilities.convertPoint(header, p, editorComponent);
           dispatchComponent = SwingUtilities.getDeepestComponentAt(
               editorComponent, p2.x, p2.y);
         }

         private boolean repostEvent(MouseEvent e) {
           if (dispatchComponent == null) {
             return false;
           }
           MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e,
               dispatchComponent);
           dispatchComponent.dispatchEvent(e2);
           return true;
         }

         public void mousePressed(MouseEvent e) {
           if (!SwingUtilities.isLeftMouseButton(e)) {
             return;
           }
           super.mousePressed(e);

           if (header.getResizingColumn() == null) {
             Point p = e.getPoint();
             TableColumnModel columnModel = header.getColumnModel();
             int index = columnModel.getColumnIndexAtX(p.x);
             if (index != -1) {
               if (header.editCellAt(index, e)) {
                 setDispatchComponent(e);
                 repostEvent(e);
               }
             }
           }
         }

         public void mouseReleased(MouseEvent e) {
           super.mouseReleased(e);
           if (!SwingUtilities.isLeftMouseButton(e)) {
             return;
           }
           repostEvent(e);
           dispatchComponent = null;
         }

    }   

}

class EditableHeaderTableColumn extends TableColumn {

    protected TableCellEditor headerEditor;

    protected boolean isHeaderEditable;

    public EditableHeaderTableColumn() {
     setHeaderEditor(createDefaultHeaderEditor());
     isHeaderEditable = true;
    }

    public void setHeaderEditor(TableCellEditor headerEditor) {
     this.headerEditor = headerEditor;
    }

    public TableCellEditor getHeaderEditor() {
     return headerEditor;
    }

    public void setHeaderEditable(boolean isEditable) {
     isHeaderEditable = isEditable;
    }

    public boolean isHeaderEditable() {
     return isHeaderEditable;
    }

    public void copyValues(TableColumn base) {
     modelIndex = base.getModelIndex();
     identifier = base.getIdentifier();
     width = base.getWidth();
     minWidth = base.getMinWidth();
     setPreferredWidth(base.getPreferredWidth());
     maxWidth = base.getMaxWidth();
     headerRenderer = base.getHeaderRenderer();
     headerValue = base.getHeaderValue();
     cellRenderer = base.getCellRenderer();
     cellEditor = base.getCellEditor();
     isResizable = base.getResizable();
    }

    protected TableCellEditor createDefaultHeaderEditor() {
     return new DefaultCellEditor(new JTextField());
    }

}


Multiple rows in the same JTable header column code (Fixed for java 7) taken from: http://www.java2s.com/Code/Java/Swing-Components/GroupableGroupHeaderExample.htm

Code: Column group class:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;


/**
 * ColumnGroup
 *
 * @version 1.0 10/20/98
 * @author Nobuo Tamemasa
 */

class ColumnGroup {
  protected TableCellRenderer renderer;
  protected Vector v;
  protected String text;
  protected int margin=0;

  public ColumnGroup(String text) {
    this(null,text);
  }

  public ColumnGroup(TableCellRenderer renderer,String text) {
    if (renderer == null) {
      this.renderer = new DefaultTableCellRenderer() {
          public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
             JTableHeader header = table.getTableHeader();
              if (header != null) {
                  setForeground(header.getForeground());
                  setBackground(header.getBackground());
                  setFont(header.getFont());
              }
              setHorizontalAlignment(JLabel.CENTER);
              setText((value == null) ? "" : value.toString());
              setBorder(UIManager.getBorder("TableHeader.cellBorder"));
              return this;
          }
      };
    } else {
      this.renderer = renderer;
    }
    this.text = text;
    v = new Vector();
  }


  /**
   * @param obj    TableColumn or ColumnGroup
   */
  public void add(Object obj) {
    if (obj == null) { return; }
    v.addElement(obj);
    /*if(obj instanceof JTextField) {
        this.setHeaderRenderer(renderer)
    }*/
  }


  /**
   * @param c    TableColumn
   * @param v    ColumnGroups
   */
  public Vector getColumnGroups(TableColumn c, Vector g) {
    g.addElement(this);
    if (v.contains(c)) return g;    
    Enumeration e = v.elements();
    while (e.hasMoreElements()) {
      Object obj = e.nextElement();
      if (obj instanceof ColumnGroup) {
        Vector groups = 
          (Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone());
        if (groups != null) return groups;
      }
    }
    return null;
  }

  public TableCellRenderer getHeaderRenderer() {
    return renderer;
  }

  public void setHeaderRenderer(TableCellRenderer renderer) {
    if (renderer != null) {
       this.renderer = renderer;
    }
  }

  public Object getHeaderValue() {
    return text;
  }

  public Dimension getSize(JTable table) {
    Component comp = renderer.getTableCellRendererComponent(
        table, getHeaderValue(), false, false,-1, -1);
    int height = comp.getPreferredSize().height; 
    int width  = 0;
    Enumeration e = v.elements();
    while (e.hasMoreElements()) {
      Object obj = e.nextElement();
      if (obj instanceof TableColumn) {
        TableColumn aColumn = (TableColumn)obj;
        width += aColumn.getWidth();
        //width += margin;
      } else {
        width += ((ColumnGroup)obj).getSize(table).width;
      }
    }
    return new Dimension(width, height);
  }

  public void setColumnMargin(int margin) {
    this.margin = margin;
    Enumeration e = v.elements();
    while (e.hasMoreElements()) {
      Object obj = e.nextElement();
      if (obj instanceof ColumnGroup) {
         ((ColumnGroup)obj).setColumnMargin(margin);
       }
    }
  }

GroupableHeaderExample

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

/**
 * @version 1.0 11/09/98
 */
public class GroupableHeaderExample extends JFrame {

  GroupableHeaderExample() {
    super( "Groupable Header Example" );

    String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
    JComboBox petList = new JComboBox(petStrings);

    DefaultTableModel dm = new DefaultTableModel();
    dm.setDataVector(new Object[][]{
      {"foo","ja"},
      {"bar","en"}},
    new Object[]{new JTextField(), petList});//"Input box","Combo Box"});

    JTable table = new JTable( dm ) {
      protected JTableHeader createDefaultTableHeader() {
          return new GroupableTableHeader(columnModel);
      }
    };


    TableColumnModel cm = table.getColumnModel();
    ColumnGroup g_name = new ColumnGroup("Title1");
    g_name.add(cm.getColumn(0));
    //g_name.add(cm.getColumn(1));
    ColumnGroup g_lang = new ColumnGroup("Title2");
    g_lang.add(cm.getColumn(1));
    /*ColumnGroup g_other = new ColumnGroup("Others");
    g_other.add(cm.getColumn(4));
    g_other.add(cm.getColumn(5));
    g_lang.add(g_other);*/

    GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader();
    header.addColumnGroup(g_name);
    header.addColumnGroup(g_lang);
    JScrollPane scroll = new JScrollPane( table );
    getContentPane().add( scroll );
    setSize( 400, 120 );   
  }

 public static void main(String[] args) {
    GroupableHeaderExample frame = new GroupableHeaderExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
  System.exit(0);
      }
    });
    frame.setVisible(true);
  }
}

GroupableTableHeader class

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

/**
  * GroupableTableHeader
  *
  * @version 1.0 10/20/98
  * @author Nobuo Tamemasa
  */

public class GroupableTableHeader extends JTableHeader {
  private static final String uiClassID = "GroupableTableHeaderUI";
  protected Vector columnGroups = null;

  public GroupableTableHeader(TableColumnModel model) {
    super(model);
    setUI(new GroupableTableHeaderUI());
    setReorderingAllowed(false);
  }
  public void updateUI(){
   setUI(new GroupableTableHeaderUI());
  }

  public void setReorderingAllowed(boolean b) {
    reorderingAllowed = false;
  }

  public void addColumnGroup(ColumnGroup g) {
    if (columnGroups == null) {
      columnGroups = new Vector();
    }
    columnGroups.addElement(g);
  }

  public Enumeration getColumnGroups(TableColumn col) {
    if (columnGroups == null) return null;
    Enumeration e = columnGroups.elements();
    while (e.hasMoreElements()) {
      ColumnGroup cGroup = (ColumnGroup)e.nextElement();
      Vector v_ret = (Vector)cGroup.getColumnGroups(col,new Vector());
      if (v_ret != null) { 
  return v_ret.elements();
      }
    }
    return null;
  }

  public void setColumnMargin() {
    if (columnGroups == null) return;
    int columnMargin = getColumnModel().getColumnMargin();
    Enumeration e = columnGroups.elements();
    while (e.hasMoreElements()) {
      ColumnGroup cGroup = (ColumnGroup)e.nextElement();
      cGroup.setColumnMargin(columnMargin);
    }
  }

}

GroupableTableHeaderUI class

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;

public class GroupableTableHeaderUI extends BasicTableHeaderUI {

  public void paint(Graphics g, JComponent c) {
    Rectangle clipBounds = g.getClipBounds();
    if (header.getColumnModel() == null) return;
    ((GroupableTableHeader)header).setColumnMargin();
    int column = 0;
    Dimension size = header.getSize();
    Rectangle cellRect  = new Rectangle(0, 0, size.width, size.height);
    Hashtable h = new Hashtable();
    int columnMargin = header.getColumnModel().getColumnMargin();

    Enumeration enumeration = header.getColumnModel().getColumns();
    while (enumeration.hasMoreElements()) {
      cellRect.height = size.height;
      cellRect.y      = 0;
      TableColumn aColumn = (TableColumn)enumeration.nextElement();
      Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn);
      if (cGroups != null) {
        int groupHeight = 0;
        while (cGroups.hasMoreElements()) {
          ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement();
          Rectangle groupRect = (Rectangle)h.get(cGroup);
          if (groupRect == null) {
            groupRect = new Rectangle(cellRect);
            Dimension d = cGroup.getSize(header.getTable());
            groupRect.width  = d.width;
            groupRect.height = d.height;    
            h.put(cGroup, groupRect);
          }
          paintCell(g, groupRect, cGroup);
          groupHeight += groupRect.height;
          cellRect.height = size.height - groupHeight;
          cellRect.y      = groupHeight;
        }
      }      
      cellRect.width = aColumn.getWidth();// + columnMargin;
      if (cellRect.intersects(clipBounds)) {
        paintCell(g, cellRect, column);
      }
      cellRect.x += cellRect.width;
      column++;
    }
  }

  private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
    TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
    TableCellRenderer renderer = aColumn.getHeaderRenderer();
    //revised by Java2s.com
    renderer = new DefaultTableCellRenderer(){
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          JLabel header = new JLabel();
            header.setForeground(table.getTableHeader().getForeground());
            header.setBackground(table.getTableHeader().getBackground());
            header.setFont(table.getTableHeader().getFont());

          header.setHorizontalAlignment(JLabel.CENTER);
          header.setText(value.toString());
          header.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
            return header;
        }

    };
    Component c = renderer.getTableCellRendererComponent(
        header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex);

        c.setBackground(UIManager.getColor("control"));

    rendererPane.add(c);
    rendererPane.paintComponent(g, c, header, cellRect.x, cellRect.y,
        cellRect.width, cellRect.height, true);
  }

  private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) {
    TableCellRenderer renderer = cGroup.getHeaderRenderer();
      //revised by Java2s.com
     // if(renderer == null){
//      return ;
  //    }

    Component component = renderer.getTableCellRendererComponent(
      header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1);
    rendererPane.add(component);
    rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
        cellRect.width, cellRect.height, true);
  }

  private int getHeaderHeight() {
    int height = 0;
    TableColumnModel columnModel = header.getColumnModel();
    for(int column = 0; column < columnModel.getColumnCount(); column++) {
      TableColumn aColumn = columnModel.getColumn(column);
      TableCellRenderer renderer = aColumn.getHeaderRenderer();
      //revised by Java2s.com
      if(renderer == null){
      return 40;
      }

      Component comp = renderer.getTableCellRendererComponent(
        header.getTable(), aColumn.getHeaderValue(), false, false,-1, column);
      int cHeight = comp.getPreferredSize().height;
      Enumeration e = ((GroupableTableHeader)header).getColumnGroups(aColumn);      
      if (e != null) {
        while (e.hasMoreElements()) {
          ColumnGroup cGroup = (ColumnGroup)e.nextElement();
          cHeight += cGroup.getSize(header.getTable()).height;
        }
      }
      height = Math.max(height, cHeight);
    }
    return height;
  }

  private Dimension createHeaderSize(long width) {
    TableColumnModel columnModel = header.getColumnModel();
    width += columnModel.getColumnMargin() * columnModel.getColumnCount();
    if (width > Integer.MAX_VALUE) {
      width = Integer.MAX_VALUE;
    }
    return new Dimension((int)width, getHeaderHeight());
  }

  public Dimension getPreferredSize(JComponent c) {
    long width = 0;
    Enumeration enumeration = header.getColumnModel().getColumns();
    while (enumeration.hasMoreElements()) {
      TableColumn aColumn = (TableColumn)enumeration.nextElement();
      width = width + aColumn.getPreferredWidth();
    }
    return createHeaderSize(width);
  }
}

解决方案

  • just idea to use TableCellEditor in JTableHeader is wrong, nor multi_line_header, to buy Jide (support)

  • simpler as is possible to use RowFilter from JTextField,

  • note don't forget to convert indexes from view coordinates to model coordinates

.

.

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

//code based on posts by @camickr     

public class TableFilterRow implements TableColumnModelListener {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame();
    private JTable table = new JTable(3, 5);
    private JScrollPane scrollPane = new JScrollPane(table);
    // Panel for text fields
    private JPanel filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));

    public TableFilterRow() {
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.getColumnModel().addColumnModelListener(this);
        filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        for (int i = 0; i < table.getColumnCount(); i++) {
            filterRow.add(new JTextField(" Sum at - " + i));
        }
        columnMarginChanged(new ChangeEvent(table.getColumnModel()));
        frame.add(scrollPane);
        frame.add(filterRow, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

    //  Implement TableColumnModelListener methods
    //  (Note: instead of implementing a listener you should be able to
    //  override the columnMarginChanged and columMoved methods of JTable)
    @Override
    public void columnMarginChanged(ChangeEvent e) {
        TableColumnModel tcm = table.getColumnModel();
        int columns = tcm.getColumnCount();

        for (int i = 0; i < columns; i++) {
            JTextField textField = (JTextField) filterRow.getComponent(i);
            Dimension d = textField.getPreferredSize();
            d.width = tcm.getColumn(i).getWidth();
            textField.setPreferredSize(d);
        }

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                filterRow.revalidate();
            }
        });
    }

    @Override
    public void columnMoved(TableColumnModelEvent e) {
        Component moved = filterRow.getComponent(e.getFromIndex());
        filterRow.remove(e.getFromIndex());
        filterRow.add(moved, e.getToIndex());
        filterRow.validate();
    }

    @Override
    public void columnAdded(TableColumnModelEvent e) {
    }

    @Override
    public void columnRemoved(TableColumnModelEvent e) {
    }

    @Override
    public void columnSelectionChanged(ListSelectionEvent e) {
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TableFilterRow frame = new TableFilterRow();
            }
        });
    }
}

相关文章