2011-10-24 32 views
4

我在jscrollpane内有一个jtable。我使用jgoodies Form Layout,并将scrollpane放在一个设置为“pref”的行中。这是表看起来像现在:JScrollpane中的JTable调整显示组件的高度

enter image description here

我使用的方式swingx JXTable并visibleRowCount的将设置为2。但是,只有显示一半的行。

虽然制作SSCCE我意识到它不能正常工作,因为我有一个自定义的TextAreaRenderer。我想因为这个渲染器,行高不能正确计算。我试图找出为什么,在此期间,如果你们能发现它,将是巨大......

public static void main(String[] args) { 
    JFrame frame=new JFrame(); 
    JPanel panel=new FormDebugPanel(); 
    frame.setContentPane(panel); 
    FormLayout layout=new FormLayout("1dlu:grow,200dlu:grow,1dlu:grow", 
      "10dlu,pref,5dlu,pref,10dlu"); 
    panel.setLayout(layout); 
    String[] columns= {"1st Column","2nd Column","3rd Column"}; 
    String[][] data= { 
      {"Sethu","Data","Something\nis\nhere"}, 
      {"Sethu","Data","Something\nis\nhere"}, 

    }; 
    JXTable table=new JXTable(data,columns); 
    table.setVisibleRowCount(2); 

    TableColumnModel columnModel=table.getColumnModel(); 
    columnModel.getColumn(2).setCellRenderer(new TextAreaRenderer()); 

    JScrollPane scrlPan=new JScrollPane(table); 
    CellConstraints cc=new CellConstraints(); 
    panel.add(scrlPan, cc.xy(2, 2)); 
    panel.add(new JLabel("Label After Table"),cc.xy(2,4)); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setVisible(true); 
    } 
} 

而这里的渲染器:

class TextAreaRenderer extends JTextArea implements TableCellRenderer { 

private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer(); 

/** map from table to map of rows to map of column heights */ 
private final Map<JTable,Map<Integer,Map<Integer,Integer>>> cellSizes = new HashMap<JTable,Map<Integer,Map<Integer,Integer>>>(); 

public TextAreaRenderer() { 
    setLineWrap(true); 
    setWrapStyleWord(true); 
} 

public Component getTableCellRendererComponent(// 
     JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) { 
    // set the colours, etc. using the standard for that platform 
    adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column); 
    setForeground(adaptee.getForeground()); 
    setBackground(adaptee.getBackground()); 
    setBorder(adaptee.getBorder()); 
    setFont(adaptee.getFont()); 
    setText(adaptee.getText()); 

    // This line was very important to get it working with JDK1.4 
    TableColumnModel columnModel = table.getColumnModel(); 
    setSize(columnModel.getColumn(column).getWidth(), 100000); 
    int height_wanted = (int) getPreferredSize().getHeight(); 
    addSize(table, row, column, height_wanted); 
    height_wanted = findTotalMaximumRowSize(table, row); 
    if (height_wanted != table.getRowHeight(row)) { 
     table.setRowHeight(row, height_wanted); 
    } 
    return this; 
} 

private void addSize(JTable table, int row, int column, int height) { 
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table); 
    if (rows == null) { 
     cellSizes.put(table, rows = new HashMap<Integer,Map<Integer,Integer>>()); 
    } 
    Map<Integer,Integer> rowheights = rows.get(new Integer(row)); 
    if (rowheights == null) { 
     rows.put(new Integer(row), rowheights = new HashMap<Integer,Integer>()); 
    } 
    rowheights.put(new Integer(column), new Integer(height)); 
} 

/** 
* Look through all columns and get the renderer. If it is also a 
* TextAreaRenderer, we look at the maximum height in its hash table for 
* this row. 
*/ 
private int findTotalMaximumRowSize(JTable table, int row) { 
    int maximum_height = 0; 
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns(); 
    while (columns.hasMoreElements()) { 
     TableColumn tc = (TableColumn) columns.nextElement(); 
     TableCellRenderer cellRenderer = tc.getCellRenderer(); 
     if (cellRenderer instanceof TextAreaRenderer) { 
      TextAreaRenderer tar = (TextAreaRenderer) cellRenderer; 
      maximum_height = Math.max(maximum_height, tar.findMaximumRowSize(table, row)); 
     } 
    } 
    return maximum_height; 
} 

