Swing GUI; Able to resize window while running long process but panels inside main frame won't update until process is complete

StackOverflow https://stackoverflow.com/questions/21237193

Question

I trying to use SwingUtilities.invokelater to allow me to resize and move my programs window about while my long process is running. What I'm getting is that I'm able to move the window and resize it but the components inside don't update e.g. If I resize the window to being larger than it was when it started I just get black colour filling it.

I'm not quite sure where I'm going wrong but I feel like it's how I have my panels/frames setup? Any help would be appreciated.

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        System.out.println("Error setting system look and feel: "+e);
    }       

    SwingUtilities.invokeLater(new Runnable(){

        @Override
        public void run(){      

            BrowseModel model = new BrowseModel();
            BrowseView view = new BrowseView(model);
            BrowseController controller = new BrowseController(model, view);

            view.setVisible(true);
        }
    });

}

My View:

BrowseView(BrowseModel model){
    m_model = model;

    JScrollPane targetUrlScroller = new JScrollPane(m_targetURLs);
    targetUrlScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    targetUrlScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    targetUrlScroller.setAlignmentX(Component.LEFT_ALIGNMENT);

    m_resultsTable = new JTable(table_model);
    table_model.addColumn("Locale");
    table_model.addColumn("URL");
    table_model.addColumn("Product");
    table_model.addColumn("Category");
    table_model.addColumn("Filter");
    table_model.addColumn("Article Title");
    table_model.addColumn("Article Image");
    table_model.addColumn("Article Description");
    table_model.addColumn("Article URL");
    m_resultsTable.setFillsViewportHeight(true);

    JScrollPane resultsScroller = new JScrollPane(m_resultsTable);
    resultsScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    resultsScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    resultsScroller.setAlignmentX(Component.LEFT_ALIGNMENT);

    JPanel localeSelection = new JPanel();
    localeSelection.add(new JLabel("Locales:"));
    localeSelection.add(m_selectLocale = new JComboBox(getLocales().toArray()));
    localeSelection.setLayout(new FlowLayout(FlowLayout.RIGHT));
    localeSelection.setAlignmentX(Component.LEFT_ALIGNMENT);

    JPanel buttonsPanel = new JPanel();
    buttonsPanel.add(m_currentStatus);
    buttonsPanel.add(m_clearButton);
    buttonsPanel.add(m_runButton);
    buttonsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    buttonsPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));   

    JPanel content = new JPanel();
    content.setBorder(new EmptyBorder(10, 10, 10, 10));
    content.setAlignmentX(Component.LEFT_ALIGNMENT);
    content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
    content.add(localeSelection);
    content.add(new JLabel("Target URLs:"));
    content.add(targetUrlScroller);
    content.add(new JLabel("Results:"));
    content.add(resultsScroller);
    content.add(buttonsPanel);

    this.setContentPane(content);
    this.pack();

    this.setMinimumSize(new Dimension(900,600));

    this.setTitle("Browse Page Inspector");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Was it helpful?

Solution

Sounds like you're running the long running process in the event dispatch thread, and that blocks the GUI from updating. While the event dispatch thread is busy completing the task, no drawing can happen, as swing does all its work in the same thread. Thus updating the GUI can not happen until the task has been completed and swing is given a chance to do its work (which can be never, if the task is an infinite loop).

The solution is running time consuming tasks in the background. SwingWorker is usually the most convenient tool for background tasks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top