gpt4 book ai didi

java - 如何在现有 JTable 的顶部添加一个表,其中一行由 JComboboxes 组成

转载 作者:行者123 更新时间:2023-11-30 11:12:58 26 4
gpt4 key购买 nike

我正在尝试在现有 JTable 之上添加一行 JTable,该 JTable 通常是动态创建的,并且经常更改其数据模型。

JTable

如您所见,黄色区域仅代表一个行计数器,它是使用此 source 创建的

黄色列因此已使用以下代码附加到主表:

JTable rowTable = new RowNumberTable(table);
scrollTable.setRowHeaderView(rowTable);

表格列 A、B、C 等,如果单击,则相应地对 JTable 进行排序并且应该保留此功能(我不想将 JCombobox 放在表格标题中,除非有一个聪明的方法两者都有)。

我的目标是创建一个单行(见红行)的 JTable,它的列数与主 JTable 的列数一样多

编辑

这里是SSCCE

我想将 JComboBoxes 放在 A、B、C、D 之上......

渲染JComboBoxes的类是ColumnJComboBoxTable,在TableDemo中调用如下:

//Column JCombobox
JTable columnTable = new ColumnJComboBoxTable(table);
scrollTable.setColumnHeaderView(columnTable);

现在它没有像我想要的那样工作(好吧,它根本没有工作)

enter image description here

顶部的按钮添加和删除列。因此,如果删除一列,则相应的 JComboBox 也必须删除。

代码

表格演示

package com.table;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.AbstractAction;

public class TableDemo extends JFrame
{

private static final long serialVersionUID = 1L;

public TableDemo()
{
super("TableDemo");

Object[][] data =
{
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
{"0","1","2","3","4","5","6","7","8","9","10"},
};

String[] columnNames =
{
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
};

final JTable table = new JTable(data, columnNames);
new JPopupMenu();
final JToolBar toolBar = new JToolBar();
final XTableColumnModel columnModel = new XTableColumnModel();

table.setColumnModel(columnModel);
table.createDefaultColumnsFromModel();

toolBar.add(new JButton(new AbstractAction("ALL") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
columnModel.setAllColumnsVisible();
}
}));

toolBar.add(new JButton(new AbstractAction("Column 0") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(0);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 1") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(1);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 2") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(2);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 3") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(3);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));

toolBar.add(new JButton(new AbstractAction("Column 4") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(4);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 5") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(5);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 6") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(6);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 7") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(7);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 8") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(8);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 9") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(9);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
toolBar.add(new JButton(new AbstractAction("Column 10") {
/**
*
*/
private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(10);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));


//Row number
table.setFillsViewportHeight(true);
JScrollPane scrollTable = new JScrollPane(table,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollTable.setViewportView(table);

JTable rowTable = new RowNumberTable(table);
scrollTable.setRowHeaderView(rowTable);
scrollTable.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());

//Column JCombobox
JTable columnTable = new ColumnJComboBoxTable(table);
scrollTable.setColumnHeaderView(columnTable);

getContentPane().add(toolBar, BorderLayout.NORTH);
getContentPane().add(scrollTable, BorderLayout.CENTER);

addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}

public static void main(String[] args)
{
TableDemo frame = new TableDemo();

frame.pack();
frame.repaint();
frame.setVisible(true);
}
}

XTableColumnModel

表格模型已借用here

package com.table;
import javax.swing.table.*;
import java.util.Vector;
import java.util.Enumeration;


