-1

I'd like to use SftpProgressMonitor's count() method to update the percentage of completion of a SFTP operation. I know it is better to use Worker threads in order not to block the UI, but I am curious on why this code does not update the table until the SFTP operation has completed:

public class MySftpProgressMonitor implements SftpProgressMonitor {

    JTable table = getTableReference();
    DefaultTableModel tableModel = getTableModelReference();
    
    @Override
    public boolean count(long bytes) {
        
        int percentage = computePercentage(bytes);
        table.setValueAt(percentage, 0, 1);
        
        return true;
    }

    @Override
    public void end() {
    }

    @Override
    public void init(int op, String src, String dest, long maxBytes) {
        Object[] rowData = {src, 0};
        tableModel.addRow(rowData);
    }

}

I don't see anything happening on the UI until the file transfer is completed (I see an entry whose percentage is 100%) and I wonder why. Since I am not using any additional threads, this code gets executed on the EDT, so it should be able to update UI components. I am also trying to explicitly call repaint() , table.repaint() and revalidate() but nothing happens.

I am reading TFM but can't figure out what is the error here. Thank you.

Alessandro
  • 97
  • 6
  • 1
    In eccesnse, unless you use a worker thread, if you are doing something (SFTP transfer) in your swing application thread nothing will happen until it's done with what you asked it to do. – BernardV Jul 11 '23 at 07:17
  • @BernardV thank you for your kind answer, but I still have some doubts: If everything is on a single thread and if I see that the execution hits "count()" for each chunk of data transferred, then why doesn't the UI get updated? The execution here is sequential – Alessandro Jul 11 '23 at 08:01
  • Perhaps have a look here: https://stackoverflow.com/a/13520062/3324415 and here: https://stackoverflow.com/a/7158505/3324415 – BernardV Jul 11 '23 at 08:05
  • @BernardV thank you so much again. They say "Swing components and models should be created, modified, and queried only from the event-dispatching thread". The thing is that I am on the EDT. In fact, if I call SwingUtilities.isEventDispatchThread(), it returns true. According to this, it should be able to edit UI components. What am I missing? Again thank you. – Alessandro Jul 11 '23 at 09:03
  • A single thread can only execute a single set of instructions. If you're doing non-GUI work on the EDT, the GUI **cannot update**. Period. That's why the EDT is reserved for Swing components and only Swing components. – Gilbert Le Blanc Jul 11 '23 at 09:50

1 Answers1

0

For whoever might be interested, this appears to be the main reason on why the UI seems to be frozen even if the UI changes are performed on the Event Dispatch Thread:

  1. When calling table.setValueAt(percentage, 0, 1); the underlying table's structure gets modified as expected and generates a repaint request;
  2. The repaint request gets handled by the repaint manager which is responsable for the repaint process and it is executed on the EDT after the EDT becomes idle, and serves the rapaint requests in the order they were scheduled.

This means that if the EDT is not idle, the UI will not be repainted. The EDT is not idle because it's processing a SFTP transfer. Easy :-)

Alessandro
  • 97
  • 6