Java JTable определяет столбец, измененный пользователем - PullRequest
9 голосов
/ 06 января 2012

У меня есть JTable, который использует TableColumnModelListener() для определения размера столбца, и у меня есть некоторый код, который я хочу выполнить в методе columnMarginChanged().

Как определить, был ли размер столбца изменен пользователем или в результате использования другого кода?

Я думаю, мне нужно начать с ChangeEvent.getSource(), но я не знаю, куда идти.

Спасибо.

Ответы [ 3 ]

7 голосов
/ 19 января 2012

Я могу дать вам один из возможных подходов.Я пытался решить ту же проблему, потому что хотел сериализовать информацию о ширине столбцов на диск, чтобы в следующий раз, когда таблица открывалась в моем приложении, я мог соответствующим образом восстановить ширину столбцов.Вот так:

Шаг 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 были частными внутренними классами моего основного класса приложения.Мой основной класс приложения придерживался ссылки на наблюдаемую таблицу.Следовательно, эти внутренние классы имели доступ к экземпляру таблицы.Очевидно, что в зависимости от вашей настройки вам нужно сделать соответствующую вещь, чтобы сделать экземпляр таблицы доступным для этих других классов.Надеюсь, это поможет!

4 голосов
/ 18 апреля 2013

Обычно вы хотите получать уведомления о завершении перетаскивания столбца или изменении размера завершенного столбца.Например,

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);
0 голосов
/ 15 сентября 2017

Более простым решением может быть просто прослушивание события отпускания мыши (которое происходит только один раз в этом взаимодействии с пользователем) и проверка, изменились ли размеры столбцов за это время? Я использую приведенный ниже код для прослушивания переупорядочения столбцов и изменения размера.

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...
   }});
...