0

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);
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Peck3277
  • 1,383
  • 8
  • 22
  • 46
  • Where's your long running process? There doesn't seem to be anything wrong with the code posted. – Harald K Jan 20 '14 at 15:14
  • 1
    Sounds like you're running the long running process in the event dispatch thread, and that blocks the GUI from updating. [SwingWorker](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) is usually a good way to do the time consuming task in the background. – kiheru Jan 20 '14 at 15:16
  • My long running process will be in the model, at the moment I'm testing it with a loop and Thread.sleep(1000); @kiheru, that most likely is it, I was planning on putting in a swingworker but wanted to get this working first. I'll give it a shot. Thanks! – Peck3277 Jan 20 '14 at 15:16
  • 1
    You're welcome :-) That's the most typical cause for UI freezes. – kiheru Jan 20 '14 at 15:19
  • Looks like your solution was correct. Do you want to give a full answer so I can mark it as accepted? – Peck3277 Jan 20 '14 at 15:44
  • 1
    OK. I'll try to write something more complete, even though the comment already has all the meat. Having an accepted answer will make it easier for the others. – kiheru Jan 20 '14 at 15:49

1 Answers1

2

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.

kiheru
  • 6,588
  • 25
  • 31