public class XTableColumnModel extends DefaultTableColumnModel {

private static final long serialVersionUID = 1L;

protected Vector allTableColumns = new Vector();

XTableColumnModel() {
}

public void setColumnVisible(TableColumn column, boolean visible) {
if(!visible) {
super.removeColumn(column);
}
else
{
int noVisibleColumns = tableColumns.size();
int noInvisibleColumns = allTableColumns.size();
int visibleIndex = 0;

for(int invisibleIndex = 0; invisibleIndex < noInvisibleColumns; ++invisibleIndex) {
TableColumn visibleColumn = (visibleIndex < noVisibleColumns ? (TableColumn)tableColumns.get(visibleIndex) : null);
TableColumn testColumn = (TableColumn)allTableColumns.get(invisibleIndex);

if(testColumn == column) {
if(visibleColumn != column) {
super.addColumn(column);
super.moveColumn(tableColumns.size() - 1, visibleIndex);
}
return;
}
if(testColumn == visibleColumn) {
++visibleIndex;
}
}
}
}

public void setAllColumnsVisible() {
int noColumns = allTableColumns.size();

for(int columnIndex = 0; columnIndex < noColumns; ++columnIndex) {
TableColumn visibleColumn = (columnIndex < tableColumns.size() ? (TableColumn)tableColumns.get(columnIndex) : null);
TableColumn invisibleColumn = (TableColumn)allTableColumns.get(columnIndex);

if(visibleColumn != invisibleColumn) {
super.addColumn(invisibleColumn);
super.moveColumn(tableColumns.size() - 1, columnIndex);
}
}
}

public TableColumn getColumnByModelIndex(int modelColumnIndex) {
for (int columnIndex = 0; columnIndex < allTableColumns.size(); ++columnIndex) {
TableColumn column = (TableColumn)allTableColumns.elementAt(columnIndex);
if(column.getModelIndex() == modelColumnIndex) {
return column;
}
}
return null;
}

public boolean isColumnVisible(TableColumn aColumn) {
return (tableColumns.indexOf(aColumn) >= 0);
}

public void addColumn(TableColumn column) {
allTableColumns.addElement(column);
super.addColumn(column);
}

public void removeColumn(TableColumn column) {
int allColumnsIndex = allTableColumns.indexOf(column);
if(allColumnsIndex != -1) {
allTableColumns.removeElementAt(allColumnsIndex);
}
super.removeColumn(column);
}

public void moveColumn(int oldIndex, int newIndex) {
if ((oldIndex < 0) || (oldIndex >= getColumnCount()) ||
(newIndex < 0) || (newIndex >= getColumnCount()))
throw new IllegalArgumentException("moveColumn() - Index out of range");

TableColumn fromColumn = (TableColumn) tableColumns.get(oldIndex);
TableColumn toColumn = (TableColumn) tableColumns.get(newIndex);

int allColumnsOldIndex = allTableColumns.indexOf(fromColumn);
int allColumnsNewIndex = allTableColumns.indexOf(toColumn);

if(oldIndex != newIndex) {
allTableColumns.removeElementAt(allColumnsOldIndex);
allTableColumns.insertElementAt(fromColumn, allColumnsNewIndex);
}

super.moveColumn(oldIndex, newIndex);
}

public int getColumnCount(boolean onlyVisible) {
Vector columns = (onlyVisible ? tableColumns : allTableColumns);
return columns.size();
}

public Enumeration getColumns(boolean onlyVisible) {
Vector columns = (onlyVisible ? tableColumns : allTableColumns);

return columns.elements();
}

public int getColumnIndex(Object identifier, boolean onlyVisible) {
if (identifier == null) {
throw new IllegalArgumentException("Identifier is null");
}

Vector columns = (onlyVisible ? tableColumns : allTableColumns);
int noColumns = columns.size();
TableColumn column;

for(int columnIndex = 0; columnIndex < noColumns; ++columnIndex) {
column = (TableColumn)columns.get(columnIndex);

if(identifier.equals(column.getIdentifier()))
return columnIndex;
}

throw new IllegalArgumentException("Identifier not found");
}

public TableColumn getColumn(int columnIndex, boolean onlyVisible) {
return (TableColumn)tableColumns.elementAt(columnIndex);
}
}

RowNumberTable

package com.table;
import java.awt.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;


public class RowNumberTable extends JTable
implements ChangeListener, PropertyChangeListener, TableModelListener
{

private static final long serialVersionUID = -3837585325898676144L;
private JTable main;

public RowNumberTable(JTable table)
{
main = table;
main.addPropertyChangeListener( this );
main.getModel().addTableModelListener( this );

setFocusable( false );
setAutoCreateColumnsFromModel( false );
setSelectionModel( main.getSelectionModel() );

TableColumn column = new TableColumn();
column.setHeaderValue(" ");
addColumn( column );
column.setCellRenderer(new RowNumberRenderer());

getColumnModel().getColumn(0).setPreferredWidth(50);
setPreferredScrollableViewportSize(getPreferredSize());
}

@Override
public void addNotify()
{
super.addNotify();

Component c = getParent();

// Keep scrolling of the row table in sync with the main table.

if (c instanceof JViewport)
{
JViewport viewport = (JViewport)c;
viewport.addChangeListener( this );
}
}


@Override
public int getRowCount()
{
return main.getRowCount();
}

@Override
public int getRowHeight(int row)
{
int rowHeight = main.getRowHeight(row);

if (rowHeight != super.getRowHeight(row))
{
super.setRowHeight(row, rowHeight);
}

return rowHeight;
}


@Override
public Object getValueAt(int row, int column)
{
return Integer.toString(row + 1);
}


@Override
public boolean isCellEditable(int row, int column)
{
return false;
}

@Override
public void setValueAt(Object value, int row, int column) {}

public void stateChanged(ChangeEvent e)
{
// Keep the scrolling of the row table in sync with main table

JViewport viewport = (JViewport) e.getSource();
JScrollPane scrollPane = (JScrollPane)viewport.getParent();
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
viewport.setBackground(Color.WHITE);
}

public void propertyChange(PropertyChangeEvent e)
{
// Keep the row table in sync with the main table

if ("selectionModel".equals(e.getPropertyName()))
{
setSelectionModel( main.getSelectionModel() );
}

if ("rowHeight".equals(e.getPropertyName()))
{
repaint();
}

if ("model".equals(e.getPropertyName()))
{
main.getModel().addTableModelListener( this );
revalidate();
}
}

@Override
public void tableChanged(TableModelEvent e)
{
revalidate();
}

/*
* Attempt to mimic the table header renderer
*/
private static class RowNumberRenderer extends DefaultTableCellRenderer
{
/**
*
*/
private static final long serialVersionUID = 6579115025835194953L;

public RowNumberRenderer()
{
setHorizontalAlignment(JLabel.CENTER);
}

public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (table != null)
{
JTableHeader header = table.getTableHeader();

if (header != null)
{
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}

if (isSelected)
{
setFont( getFont().deriveFont(Font.ITALIC) );
}

setText((value == null) ? "" : value.toString());
//setBorder(UIManager.getBorder("TableHeader.cellBorder"));

return this;
}
}
}

ColumnJComboBoxTable

package com.table;
import java.awt.*;
import java.beans.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;


public class ColumnJComboBoxTable extends JTable implements ChangeListener,PropertyChangeListener, TableModelListener
{

private static final long serialVersionUID = -3837585325898676144L;
private JTable main;

public ColumnJComboBoxTable(JTable table)
{
main = table;
main.addPropertyChangeListener( this );
main.getModel().addTableModelListener( this );

setFocusable( false );
setAutoCreateColumnsFromModel( false );
setSelectionModel( main.getSelectionModel() );

for(int i =0; i<main.getModel().getColumnCount();i++)
{
TableColumn column = new TableColumn();
column.setHeaderValue(i);
addColumn( column );
getColumnModel().getColumn(i).setPreferredWidth(50);
column.setCellRenderer(new ColumnJComboBoxRenderer());
column.setHeaderRenderer(new ColumnJComboBoxRenderer());
}
setPreferredScrollableViewportSize(getPreferredSize());

}

@Override
public void addNotify()
{
super.addNotify();

Component c = getParent();

// Keep scrolling of the row table in sync with the main table.

if (c instanceof JViewport)
{
JViewport viewport = (JViewport)c;
viewport.addChangeListener( this );
}
}

@Override
public int getColumnCount()
{
return main.getColumnCount();
}

@Override
public int getRowHeight(int row)
{
int rowHeight = main.getRowHeight(row);

if (rowHeight != super.getRowHeight(row))
{
super.setRowHeight(row, rowHeight);
}
return rowHeight;
}

/*
* No model is being used for this table so just use the row number
* as the value of the cell.
*/
@Override
public Object getValueAt(int row, int column)
{
return Integer.toString(column + 1);
}

/*
* Don't edit data in the main TableModel by mistake
*/
@Override
public boolean isCellEditable(int row, int column)
{
return false;
}

/*
* Do nothing since the table ignores the model
*/

@Override
public void setValueAt(Object value, int row, int column) {}
//
// Implement the ChangeListener
//
public void stateChanged(ChangeEvent e)
{
// Keep the scrolling of the row table in sync with main table
JViewport viewport = (JViewport) e.getSource();
JScrollPane scrollPane = (JScrollPane)viewport.getParent();
scrollPane.getHorizontalScrollBar().setValue(viewport.getViewPosition().x);
}

//
// Implement the PropertyChangeListener
//

public void propertyChange(PropertyChangeEvent e)
{
// Keep the row table in sync with the main table

if ("selectionModel".equals(e.getPropertyName()))
{
setSelectionModel( main.getSelectionModel() );
}

if ("rowHeight".equals(e.getPropertyName()))
{
repaint();
}

if ("model".equals(e.getPropertyName()))
{
main.getModel().addTableModelListener( this );
revalidate();
}
}

//
// Implement the TableModelListener
//
@Override
public void tableChanged(TableModelEvent e)
{
revalidate();
}

/*
* Attempt to mimic the table header renderer
*/
private static class ColumnJComboBoxRenderer extends DefaultTableCellRenderer
{
/**
*
*/
private static final long serialVersionUID = 6579115025835194953L;

public ColumnJComboBoxRenderer()
{
setHorizontalAlignment(JLabel.HORIZONTAL);
}

public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (table != null)
{
JTableHeader header = table.getTableHeader();

if (header != null)
{
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}

if (isSelected)
{
setFont( getFont().deriveFont(Font.ITALIC) );
}
setText((value == null) ? "" : value.toString());

return this;
}
}
}

