多页和多线JTable

时间:2015-04-27 07:08:17

标签: java swing jtable

我想创建一个可以在多个页面中显示的JTable(如果行超过最大行数),并且它还有一个可以包装多行文本的列(或单元格)。问题是当它被设置为多页时,它的表模型已经用于AbstractTableModel,并且它不能被DefaultTableModel设置(再次),这是包装多行文本所需要的。我可以单独运行多页表或多行文本列表,但是当我将两者结合起来时,就会出现问题。我已经在互联网上的任何地方搜索,但我的问题没有答案。有人能帮助我吗?

这是我用于多页表的AbstractTableModel代码:

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {"No.","Kode","Produk","Jasa","satuan", "harga", "qty", "jml"};
    private Vector data = new Vector();
    public final Object[] longValues = {"", "", "", false, "", new Double(20), new Integer(20), new Double(20)};

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }
    @Override
    public int getRowCount() {
        return data.size();
    }
    @Override
    public Object getValueAt(int row, int col) {
        return ((Vector) data.get(row)).get(col);
    }           

    public String getColumnName(int col){
        return columnNames[col];
    }
    public void setEmpty(int rows) {    
        int i = rows-1;
        while (i > -1) {
            data.removeElementAt(i); 
            i--;
        }

        fireTableDataChanged();
    }
    public Class getColumnClass(int col){
        switch (col) {
            case 0:
                return String.class;
            case 1:
                return String.class;
            case 2:
                return String.class;
            case 3:
                return Boolean.class;   
            case 4:
                return String.class; 
            case 5:
                return Double.class; 
            case 6:
                return Integer.class; 
            case 7:
                return Double.class; 
            default:
                return String.class;
        }
    }        
    public void setValueAt(Object value, int row, int col){
        ((Vector) data.get(row)).setElementAt(value, col);
        fireTableCellUpdated(row,col);
    }
    public boolean isCellEditable(int row, int col){            
        return true;            
    }
    public void insertData(Object[] values){
        data.add(new Vector());
        for(int i = 0; i < values.length; i++){
            ((Vector) data.get(data.size()-1)).add(values[i]);
        }
        fireTableDataChanged();
    }
    public void removeRow(int row){
        data.removeElementAt(row);
        fireTableDataChanged();
    }
}

我从setGrid()方法调用它:

public void setGrid() {
...
tabelItem = new Zebra();
btnRight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nomorHalaman++;
                initPagination();
            }
 });
 panelNavigasi.add(btnRight);
...
}

initPagination()使用上面的MyTableModel来加载MySQL数据库中表的记录,每次用户单击导航按钮(第一个,左,右,最后)时,可以设置一页中的行数:

private void initPagination(){
    totalData=getItemRecNum();         
    jumlahBarisPerhalaman=Integer.valueOf(txtPagesize.getText());
    Double totalHalamanD=Math.ceil((double)totalData/(double)jumlahBarisPerhalaman);
    totalHalaman=totalHalamanD.intValue();        
    String HEADER[]={"No.","Kode","Produk","Jasa","satuan", "harga", "qty", "jml"};
    if(nomorHalaman.equals(1)){
        btnOne.setEnabled(false);
        btnLeft.setEnabled(false);
    }   else {
        btnOne.setEnabled(true);
        btnLeft.setEnabled(true);
    }

    if(nomorHalaman.equals(totalHalaman)){
        btnEnd.setEnabled(false);
        btnRight.setEnabled(false);
    }   else    {
        btnEnd.setEnabled(true);
        btnRight.setEnabled(true);
    }    
    if(nomorHalaman>totalHalaman){
        nomorHalaman=1;
    }        

    model = new MyTableModel();
  // Get records from MySQL DB according to page(offset) and rows per page      
    show(nomorHalaman, jumlahBarisPerhalaman);
    tabelItem.setModel(model);   

    lblPage.setText("p." + nomorHalaman + "/" + totalHalaman + "     ");
}

Zebra是一个class,可以制作斑马条纹表,我将它用于多行单元格表:

public class Zebra extends JTable {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
    Component cell = super.prepareRenderer(renderer, row, col);
    cell.setForeground(Color.BLACK);
    if (row % 2 == 0) {
        cell.setBackground(Color.ORANGE);            
    } else {
        cell.setBackground(Color.WHITE);            
    }
    return cell;
}
@Override public void doLayout() {
    TableColumn col = getColumnModel().getColumn(2);
    for(int row=0; row<getRowCount(); row++) {
      Component c = prepareRenderer(col.getCellRenderer(), row, 2);
      if(c instanceof JTextArea) {
        JTextArea a = (JTextArea)c;
        int h = getPreferredHeight(a) + getIntercellSpacing().height;
        if(getRowHeight(row)!=h) setRowHeight(row, h);
      }
    }
    super.doLayout();
  }

  private int getPreferredHeight(JTextComponent c) {
    Insets insets = c.getInsets();
    View view = c.getUI().getRootView(c).getView(0);
    int preferredHeight = (int)view.getPreferredSpan(View.Y_AXIS);
    return preferredHeight + insets.top + insets.bottom;
  }

  class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
    private final Color evenColor = new Color(230, 240, 255);
    public TextAreaCellRenderer() {
      super();
      setLineWrap(true);
      setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
    }
    @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
      if(isSelected) {
        setForeground(table.getSelectionForeground());
        setBackground(table.getSelectionBackground());
      } else {
        setForeground(table.getForeground());
        setBackground(table.getBackground());
        setBackground((row%2==0)?evenColor:getBackground());
      }
      setFont(table.getFont());
      setText((value ==null) ? "" : value.toString());
      return this;
    }
}

1 个答案:

答案 0 :(得分:0)

我已经找到了解决问题的方法。也许还有其他方法,但这对我来说已经足够了。我对旧源进行了一些修改,并将其限制为三行,因为项目名称不长,需要三行以上。 Aaron Digulla是对的,它应该来自渲染器,与模型无关....感谢您的建议。

private int getPreferredHeight(JTextComponent c) {
    Insets insets = c.getInsets();
    View view = c.getUI().getRootView(c).getView(2);
    int preferredHeight = (int)view.getPreferredSpan(View.Y_AXIS);
    return preferredHeight + insets.top + insets.bottom;
} 
private void setMultiLine(JTable table, TableColumn col, int row) {    
    int tableRowHeight = table.getRowHeight();
    col.setCellRenderer(new TextAreaCellRenderer());
    Component c = table.prepareRenderer(col.getCellRenderer(), row, 2);
    if(c instanceof JTextArea) {
          JTextArea a = (JTextArea) c;
          int h = getPreferredHeight(a) +     table.getIntercellSpacing().height;               
          if(h > tableRowHeight) {
              if (tableRowHeight * 3 < h) 
                  table.setRowHeight(row, tableRowHeight * 3);
              else
                  table.setRowHeight(row, h);
          }
    }       
}