Взаимодействие с визуализатором ячеек в JTable

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


person NewlessClubie    schedule 22.09.2010    source источник


Ответы (2)


Никогда не пробовал, но я думаю, вам нужно:

а) создать собственный рендерер для рисования ячейки в двух состояниях

б) вам нужно следить за тем, какая ячейка в данный момент должна быть закрашена в состоянии «наведение мыши»

c) добавить прослушиватель мыши для отслеживания входа/выхода мыши и перемещения мыши. С каждым событием вам нужно будет обновлять переменную, которая отслеживает, над какой ячейкой находится мышь. Вы можете использовать методы columnAtPoint() и rowAtPoint() JTable.

г) когда мышь покидает ячейку, вам нужно вызвать repaint() для ячейки. Вы можете использовать метод getCellRect(), чтобы определить, какую ячейку нужно перекрасить.

e) когда мышь входит в ячейку, вам нужно сбросить значение ячейки для состояния «наведение мыши», а затем перекрасить ячейку.

person camickr    schedule 22.09.2010
comment
Чтобы уточнить немного: помните, что средство визуализации ячеек (в таблице, списке, комбо и т. д.) всегда является просто резиновым штампом, поэтому вам нужно добавить прослушиватель мыши в свою таблицу, а затем делегировать его вашему пользовательскому средству визуализации/редактора, используя columnAtPoint и rowAtPoint чтобы выяснить, где находится точка мыши, как упоминал @camickr. - person Geoffrey Zheng; 22.09.2010
comment
Как я должен сказать jtable, чтобы получить и отобразить новый модуль рендеринга ячеек по моей команде? - person NewlessClubie; 23.09.2010
comment
Запрос repaint() должен делать это. - person camickr; 23.09.2010

Итак, я попытался реализовать подход camickr, но в процессе столкнулся с очень неприятной проблемой. Я добавил MouseMotionListener в JTable, чтобы отслеживать текущую и предыдущую ячейку, и добавил несколько методов, которые сообщают средству визуализации, какой компонент следует вернуть, а затем перерисовывают соответствующую ячейку. Однако по какой-то странной причине каждая ячейка перерисовывается дважды, хотя был только один запрос на перерисовку. По сути, я мог выделить ячейку при наведении курсора мыши, но было невозможно удалить выделение из ячейки после того, как курсор мыши покинул ее. После первоначальной путаницы я решил сделать это по-другому. Я добавил метод, который вызывает редактор, когда мышь находится над ячейкой, а затем добавил некоторый код, который прекращает редактирование, как только изменяется состояние JToggleButton (мой компонент рендеринга и редактирования). Мой текущий код выглядит так:

package guipkg;

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

public class Grid extends JTable implements MouseListener {

int currentCellColumn = -1;
int currentCellRow = -1;
int previousCellColumn = -1;
int previousCellRow = -1;

public void detectCellAtCursor (MouseEvent e) {
    Point hit = e.getPoint();
    int hitColumn = columnAtPoint(hit);
    int hitRow = rowAtPoint(hit);
    if (currentCellRow != hitRow || currentCellColumn != hitColumn) {
        this.editCellAt(hitRow, hitColumn);
        currentCellRow = hitRow;
        currentCellColumn = hitColumn;
    }

}


}







package guipkg;

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


public class TCEditor extends AbstractCellEditor implements TableCellEditor  {

    /**
     * A toggle button which will serve as a cell editing component
     */

    JToggleButton togglebutton = new JToggleButton();





    public Component getTableCellEditorComponent (JTable Table, Object value, boolean isSelected, int rindex, int cindex) {

        /**
         * We're adding an action listener here to stop editing as soon as the state of JToggleButton is switched.
         * This way data model is updated immediately. Otherwise updating will only occur after we've started to
         * edit another cell.
         */

        togglebutton.addActionListener(new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                stopCellEditing();
            }
        });


        if (value.toString().equals("true")) {
            togglebutton.setSelected(true);
        }
 else {
            togglebutton.setSelected(false);
 }
        togglebutton.setBorderPainted(false);
        return togglebutton;
    }

    public Object getCellEditorValue () {
        return togglebutton.isSelected();
    }


}

Я надеюсь, что это поможет кому-то

person NewlessClubie    schedule 25.09.2010