我需要一种简单的方法来从另一个类调用Java的swingworker publish()方法

时间:2018-10-12 00:14:00

标签: java multithreading swing user-interface swingworker

下面的代码工作正常。我唯一需要的是能够从Bot()类内部将结果发布()到Swingworker吗?

我在整个网络上搜索都无济于事。这个Answer对我不起作用。

JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        Bot test = new Bot();
        SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
            @Override
            protected Void doInBackground() throws Exception {
                test.run();
                return null;
            }

            @Override
            public void process(List<String> chunks) {
                for (String s : chunks) {
                    textAreaMain.setText(s);
                }
            }

        };
        worker.execute();
    }
});

btnStart.setBounds(305, 179, 95, 25);
panel_1.add(btnStart);

另一种方法

// Bot类具有

class Bot {
    void run() {
        for (int i = 0; i <= 10; i++) {
            Thread.sleep(1000);
            publish("Some message");
        }
    }
}

以示例为例,如何编写Bot()类以获取所需的内容?

2 个答案:

答案 0 :(得分:3)

我将为Bot类的test方法提供一个参数,该参数接受单个参数String函数,回调并通过此方法进行回调。

但是实际上任何回调都可以,但是Java 8函数引用可以完美地工作。

例如

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import javax.swing.*;

public class FooJPanel extends JPanel {
    private JButton btn = new JButton("Button");
    private JTextArea textAreaMain = new JTextArea(20, 20);

    public FooJPanel() {
        textAreaMain.setFocusable(false);
        add(new JScrollPane(textAreaMain));
        add(btn);

        btn.addActionListener(e -> {
            final Bot bot = new Bot();
            SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
                @Override
                protected Void doInBackground() throws Exception {
                    bot.run(this::publish); // thanks Vince Emigh
                    return null;
                }

                @Override
                public void process(List<String> chunks) {
                    for (String s : chunks) {
                        textAreaMain.append(s + "\n");
                    }
                }

            };
            worker.execute();
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Foo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new FooJPanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}

class Bot {

    public void run(Consumer<String> c) {
        for (int i = 0; i < 10; i++) {
            c.accept("String #" + i);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
        }
    }

}

但是任何回调或侦听器构造都可以使用,例如PropertyChangeListener。只要保持较低的耦合度和较高的内聚力,就应该做好。

答案 1 :(得分:1)

只需将SwingWorker作为参数传递给Bot类,并在SwingWorker中创建一个调用publish的方法即可。

class Bot {

    Task task;
    public Bot(Task task) {
        this.task = task;
    }

    void run() {
        task.publish2("Me");
    }
}

class Task extends SwingWorker<Void, String> {

    @Override
    protected Void doInBackground() throws Exception {

    }

    void publish2(String str) {
        publish(str);
    }
}