Java Swing 在循环中运行多个模拟 [英] Java Swing running multiple simulations in a loop

查看:32
本文介绍了Java Swing 在循环中运行多个模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个简单的模拟,其中 2 个以不同速度移动的球尝试移动到画面的中间,然后移回它们的起始位置.在指定的 totalTime 结束时,我结束模拟并记录此数据.

我的问题是,是否可以自动循环并运行多个模拟?目前,当我的 totalTime 启动时,动画会冻结但窗口不会关闭.理想情况下,我想,我希望看到旧窗口关闭并弹出一个新窗口,其中包含不同球的新速度.

所以我的代码看起来像这样:

 public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){双 rSpeed = 0;JFrame frame = new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);frame.setSize(500, 500);矩形 r = frame.getBounds();frame.add(new MoveAgents(r.getWidth(), rSpeed));}});}公共移动代理(双 w,双 rFrameSpeed){//初始化我的2个球及其速度和起始位置定时器 timer = new Timer(15, null);timer.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {总时间++;如果(总时间 == 1000){定时器停止();尝试 {generateCsvFile(OUTPUT_FILE);} catch (IOException e1) {//TODO 自动生成的 catch 块e1.printStackTrace();}}//否则,做事}}

解决方案

是否可以自动循环并运行多个模拟?

是的.当模拟结束时,不要尝试替换视图.相反,

  • Timer 上调用 stop().

  • 调用 generateCsvFile() 来保存结果.

  • 完全按照第一次的方式初始化模拟模型.

  • Timer 上调用 restart().

在下面的例子中,模型是一个名为 dataint,模拟简单地渲染它并增加到 1000.重复模拟次数的 count 作为参数传递给 Simulation 构造函数.代替 frame.setSize(),覆盖绘图面板的 getPreferredSize(),如所讨论的

import java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.Font;导入 java.awt.Graphics;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.Timer;/*** @see https://stackoverflow.com/a/372​​93513/230513*/公共类 SimTest {私人无效显示(){JFrame f = new JFrame("SimTest");f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.add(new Simulation(8));f.pack();f.setLocationRelativeTo(null);f.setVisible(true);}私有静态类模拟扩展 JPanel {私有最终字体字体 = this.getFont().deriveFont(36f);私有整数计数;私有整数数据;Timer t = new Timer(100, new ActionListener() {@覆盖public void actionPerformed(ActionEvent e) {重绘();如果((数据+= 100)== 1000){停止();System.out.println("保存结果...");//generateCsvFile();如果 (--count == 0) {System.out.println("完成!");System.exit(0);} 别的 {在里面();t.restart();}}}});公共模拟(整数计数){this.count = 计数;在里面();t.start();}私有无效初始化(){数据 = 0;}@覆盖受保护的无效paintComponent(图形g){super.paintComponent(g);g.setFont(字体);g.drawString(String.valueOf(data), 8, g.getFontMetrics().getHeight());}@覆盖公共维度 getPreferredSize() {返回新维度(256, 128);}}公共静态无效主(字符串 [] args){EventQueue.invokeLater(new SimTest()::display);}}

I have coded up a simple simulation where 2 balls moving at different speeds try to move to the middle of the frame and then move back to their starting positions. At the end a specified, totalTime, I end the simulation and I record this data.

My question is, is it possible to loop through and run multiple simulations automatically? Currently, when my totalTime is up, the animation just freezes but the window doesn't close. Ideally I guess, I'd like to see the old window close and a new window pop up with new speeds for the different balls.

So my code looks something like this:

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

        @Override
        public void run() {
            double rSpeed = 0;
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            frame.setSize(500, 500);
            Rectangle r = frame.getBounds();
            frame.add(new MoveAgents(r.getWidth(), rSpeed));
        }            
    });
}

public MoveAgents(double w, double rFrameSpeed) {
     //initialize my 2 balls and their speeds and starting locations

    Timer timer = new Timer(15, null);
    timer.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            totalTime++;

            if (totalTime == 1000) {
                timer.stop();

                try {
                    generateCsvFile(OUTPUT_FILE);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
          //otherwise, do things 
    }
 }

解决方案

Is it possible to loop through and run multiple simulations automatically?

Yes. When the simulation ends, don't try to replace the view. Instead,

  • Invoke stop() on the Timer.

  • Invoke generateCsvFile() to save the results.

  • Initialize the simulation's model exactly as done the first time.

  • Invoke restart() on the Timer.

In the example below, the model is an int named data, which the simulation simply renders and increments to 1000. A count of the number of times to repeat the simulation is passed as a parameter to the Simulation constructor. Instead of frame.setSize(), override the drawing panel's getPreferredSize() as discussed here.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * @see https://stackoverflow.com/a/37293513/230513
 */
public class SimTest {

    private void display() {
        JFrame f = new JFrame("SimTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new Simulation(8));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static class Simulation extends JPanel {

        private final Font font = this.getFont().deriveFont(36f);
        private int count;
        private int data;
        Timer t = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
                if ((data += 100) == 1000) {
                    t.stop();
                    System.out.println("Saving results…");//generateCsvFile();
                    if (--count == 0) {
                        System.out.println("Fin!");
                        System.exit(0);
                    } else {
                        init();
                        t.restart();
                    }
                }
            }
        });

        public Simulation(int count) {
            this.count = count;
            init();
            t.start();
        }

        private void init() {
            data = 0;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setFont(font);
            g.drawString(String.valueOf(data), 8, g.getFontMetrics().getHeight());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(256, 128);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new SimTest()::display);
    }
}

这篇关于Java Swing 在循环中运行多个模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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