简体   繁体   English

您可以使用在后台运行in的方法中的发布吗?

[英]Can you use publish from a method called in run in background?

I am using swingworker to run a method in the background and periodically update the gui with information, but from what I've found publish can't be called from another class. 我正在使用swingworker在后台运行方法并定期用信息更新gui,但是根据我发现的发布,不能从另一个类调用它。 Here's where my Swingworker is called: 这是我的Swingworker的名称:

private void start() {
    worker = new SwingWorker <Void, String>() {

        @Override
        protected Void doInBackground() throws Exception {
            navigator.navigator();

            return null;
        }
        @Override
        protected void process(List<String> chunks) {
            for (String line : chunks) {
                txtrHello.append(line);
                txtrHello.append("\n");
            }
        }
        @Override
        protected void done() {

        }

    };
    worker.execute();
}

And now from the navigator method I want to call publish(String); 现在从导航器方法中我想调用publish(String); , how would I do this? ,我该怎么做? Moving all of my methods into doInBackground() would be impossible. 将所有方法都移到doInBackground()是不可能的。

Possible solution is to add an observer to your Navigator object, the key being to somehow allow the Navigator to communicate with any listener (here the SwingWorker) that its state has changed: 可能的解决方案是向您的Navigator对象添加一个观察者,关键是以某种方式允许Navigator与状态已更改的任何侦听器(此处为SwingWorker)进行通信:

  • Give Navigator a PropertyChangeSupport object as well as an addPropertyChangeListener(PropertyChangeListener listener) method that adds the passed in listener to the support object. 给Navigator一个PropertyChangeSupport对象以及一个addPropertyChangeListener(PropertyChangeListener listener)方法,该方法将传入的侦听器添加到支持对象。
  • Give Navigator some type of "bound" property, a field that when its state is changed, often in a setXxxx(...) type method, notifies the support object of this change. 给Navigator提供某种类型的“绑定”属性,该字段通常在setXxxx(...)类型方法中更改其状态时,将此更改通知支持对象。
  • Then in your SwingWorker constructor, add a PropertyChangeListener to your Navigator object. 然后在您的SwingWorker构造函数中,将PropertyChangeListener添加到导航器对象。
  • In this listener, call the publish method with the new data from your Navigator object. 在此侦听器中,使用来自Navigator对象的新数据调用publish方法。

For example: 例如:

import java.awt.event.ActionEvent;
import java.beans.*;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class PropChangeSupportEg extends JPanel {
   private MyNavigator myNavigator = new MyNavigator();
   private JTextField textField = new JTextField(10);

   public PropChangeSupportEg() {
      textField.setFocusable(false);
      add(textField);
      add(new JButton(new StartAction("Start")));
      add(new JButton(new StopAction("Stop")));
   }

   private class StartAction extends AbstractAction {
      public StartAction(String name) {
         super(name);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         if (myNavigator.isUpdatingText()) {
            return; // it's already running
         }
         MyWorker worker = new MyWorker();
         worker.execute();
      }
   }

   private class StopAction extends AbstractAction {
      public StopAction(String name) {
         super(name);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         myNavigator.stop();
      }
   }

   private class MyWorker extends SwingWorker<Void, String> {
      @Override
      protected Void doInBackground() throws Exception {
         if (myNavigator.isUpdatingText()) {
            return null;
         }

         myNavigator.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
               if (MyNavigator.BOUND_PROPERTY_TEXT.equals(evt.getPropertyName())) {
                  publish(evt.getNewValue().toString());
               }
            }
         });
         myNavigator.start();
         return null;
      }

      @Override
      protected void process(List<String> chunks) {
         for (String chunk : chunks) {
            textField.setText(chunk);
         }
      }


   }

   private static void createAndShowGui() {
      PropChangeSupportEg mainPanel = new PropChangeSupportEg();

      JFrame frame = new JFrame("Prop Change Eg");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyNavigator {
   public static final String BOUND_PROPERTY_TEXT = "bound property text";
   public static final String UPDATING_TEXT = "updating text";
   private static final long SLEEP_TIME = 1000;
   private PropertyChangeSupport pcSupport = new PropertyChangeSupport(this);
   private String boundPropertyText = "";
   private String[] textArray = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
   private int textArrayIndex = 0;
   private volatile boolean updatingText = false;

   public void start() {
      if (updatingText) {
         return;
      }
      updatingText = true;
      while (updatingText) {
         textArrayIndex++;
         textArrayIndex %= textArray.length;
         setBoundPropertyText(textArray[textArrayIndex]);
         try {
            Thread.sleep(SLEEP_TIME);
         } catch (InterruptedException e) {}
      }
   }

   public void stop() {
      setUpdatingText(false);
   }

   public String getBoundPropertyText() {
      return boundPropertyText;
   }

   public boolean isUpdatingText() {
      return updatingText;
   }

   public void setUpdatingText(boolean updatingText) {
      boolean oldValue = this.updatingText;
      boolean newValue = updatingText;
      this.updatingText = updatingText;
      pcSupport.firePropertyChange(UPDATING_TEXT, oldValue, newValue);
   }

   public void setBoundPropertyText(String boundPropertyText) {
      String oldValue = this.boundPropertyText;
      String newValue = boundPropertyText;
      this.boundPropertyText = boundPropertyText;
      pcSupport.firePropertyChange(BOUND_PROPERTY_TEXT, oldValue, newValue);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调用静态方法时,是否可以要求调用单独的方法? - Can you require a separate method be called when a static method is called? 从另一个类调用方法时,无法运行方法的一部分 - Can't run part of method when method is called from another class 我如何知道何时可以从后台线程安全地调用方法? - How do I know when a method can be called safely from a background thread? 我无法在Spring的后台运行该方法 - I can not run the method in the background in Spring 你能直接从eclipse发布一个.war到web服务器吗? - Can you publish a .war directly from eclipse to a web server 在 Dataflow 模板中调用 waitUntilFinish() 之后可以运行代码吗? - Can you run code after waitUntilFinish() is called in a Dataflow template? 我可以在一个可以在稍后有while循环的main中调用的方法中使用break语句吗? - Can I use break statement in a method which can be later called from main where there is a while loop? 如何停止执行从线程的run()方法调用的方法 - How to stop execution of method called from run() method of thread 如何使用从Java中的方法调用的对象? - How to use an object that was called from a method in Java? 尝试将背景从白色更改为黑色但无法使此timer()方法运行,屏幕仅为白色 - Trying to change background from white to black but can't get this timer() method to run, the screen is only white
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM