我有一个JTable使用TableColumnModelListener()
来检测列何时重新调整大小,并且我想要在columnMarginChanged()
方法中执行一些代码。
如何确定列是由用户重新调整大小还是由于其他代码?
我想我必须从ChangeEvent.getSource()
开始,但我不知道从哪里开始。
谢谢。
答案 0 :(得分:7)
我可以给你一个可能的方法。我试图解决同样的问题,因为我想将有关列宽的信息序列化到磁盘,以便下次在我的应用程序中打开表时,我可以适当地恢复列宽。这是:
第1步 - 覆盖您的JTable并为其添加布尔属性
class MyTable extends JTable {
private boolean isColumnWidthChanged;
public boolean getColumnWidthChanged() {
return isColumnWidthChanged;
}
public void setColumnWidthChanged(boolean widthChanged) {
isColumnWidthChanged = widthChanged;
}
}
第2步 - 将TableColumnModelListener()添加到表
private class TableColumnWidthListener implements TableColumnModelListener
{
@Override
public void columnMarginChanged(ChangeEvent e)
{
/* columnMarginChanged is called continuously as the column width is changed
by dragging. Therefore, execute code below ONLY if we are not already
aware of the column width having changed */
if(!tableObj.hasColumnWidthChanged())
{
/* the condition below will NOT be true if
the column width is being changed by code. */
if(tableObj.getTableHeader.getResizingColumn() != null)
{
// User must have dragged column and changed width
tableObj.setColumnWidthChanged(true);
}
}
}
@Override
public void columnMoved(TableColumnModelEvent e) { }
@Override
public void columnAdded(TableColumnModelEvent e) { }
@Override
public void columnRemoved(TableColumnModelEvent e) { }
@Override
public void columnSelectionChanged(ListSelectionEvent e) { }
}
步骤3 - 将鼠标监听器添加到表格标题
private class TableHeaderMouseListener extends MouseAdapter
{
@Override
public void mouseReleased(MouseEvent e)
{
/* On mouse release, check if column width has changed */
if(tableObj.getColumnWidthChanged())
{
// Do whatever you need to do here
// Reset the flag on the table.
tableObj.setColumnWidthChanged(false);
}
}
}
注意:在我的应用程序中,TableHeaderMouseListener和TableColumnWidthListener类是我的主应用程序类的私有内部类。我的主要应用程序类保持对正在观察的表的引用。因此,这些内部类可以访问表实例。显然,根据您的设置,您需要执行适当的操作以使表实例可用于这些其他类。希望这有帮助!
答案 1 :(得分:4)
通常,您希望收到已完成列拖动或已完成列调整大小的通知。 E.g。
interface SGridModel {
public void columnMoved(int oldLocation, int newLocation);
public void columnResized(int column, int newWidth);
}
这不是很好,但它会做你想要的:
class SColumnListener extends MouseAdapter implements TableColumnModelListener {
private final Logger log = Logger.getLogger(getClass());
private final SGridModel model;
private int oldIndex = -1;
private int newIndex = -1;
private boolean dragging = false;
private boolean resizing = false;
private int resizingColumn = -1;
private int oldWidth = -1;
SColumnListener(SGridModel model){
this.model = model;
}
@Override
public void mousePressed(MouseEvent e) {
// capture start of resize
if(e.getSource() instanceof JTableHeader) {
TableColumn tc = ((JTableHeader)e.getSource()).getResizingColumn();
if(tc != null) {
resizing = true;
resizingColumn = tc.getModelIndex();
oldWidth = tc.getPreferredWidth();
} else {
resizingColumn = -1;
oldWidth = -1;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// column moved
if(dragging && oldIndex != newIndex) {
model.columnMoved(oldIndex, newIndex);
log.info("column moved: " +oldIndex+" -> "+newIndex);
}
dragging = false;
oldIndex = -1;
newIndex = -1;
// column resized
if(resizing) {
if(e.getSource() instanceof JTableHeader) {
TableColumn tc = ((JTableHeader)e.getSource()).getColumnModel().getColumn(resizingColumn);
if(tc != null) {
int newWidth = tc.getPreferredWidth();
if(newWidth != oldWidth) {
model.columnResized(resizingColumn, newWidth);
log.info("column resized: " +resizingColumn+" -> "+newWidth);
}
}
}
}
resizing = false;
resizingColumn = -1;
oldWidth = -1;
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
// capture dragging
dragging = true;
if(oldIndex == -1){
oldIndex = e.getFromIndex();
}
newIndex = e.getToIndex();
}
@Override
public void columnMarginChanged(ChangeEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
}
将其添加到表中,如下所示:
table.getColumnModel().addColumnModelListener(cl);
table.getTableHeader().addMouseListener(cl);
答案 2 :(得分:0)
更简单的解决方案可能只是监听鼠标释放事件(在此用户交互中仅发生一次)并检查列大小是否同时发生变化?我使用下面的代码来监听列重新排序和大小更改。
getTableHeader().addMouseListener( new MouseAdapter() {
public void mouseReleased(MouseEvent arg0)
{
String colNamesAndSizes = "";
for( int i=0;i<getColumnModel().getColumnCount();i++ ) {
if( i>0 ) colNamesAndSizes += ",";
TableColumn column = getColumnModel().getColumn(i);
colNamesAndSizes += column.getHeaderValue();
colNamesAndSizes += ":";
colNamesAndSizes += column.getWidth();
}
// check if changed, if yes, persist...
}});