现有一个jtable共3列5行   
想实现,第一列是类似树节点可展开(就是treetable)那个样子,   
在展开第一行后(如果是treetable展开后应该是是tree的各个节点)现在想要展开的是一个JPanel,我想在JPanel上再重新实现一个jtable共8列9行,该怎么做啊?   
注:就是表第一个jtable中,一行不分列的嵌入一个面板,初始为隐藏状态,点击第一列有小加号时才能展开看到或是新生成JPanel。   怎么才能跟据一个条件过滤jtree,把没有用节点隐藏或去掉?   我在JIDE的例子中看到有这样的效果,可是太贵,没钱,呵呵   
jide中   
HierarchicalTable这个类是可在一行中嵌套任意组件。   
QuickTreeFilterField这个类可以使用QuickTreeFilterField.setTree(tree);进行过滤jtree。 

解决方案 »

  1.   

    很久很久以前写过一个,好像还有一些问题,你自己改改吧/*
     * 创建日期 2004-4-17
     */
    package nestedtable;import java.awt.Component;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.Rectangle;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;import javax.swing.JComponent;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JViewport;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableModel;public class NestedTable extends JTable {
    protected NestedTableRowHeader rowHeader = null; private int[] holdPlaceRowIndexes = new int[0]; /** 插入的组件到组件所占据的占位行的行号(Integer型)的映射表 */
    private Map<Component, Integer> compRowIndexMap = new HashMap<Component, Integer>(); protected NestedTableModel model; public NestedTable(NestedTableModel model) {
    setModel(new InternalTableModel(model)); this.model = model;
    this.rowHeader = new NestedTableRowHeader(this);
    } @Override
    protected void configureEnclosingScrollPane()
    {
    super.configureEnclosingScrollPane();

    Container p = getParent();
        if (p instanceof JViewport) {
          Container gp = p.getParent();
          if (gp instanceof JScrollPane) {
              JScrollPane scrollPane = (JScrollPane)gp;
              // Make certain we are the viewPort's view and not, for
              // example, the rowHeaderView of the scrollPane -
              // an implementor of fixed columns might do this.
              JViewport viewport = scrollPane.getViewport();
              if (viewport == null || viewport.getView() != this) {
                  return;
              }
              scrollPane.setRowHeaderView(rowHeader);
          }
        }
    }

    /** 判断指定的行是不是一个用来占位的行
     * @param row 行号
     * @return 如果是一个占位行返回true
     */
    public boolean isAHoldPlaceRow(int row) {
    return Arrays.binarySearch(holdPlaceRowIndexes, row) >= 0;
    } /** 添加一个占位行
     * @param rowIndex 占位行的行号
     * @param rowHeight 占位行的高度 */
    public void addHoldPlaceRow(int rowIndex, int rowHeight) {
    int temp[] = new int[holdPlaceRowIndexes.length + 1];
    int insertPos = temp.length - 1;
    boolean f = false;            
    for (int i = 0; i < holdPlaceRowIndexes.length; i++) {
    if (holdPlaceRowIndexes[i] < rowIndex) {
    temp[i] = holdPlaceRowIndexes[i];
    }
    else {
    temp[i+1] = holdPlaceRowIndexes[i] + 1;
    if (f == false) {
    insertPos = i;
    f = true;
    }
    }             
    }
    temp[insertPos] = rowIndex; this.holdPlaceRowIndexes = temp;
    ((InternalTableModel)getModel()).fireTableRowsInserted(rowIndex, rowIndex);
    setRowHeight(rowIndex, rowHeight);
    } /** 删除指定的占位行
     * @param rowIndex 占位行的行号 */
    public void removeHoldPlaceRow(int rowIndex) {
    int temp[] = new int[holdPlaceRowIndexes.length -1];
    for (int i = 0; i < temp.length; i++) {
    if (holdPlaceRowIndexes[i] < rowIndex) {
    temp[i] = holdPlaceRowIndexes[i];
    }
    else {
    temp[i] = holdPlaceRowIndexes[i+1] - 1;
    }
    } this.holdPlaceRowIndexes = temp;
    ((InternalTableModel)getModel()).fireTableRowsDeleted(rowIndex, rowIndex);
    } /** 得到指定的行号在原始表格模型中对应的行号
     * @param rowIndex
     * @return
     */
    protected int convertRowIndex(int rowIndex) {
    int row = Arrays.binarySearch(holdPlaceRowIndexes, rowIndex);
    if (row == -1)
    return rowIndex;
    return rowIndex + row + 1;
    } public void addComponentAfterRow(int row, JComponent comp) {
    int nextRow = row + 1;
    if (isAHoldPlaceRow(nextRow)) {
    throw new IllegalStateException();
    }
    Dimension d = comp.getPreferredSize();
    addHoldPlaceRow(nextRow, d.height);
    compRowIndexMap.put(comp, new Integer(nextRow)); Rectangle cellRect = getCellRect(nextRow, 0, false);
    int compCount = getComponentCount();
    Rectangle rect = new Rectangle();
    Dimension spacing = getIntercellSpacing();
    for (int i = 0; i < compCount; i++) {
    Component c = getComponent(i);
    Integer rowIndex = (Integer) compRowIndexMap.get(c);
    if (rowIndex != null && rowIndex.intValue() > nextRow) {
    c.getBounds(rect);
    rect.y += cellRect.height + spacing.height;
    c.setBounds(rect); 
    compRowIndexMap.put(c, new Integer(rowIndex.intValue() + 1));
    }
    }
    comp.setBounds(0, cellRect.y, getWidth(), cellRect.height);
    add(comp);
    } public void removeComponentAfterRow(int row) {
    int nextRow = row + 1;
    if (!isAHoldPlaceRow(nextRow)) {
    throw new IllegalStateException();
    } int rowHeight = getRowHeight(nextRow);
    removeHoldPlaceRow(nextRow); Rectangle rect = new Rectangle();
    Iterator<Component> iter = compRowIndexMap.keySet().iterator();
    while (iter.hasNext()) {
    Component comp = iter.next();
    Integer rowIndex = compRowIndexMap.get(comp);
    if (rowIndex.intValue() == nextRow) {
    remove(comp);
    iter.remove();
    }
    else if (rowIndex.intValue() > nextRow) {
    compRowIndexMap.put(comp, new Integer(rowIndex.intValue() - 1));
    comp.getBounds(rect);
    rect.y -= rowHeight;
    comp.setBounds(rect);
    }
    }
    } class InternalTableModel extends AbstractTableModel implements TableModel {
    TableModel originModel = null; public InternalTableModel(TableModel originModel) {
    this.originModel = originModel;
    } public Class<?> getColumnClass(int columnIndex) {
    return originModel.getColumnClass(columnIndex);
    } public int getColumnCount() {
    return originModel.getColumnCount();
    } public String getColumnName(int columnIndex) {
    return originModel.getColumnName(columnIndex);
    } public int getRowCount() {
    return originModel.getRowCount() + holdPlaceRowIndexes.length;
    } public Object getValueAt(int rowIndex, int columnIndex) {
    if (isAHoldPlaceRow(rowIndex))
    return null;
    rowIndex = convertRowIndex(rowIndex);
    return originModel.getValueAt(rowIndex, columnIndex);
    } public boolean isCellEditable(int rowIndex, int columnIndex) {
    if (isAHoldPlaceRow(rowIndex))
    return false;
    rowIndex = convertRowIndex(rowIndex);
    return originModel.isCellEditable(rowIndex, columnIndex);
    } public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    if (isAHoldPlaceRow(rowIndex))
    return;
    rowIndex = convertRowIndex(rowIndex);
    originModel.setValueAt(aValue, rowIndex, columnIndex);
    }
    }
    }
      

  2.   

    /*
     * 创建日期 2004-4-17
     */
    package nestedtable;import javax.swing.JComponent;
    import javax.swing.table.TableModel;public interface NestedTableModel extends TableModel {
    /** 如果第rowIndex行可以展开返回true 
     * @param rowIndex 行序号
     * @return 如果此行可以展开返回true */
    boolean isRowExpandable(int rowIndex); /** 得到第rowIndex行对应的子组件 */
    public JComponent getSubComponent(int rowIndex);
    }
      

  3.   

    package nestedtable;import java.awt.*;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;import javax.swing.JComponent;
    import javax.swing.JPanel;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    /**  表格的列头,显示行号并处理选择行的鼠标操作 */
    class NestedTableRowHeader extends JPanel 
    implements MouseListener, TableModelListener { private NestedTable nestedTable = null; public NestedTableRowHeader(NestedTable nestedTable) {
    this.nestedTable = nestedTable; //setBackground(Color.white);
    addMouseListener(this);
    nestedTable.getModel().addTableModelListener(this);
    } public Dimension getPreferredSize() {
    return new Dimension(16, nestedTable.getHeight());
    } public void paintComponent(Graphics g) {
    super.paintComponent(g); Rectangle clip = g.getClipBounds();
    Point upperLeft = clip.getLocation();
    Point lowerRight = new Point(clip.x + clip.width - 1, clip.y + clip.height - 1);
    int rMin = nestedTable.rowAtPoint(upperLeft);
    int rMax = nestedTable.rowAtPoint(lowerRight);
    if (rMin == -1) {
    rMin = 0;
    }
    if (rMax == -1) {
    rMax = nestedTable.getRowCount()-1;
    } Rectangle rect = nestedTable.getCellRect(rMin, 0, false);
    int rowCount = nestedTable.getRowCount();
    for (int i = rMin; i <= rMax; i++) {
    boolean isAHoldplaceRow = nestedTable.isAHoldPlaceRow(i);
    int rowHeight = nestedTable.getRowHeight(i); g.setColor(Color.gray);
    if (isAHoldplaceRow == false) {
    g.drawRect(3, rect.y + rowHeight/2 - 5, 8, 8);
    if (i+1 > rowCount || !nestedTable.isAHoldPlaceRow(i+1)) { //未展开的行
    g.setColor(Color.black);
    g.drawLine(5, rect.y + rowHeight/2 - 1, 9, rect.y + rowHeight/2 - 1);
    g.drawLine(7, rect.y + rowHeight/2 - 3, 7, rect.y + rowHeight/2 + 1);
    } else {  //展开的行
    g.setColor(Color.black);
    g.drawLine(5, rect.y + rowHeight/2 - 1, 9, rect.y + rowHeight/2 - 1);
    g.setColor(Color.gray);
    g.drawLine(7, rect.y + rowHeight/2 + 4, 7, rect.y + rowHeight-1);
    }
    } else {
    g.setColor(Color.gray);
    g.drawLine(7, rect.y, 7, rect.y + 8);
    g.drawLine(7, rect.y + 8, 15, rect.y + 8);
    }
    rect.y += rowHeight;
    }
    } public void mouseClicked(MouseEvent e) {
    } public void mousePressed(MouseEvent e) {
    int row = nestedTable.rowAtPoint(e.getPoint());
    if (row != -1 && !nestedTable.isAHoldPlaceRow(row)) {
    int rowCount = nestedTable.getRowCount();
    if (row+1 > rowCount || !nestedTable.isAHoldPlaceRow(row+1)) {  //未展开的行
    int r = nestedTable.convertRowIndex(row);
    JComponent comp = nestedTable.model.getSubComponent(r);
    nestedTable.addComponentAfterRow(row, comp);
    } else {
    nestedTable.removeComponentAfterRow(row);
    }
    }
    } public void mouseReleased(MouseEvent e) {
    } public void mouseEntered(MouseEvent e) {
    } public void mouseExited(MouseEvent e) {
    } //实现TableModelListener接口
    public void tableChanged(TableModelEvent e) {
    invalidate();
    repaint();
    }
    }
      

  4.   

    /*
     * 创建日期 2004-4-18
     *
     */
    package nestedtable;import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;import javax.swing.*;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableModel;public class TestNestedTable { public static void main(String[] args) {
    try {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
    } class TestNestedTableModel extends AbstractTableModel implements NestedTableModel { public boolean isRowExpandable(int rowIndex) {
    return true;
    } public TableModel getSubModel(int rowIndex) {
    return null;
    } public int getColumnCount() {
    return 5;
    } public int getRowCount() {
    return 100;
    } public Object getValueAt(int rowIndex, int columnIndex) {
    return "Cell(" + rowIndex + "," + columnIndex + ")";
    } public JComponent getSubComponent(int rowIndex)
    {
    if (rowIndex %4 == 1) {
    JLabel label = new JLabel("第" + (rowIndex+1) + "行的子组件");
    label.setBorder(BorderFactory.createCompoundBorder(
    BorderFactory.createMatteBorder(0, 1, 0, 1, Color.GRAY), 
    BorderFactory.createEmptyBorder(10, 20, 10, 20)));
    label.setOpaque(true);
    return label;
    }
    else if (rowIndex %4 == 2) {
    JProgressBar p = new JProgressBar(JProgressBar.HORIZONTAL);
    p.setValue(75);
    return p;
    }
    else if (rowIndex %4 == 3) {
    return new JSlider();
    }
    else {
    JTable tab = new JTable(5, 3);
    JPanel p = new JPanel(new BorderLayout());
    p.add(tab, BorderLayout.CENTER);
    p.add(tab.getTableHeader(), BorderLayout.NORTH);
    JPanel pp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    pp.add(p);

    return pp;
    }
    }
    } JFrame frame = new JFrame();
    NestedTable table = new NestedTable(new TestNestedTableModel());
    frame.getContentPane().add(new JScrollPane(table), "Center");
    frame.setSize(800, 600);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    }
    }
      

  5.   

    很好,可惜我在试用的时候出了问题 看能帮我解决下吗?Usage: javaw [-options] class [args...]
               (to execute a class)
       or  javaw [-options] -jar jarfile [args...]
               (to execute a jar file)where options include:
        -client   to select the "client" VM
        -server   to select the "server" VM
        -hotspot   is a synonym for the "client" VM  [deprecated]
                      The default VM is client.
                      
        -cp <class search path of directories and zip/jar files>
        -classpath <class search path of directories and zip/jar files>
                      A ; separated list of directories, JAR archives,
                      and ZIP archives to search for class files.
        -D<name>=<value>
                      set a system property
        -verbose[:class|gc|jni]
                      enable verbose output
        -version      print product version and exit
        -version:<value>
                      require the specified version to run
        -showversion  print product version and continue
        -jre-restrict-search | -jre-no-restrict-search
                      include/exclude user private JREs in the version search
        -? -help      print this help message
        -X            print help on non-standard options
        -ea[:<packagename>...|:<classname>]
        -enableassertions[:<packagename>...|:<classname>]
                      enable assertions
        -da[:<packagename>...|:<classname>]
        -disableassertions[:<packagename>...|:<classname>]
                      disable assertions
        -esa | -enablesystemassertions
                      enable system assertions
        -dsa | -disablesystemassertions
                      disable system assertions
        -agentlib:<libname>[=<options>]
                      load native agent library <libname>, e.g. -agentlib:hprof
                        see also, -agentlib:jdwp=help and -agentlib:hprof=help
        -agentpath:<pathname>[=<options>]
                      load native agent library by full pathname
        -javaagent:<jarpath>[=<options>]
                      load Java programming language agent, see java.lang.instrument
        -splash:<imagepath>
                      show splash screen with specified image2