Swing GUI;能够在运行长进程时调整窗口大小,但主进程内的面板在进程完成之前不会更新

时间:2014-01-20 14:59:47

标签: java swing resize event-dispatch-thread invokelater

我尝试使用SwingUtilities.invokelater来允许我在我的长进程运行时调整大小并移动我的程序窗口。我得到的是我能够移动窗口并调整其大小,但内部组件不会更新,例如如果我将窗口的大小调整为大于它开始时的大小,我只需填充黑色就可以了。

我不太确定我哪里出错了,但我觉得我的面板/框架是如何安装的?任何帮助将不胜感激。

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

}

我的观点:

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

1 个答案:

答案 0 :(得分:2)

听起来你正在事件调度线程中运行长时间运行的进程,并阻止GUI进行更新。当事件派发线程忙于完成任务时,不会发生绘图,因为swing在同一个线程中完成所有工作。因此,在完成任务并且有机会完成其工作之后,更新GUI不会发生(如果任务是无限循环,则可能永远不会发生)。

该解决方案在后台运行耗时的任务。 SwingWorker通常是后台任务最方便的工具。