非常感谢任何人的帮助

谢谢

最佳答案

感谢@mKorbel 的帮助

这里是解决方案的代码

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableFilterRow implements TableColumnModelListener
{

private JTable table;
private JPanel filterRow;

public TableFilterRow(JTable table,JPanel filterRow)
{
this.table = table;
this.filterRow=filterRow;
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.getColumnModel().addColumnModelListener(this);
table.columnMarginChanged(new ChangeEvent(table.getColumnModel()));
}

@Override
public void columnMarginChanged(ChangeEvent e)
{
TableColumnModel tcm = table.getColumnModel();

int columns = tcm.getColumnCount();

for (int i = 0; i < columns; i++)
{
JComboBox<?> comboBox = (JComboBox<?>) filterRow.getComponent(i);
Dimension d = comboBox.getPreferredSize();
d.width = tcm.getColumn(i).getWidth();
comboBox.setPreferredSize(d);
}

SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
filterRow.revalidate();
}
});
}

@Override
public void columnMoved(TableColumnModelEvent e)
{
Component moved = filterRow.getComponent(e.getFromIndex());
filterRow.remove(e.getFromIndex());
filterRow.add(moved, e.getToIndex());
filterRow.validate();
}

@Override
public void columnAdded(TableColumnModelEvent e)
{

}

@Override
public void columnRemoved(TableColumnModelEvent e)
{

}

@Override
public void columnSelectionChanged(ListSelectionEvent e)
{

}

public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
JTable table = new JTable(3, 5);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.columnMarginChanged(new ChangeEvent(table.getColumnModel()));

ComboFields[] comboFields = ComboFields.values();

JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);

JPanel filterRow = new JPanel();
filterRow.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

for (int i = 0; i < table.getColumnCount(); i++)
{
filterRow.add(new JComboBox<ComboFields>(comboFields));
}
new TableFilterRow(table, filterRow);

frame.add(filterRow, BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

private enum ComboFields{

VALUE_0(0),
VALUE_1(1),
VALUE_2(2),
VALUE_3(3),
VALUE_4(4),
VALUE_5(5);
// Internal state
private int fieldNumber;

private ComboFields(final int fieldNumber)
{
this.setFieldNumber(fieldNumber);
}

@SuppressWarnings("unused")
public int getFieldNumber() {
return fieldNumber;
}

public void setFieldNumber(int fieldNumber)
{
this.fieldNumber = fieldNumber;
}
}
}

关于java - 如何在现有 JTable 的顶部添加一个表,其中一行由 JComboboxes 组成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26614135/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com