private int findMaximumRowSize(JTable table, int row) { 
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table); 
    if (rows == null) 
     return 0; 
    Map<Integer,Integer> rowheights = rows.get(new Integer(row)); 
    if (rowheights == null) 
     return 0; 
    int maximum_height = 0; 
    for (Iterator<Map.Entry<Integer, Integer>> it = rowheights.entrySet().iterator(); it.hasNext();) { 
     Map.Entry<Integer,Integer> entry = it.next(); 
     int cellHeight = ((Integer) entry.getValue()).intValue(); 
     maximum_height = Math.max(maximum_height, cellHeight); 
    } 
    return maximum_height; 
} 
} 

当我使用TextAreaRenderer,然后setVisibleRowHeight()不正确。我认为这与在渲染器中不正确设置行高有关。

+2

时间为SSCCE - 看到你的评论,我不太明白你所追求的:-) – kleopatra

+0

没有看的渲染器,所以这与它无关:在SwingX中你永远不会_实现一个渲染器(你将失去自动高亮/字符串表示的所有细节,),而是实现一个ComponentProvider。测试包中包含如何执行此操作的示例,其中包括供应商出售JTextArea – kleopatra

回答

4

随着JXTable,您可以配置多少行(或列)初步显示:

table.setVisibleRowCount(2) 

这里展示了如何对设置条件的初始规模快速片段行和动态的TableModelListener更新PREF高度

final JXTable table = new JXTable(3, 5); 
    table.setVisibleRowCount(table.getRowCount()); 
    TableModelListener l = new TableModelListener() { 

     @Override 
     public void tableChanged(TableModelEvent e) { 
      if (!(e.getType() == TableModelEvent.INSERT)) return; 
      table.setVisibleRowCount(((TableModel) e.getSource()).getRowCount()); 
      RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(table); 
      ((JComponent) frame.getContentPane()).revalidate(); 
     } 
    }; 
    table.getModel().addTableModelListener(l); 
    Action insert = new AbstractAction("add row") { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      ((DefaultTableModel) table.getModel()).addRow(new Object[] {}); 
     } 
    }; 
    new Timer(500, insert).start(); 
    JComponent comp = new JPanel(new MigLayout()); 
    comp.add(new JScrollPane(table)); 
    JXFrame frame = wrapInFrame(comp, "visibleRowCount"); 
    show(frame, frame.getPreferredSize().width, frame.getPreferredSize().height * 4); 
+0

感谢您的支持。对我来说,更容易,表格中的数据在面板构建时加载并且不会更改。所以我不需要听众。但是如果我用一个滚动窗口包装了JXTable,那么随着设置visibleRowCount(),我还需要正确设置滚动窗格的大小。你能帮助我如何设置scrollpane的大小吗?设置行数的逻辑很简单。如果行计数小于3,则将setVisibleRowCount设置为行计数。否则,将setVisibleRowCount保持为3并滚动剩余的行。 – sethu

+0

对不起,我回头..你不设置滚动窗格的大小,而是你设置我使用的jgoodies表格布局中的行的大小。我需要设置包含此滚动窗格+ jxtable的行的行大小。我怎么计算表之前,表? – sethu

+0

不设置固定尺寸,永不放弃 - 让布局为您处理 – kleopatra

1

我相信你可以使用JSCrollPane的preferredSize,minSize和maxSize属性来实现这一点。如果您将preferredSize设置为所需的最小大小,并将maxsize设置为所需的最大大小,则应该可以工作。

+0

否,从不使用任何setXXSize,原因参见f.i. http://stackoverflow.com/questions/7229226/avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swing – kleopatra

2
setPreferredScrollableViewportSize(Dimension) 

是你应该看看的东西。这里是一个很好的教程:How to Use Scroll Panes

+0

不,不比setXXSize更好..尤其是不支持配置逻辑大小的组件(比如JXTable,fi) – kleopatra