【问题标题】:JTable change selection without flickering uiJTable更改选择而不闪烁ui
【发布时间】:2019-05-29 20:05:15
【问题描述】:

我想更改 JTable 中的选择。一种典型的做法是按照here的建议清除并重新选择:

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

遗憾的是,clearSelection 会立即更新 UI。因此,如果您单步执行此代码,选择会消失,然后再次返回,这可能会导致闪烁。

我试图通过忽略更改来阻止 UI 更新。但是,以下方法不起作用:

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

似乎该标志在 UI 中被忽略了。在 clearSelection 之前和之后分别删除和重新添加 ListSelectionListeners 不起作用。 UI 仍在更新,可能会闪烁。

是否有更好的方法来更改具有多行的 JTable 的完整选择,可能不是连续选择?

对我来说,这不是一个大问题,因为您确实需要寻找闪烁。尽管如此,它并不是最优的。

【问题讨论】:

  • 我使用clearSelection 时没有闪烁。正如@AndrewThompson 提到的那样,我建议您添加更多代码以获得帮助。
  • 您的问题可能是您在event dispatch thread 中没有这样做。

标签: java swing jtable


【解决方案1】:

仅当您不在事件调度线程 (EDT) 上时才会出现此问题。感谢 Sascha 提供的提示。

例子:

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

【讨论】:

猜你喜欢
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
相关资源
最近更新 更多