JTable изменить выбор без мерцания интерфейса - PullRequest
0 голосов
/ 21 мая 2019

Я хочу изменить выбор в JTable. Типичным подходом является очистка и повторный выбор в соответствии с предложением здесь :

ListSelectionModel model = table.getSelectionModel();
model.clearSelection();
model.addSelectionInterval(1, 1);
model.addSelectionInterval(18, 18);

К сожалению, clearSelection немедленно обновляет интерфейс. Таким образом, если вы выполните этот код, выбор исчезнет, ​​а затем снова вернется, что может привести к мерцанию.

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

model.setValueIsAdjusting( true );
model.clearSelection();
model.setValueIsAdjusting( false );

Кажется, флаг игнорируется в пользовательском интерфейсе. Также удаление и повторное добавление ListSelectionListeners до, соответственно, после clearSelection не работало. Пользовательский интерфейс все еще обновляется и может мерцать.

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

Для меня это не главная проблема, потому что вам действительно нужно искать мерцание. Тем не менее, это не оптимально.

1 Ответ

0 голосов
/ 29 мая 2019

Проблема возникает, только если вы не участвуете в потоке рассылки событий (EDT). Слава Саше за подсказку.

Пример:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;

public class JTableExample extends JFrame
{
    private static final long serialVersionUID = 1L;

    private final JTable table;

    public JTableExample()
    {
        // headers and data for the table
        final String[] columns = new String[]{"Id", "Name"};
        final Object[][] data = new Object[][]{{1, "Alice"}, {2, "Bob"}, {3, "Charlie"},};

        // create table with data
        table = new JTable( data, columns );
        this.add( new JScrollPane( table ) );

        // Add key listener to trigger re-selection of columns
        table.addKeyListener( new KeyAdapter()
        {
            @Override
            public void keyReleased( final KeyEvent e )
            {
                // Re-select on event dispatch thread (EDT)
                if( e.getKeyCode() == KeyEvent.VK_1 )
                {
                    reselectTable();
                }

                // Re-select on a thread that is not the EDT
                if( e.getKeyCode() == KeyEvent.VK_2 )
                {
                    new Thread( () -> reselectTable() ).start();
                }

                // Re-select on a thread that is not the EDT, but using invokeLater to get back to the EDT
                if( e.getKeyCode() == KeyEvent.VK_3 )
                {
                    new Thread( () -> SwingUtilities.invokeLater( () -> reselectTable() ) ).start();
                }
            }
        } );

        // Setup JFrame
        setTitle( "JTable Example" );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        pack();
        setVisible( true );
    }

    public static void main( final String[] args )
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                new JTableExample();
            }
        } );
    }

    private void reselectTable()
    {
        System.out.println( "isEventDispatchThread:" + SwingUtilities.isEventDispatchThread() );

        final ListSelectionModel selectionModel = table.getSelectionModel();
        selectionModel.clearSelection();
        // PUT BREAKPOINT HERE
        // Selection in rendered GUI is gone here when not in the EDT
        selectionModel.addSelectionInterval( 0, 0 );
        selectionModel.addSelectionInterval( 2, 2 );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...