gpt4 book ai didi

java - 多个 JFrame 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:08:09 25 4
gpt4 key购买 nike

这里的问题是,在通过设置 JFrame 询问用户神经网络的设置后,旨在可视化网络学习的新 JFrame 似乎只在网络完成对所有数据的循环后显示一些东西

我相信这是因为我使用了 SwingWorker 并且循环不会等待它完成计算并在进入下一个循环之前显示结果。

第 1 步:我使用 JFrame 向用户询问参数

public class Settings {

private int width = 1920 / 4;
private int height = 1080 / 4;

private JFrame settings;
private JButton startButton;

public static void main(String[] args) {
Settings settings = new Settings();
settings.start();
}

private void start() {
settings = new JFrame();
settings.setTitle("Settings");
settings.setSize(width, height);
settings.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

startButton = new JButton("start");
startButton.addActionListener(new FieldListener());
settings.getContentPane().add(startButton);

settings.pack();
settings.setVisible(true);
}

class FieldListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
prepare();
}
}
}

public void prepare() {
Control control = new Control();
control.start(amountOfNeurons);
}

第 2 步:控制类使用指定参数创建神经网络,然后向其提供数据

public class Control {

public void start(int amountOfNeurons) {
Network net = new Network(amountOfNeurons);
int[][] data = getData();
net.startLearning(data);
}

第 3 步:网络遍历给定的数据以进行学习

public class Network {

int amountOfNeurons;
Visualiser vis;

public Network(int amountOfNeurons) {
this.amountOfNeurons = amountOfNeurons;
}

public void startLearning(int[][] data) {
vis = new Visualiser();
JFrame graph = new JFrame();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setSize(1920, 1080);
graph.setTitle("Graph");
graph.getContentPane().add(vis);
graph.setResizable(false);
graph.pack();
graph.setVisible(true);

for(int i = 0; i < data.length; i++) {
new TrainTask(data[i]);
}
}

class TrainTask extends SwingWorker<Void,Void> {
int[] data;


public TrainTask(int[] data) {
this.data = data;
}

@Override
public Void doInBackground() {
for(int i = 0; i < data.length; i++) {
calculate(data);
vis.result = calculate(data);
vis.repaint();
System.out.println(i);
}
return null;
}
}

正如@c0der 和@Frakcool 所建议的那样,我使用 SwingWorker 来完成繁重的负载,即循环遍历数据并更新可视化工具

但是程序继续运行而不等待 SwingWorker 的响应... 我想尝试 invokeAndWait() 让程序等待,但是网络本身运行在 EDT 上,所以它导致程序崩溃。

我应该怎么做?

附言我想指出的是,当我不创 build 置类,而是从控制类中的主要方法创建网络时,一切似乎都工作正常......

最佳答案

发布的代码不是 mcve,因为从未调用过 prepareNetwork 执行了一个阻塞 EDT 的长进程.一旦这个过程被调用,它后面的语句直到长过程结束才被执行。
这可以通过这个 mcve 轻松地证明
:

import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Network {

Network() throws InterruptedException {

Visualiser visualiser = new Visualiser();
JFrame graph = new JFrame();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setLocation(new Point(150,150));
graph.getContentPane().add(visualiser);
graph.pack();
graph.setVisible(true);

for(int i = 0; i < 100; i++) {
visualiser.setText(String.valueOf(i));
Thread.sleep(500);
visualiser.repaint();
}
}

public static void main(String[] args) throws InterruptedException {
JFrame settings = new JFrame();
settings.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
settings.add(new JLabel("settings"));
new Network(); //invoke Network before settings is made visible
settings.pack();
settings.setVisible(true);
}
}

class Visualiser extends JPanel {

JLabel lable;
Visualiser(){
lable = new JLabel("0");
add(lable);
}

void setText(String s) {
lable.setText(s);
}
}

设置仅在计数结束后才可见。
将执行顺序更改为

settings.setVisible(true);
new Network();

导致 settings 在执行计数之前显示。
然而,这不是解决此问题的正确方法。它被张贴来解释问题。
不应在 EDT 上调用长进程。正如 Fracool 所建议的,正确的解决方案是使用 SwingWorker将漫长的过程从 EDT 中移除:

public class Network {

Visualiser visualiser;
Network() throws InterruptedException {

visualiser = new Visualiser();
JFrame graph = new JFrame();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setLocation(new Point(150,150));
graph.getContentPane().add(visualiser);
graph.pack();
graph.setVisible(true);
new VisulizerUpdateTask().execute();
}

//use swing worker perform long task
class VisulizerUpdateTask extends SwingWorker<Void,Void> {

@Override
public Void doInBackground() {
for(int i = 0; i < 100; i++) {
visualiser.setText(String.valueOf(i));
try {
Thread.sleep(500);
} catch (InterruptedException ex) { ex.printStackTrace(); }
visualiser.repaint();
}
return null;
}
}

public static void main(String[] args) throws InterruptedException {
JFrame settings = new JFrame();
settings.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
settings.add(new JLabel("settings"));
new Network();
settings.pack();
settings.setVisible(true);
}
}

另请注意 Andrew Thompson 发布的链接。

关于java - 多个 JFrame 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50881847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com