Java 多页多行JTable
我想制作一个Java 多页多行JTable,java,swing,jtable,Java,Swing,Jtable,我想制作一个JTable,它可以显示在多个页面中(如果行超过最大行数),并且它还有一个可以包装多行文本的列(或单元格)。问题是,当为多页设置它时,它的表模型已经用于AbstractTableModel,并且不能(再次)通过包装多行文本所需的DefaultTableModel设置它。我可以单独运行多页表或多行文本列表,但当我将两者结合使用时,问题就会出现。我已经在互联网上搜索过了,但我的问题没有答案。有人能帮我吗 这是我用于多页表的AbstractTableModel的代码: class MyTa
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();
}
}
initPagination()
Zebra
是一个制作Zebra stripe表的类,我将其用于多行单元格表:
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;
}
}
公共类Zebra扩展JTable{
@凌驾
公共组件预渲染器(TableCellRenderer渲染器,int行,int列){
组件单元=super.prepareRenderer(渲染器、行、列);
单元格。设置前景(颜色。黑色);
如果(第%2行==0){
细胞。挫折背景(颜色。橙色);
}否则{
细胞。挫折背景(颜色。白色);
}
返回单元;
}
@覆盖公共void doLayout(){
TableColumn col=getColumnModel().getColumn(2);
对于(int row=0;row我已经找到了问题的解决方案。也许还有其他方法,但现在对我来说已经足够了。我从旧的源代码中做了一些修改,并将其限制为三行,因为项目名称不太长,不需要超过三行。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);
}
}
}
private int getPreferredHeight(jtextc组件){
Insets Insets=c.getInsets();
视图视图=c.getUI().getRootView(c).getView(2);
int preferredHeight=(int)view.getPreferredSpan(view.Y_轴);
返回首选高度+insets.top+insets.bottom;
}
私有void setMultiLine(JTable table,TableColumn col,int row){
int tableRowHeight=table.getRowHeight();
col.setCellRenderer(新的TextAreaCellRenderer());
组件c=table.prepareRenderer(列getCellRenderer(),第2行);
if(JTextArea的c实例){
JTextArea=(JTextArea)c;
int h=getPreferredHeight(a)+table.getIntercellSpacing().height;
如果(h>表格行高){
if(表格行高*3
我“建议”多行线支持应该来自渲染器,它应该与模型无关。这和/或您可能需要使用一个或多个代理模型来“过滤”先前存在的模型以满足您的新需求。我尝试了您的建议,但我遇到错误:“线程中的异常”AWT-EventQueue-0“java.lang.ArrayIndexOutOfBoundsException:2>=0”。这是因为我为第2列调用了渲染器(该列尚未由DeafultTableModel初始化):这是对表的调用:tabelItem.getColumnModel().getColumn(2).setCellRenderer(new TextAreaCellRenderer());…我对代理模型没有任何概念……对不起,“页面”是什么“在GUI术语中?您通常将JTable
放在JScrollPane
中。
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;
}
}
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);
}
}
}