我想创建一个可以在多个页面中显示的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;
}
}
答案 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);
}
}
}