在动作侦听器中刷新JFrame [英] Refreshing a JFrame while in an Action Listener

查看:122
本文介绍了在动作侦听器中刷新JFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码段在JLabel中设置文本,该JLabel已添加到JPanel,该JPanel已附加到JFrame。无论我做什么(例如repaint(),revalidate()等),直到动作侦听器完成后,我才能获取UI更新文本。

The code snippet below sets text in a JLabel, which is added to a JPanel, which is attached to a JFrame. No matter what I do though (such as repaint(), revalidate(), etc) I cannot get the UI to update the text until the Action Listener is done.

我以前从来没有遇到过这个问题,可能是因为我从来没有在动作监听器中触发过几次事情。我缺少什么?

I have never had this problem before, possible because I have never had to have several things happen in a single firing of Action Listener. What am I missing?

TL; DR为什么以下命令在完成动作侦听器触发后才更新屏幕上的文本,即使我放入了repaint( )在每个listPanel.add()之后?

TL;DR Why does the following not update the text on the screen until it has finished firing the Action Listener, even if I put in repaint() after each listPanel.add()?

final JFrame guiFrame = new JFrame();
final JPanel listPanel = new JPanel();
listPanel.setVisible(true);
final JLabel listLbl = new JLabel("Welcome");
listPanel.add(listLbl);

startStopButton.addActionListener(new ActionListener(){@Override public void         actionPerformed(ActionEvent event){
     if(startStopButton.getText()=="Start"){
                startStopButton.setVisible(false);
                listPanel.remove(0);

     JLabel listLbl2 = new JLabel("Could not contact");
                listPanel.add(listLbl2);

     JLabel listLbl2 = new JLabel("Success");
                listPanel.add(listLbl2);
     }
}
guiFrame.setResizable(false);
guiFrame.add(listPanel, BorderLayout.LINE_START);
guiFrame.add(startStopButton, BorderLayout.PAGE_END);

//make sure the JFrame is visible
guiFrame.setVisible(true);

编辑:
我尝试实现SwingWorker,但直到动作接口完成触发后,接口才更新。这是我的SwingWorker代码:

I attempted to implement SwingWorker, but still the interface is not updating until the action interface finishes firing. Here is my SwingWorker code:

@Override
protected Integer doInBackground() throws Exception{
    //Downloads and unzips the first video.  
    if(cameraBoolean==true)
        panel.add(this.downloadRecording(camera, recording));
    else
        panel.add(new JLabel("Could not contact camera "+camera.getName()));

    panel.repaint();
    jframe.repaint();
    return 1;
}

private JLabel downloadRecording(Camera camera, Recording recording){
    //does a bunch of calculations and returns a jLabel, and works correctly
}

protected void done(){
    try{
        Date currentTime = new Timestamp(Calendar.getInstance().getTime().getTime());
        JOptionPane.showMessageDialog(jframe, "Camera "+camera.getName()+" finished downloading at "+currentTime.getTime());
    }catch (Exception e){
        e.printStackTrace();
    }
}

基本上,SwingWorker(按照我的实现)不是正确更新JPanel和JFrame。如果我尝试在 done()中进行重新绘制,则它们也不会更新。我还缺少什么?

Basically, SwingWorker (as I implemented it) is not properly updating the JPanel and JFrame. If I try to do the repaint in the "done()", they are not updated either. What am I missing?

此外,一旦JOptionPane显示自身,就无法再将其他面板添加到我的jframe中。我不确定是什么原因造成的。

Additionally, as soon as the JOptionPane displays itself, no more panels can be added to my jframe. I am unsure what is causing that either.

推荐答案

动作监听器正在事件调度线程。对于此类任务,请考虑使用 SwingWorker

The action listener is being executed on the Event Dispatch Thread. For tasks like that, consider using a SwingWorker.

这将使您能够处理逻辑,而不会阻止JFrame的更新(因此不会重新绘制)。

This would allow you to process your logic without blocking the updates (and thus the repaints) of the JFrame.

在高水平上,这就是我的意思:

At a high level, this is what I mean:

startStopButton.addActionListener(new ActionListener(){@Override public void         actionPerformed(ActionEvent event){
     if(startStopButton.getText()=="Start"){
          // Start SwingWorker to perform whatever is supposed to happen here.
     }

您可以找到有关如何使用<$ c的信息。 $ c> SwingWorker 此处,您是否需要它?

You can find some information on how to use SwingWorker here, should you need it.

这篇关于在动作侦听器中刷新JFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