绘画画布和System.out.println()不起作用

时间:2016-03-18 11:54:59

标签: java swing canvas println

JFrame有一个开始按钮,触发Julia Set的计算。 单击开始按钮时执行的代码如下:

public void actionPerformed(ActionEvent aActionEvent) 
{
    String strCmd = aActionEvent.getActionCommand();

    if (strCmd.equals("Start")) 
    {
        m_cCanvas.init();
        m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
        m_bRunning = true;
        this.handleCalculation();
    }
    else if (aActionEvent.getSource() == m_cTReal)

以前工作正常,但应用程序无法再关闭。因此,我尝试在单独的方法中使用m_bRunning,以便始终不会阻止actionPerformed()查看是否有帮助,然后在方法{{1}中设置m_bRunning = false当窗口关闭时调用它:

stop()

方法public void run() { if(m_bRunning) { this.handleCalculation(); } } 是从run()循环中的主类调用的。

但遗憾的是,这既没有解决问题,也没有任何输出到画布或while(true)的任何调试跟踪。有人能指出我正确的方向吗?

修改

以下是整个文件:

System.out.println()

2 个答案:

答案 0 :(得分:2)

我引用@MadProgrammer最近的评论(包括链接)

“Swing是单线程的,你无法做任何改变,所有事件都被发布到事件队列并由事件调度线程处理,有关详细信息,请参阅Concurrency in Swing并查看Worker Threads and SwingWorker至少有一个可能的解决方案“

代码中只有一个主题。该线程忙于进行计算,无法响应位于GUI中的事件。您必须在另一个定期更新窗口中显示的数量的线程中分离计算。更多关于链接的信息,由@MadProgrammer提供,我坚持。

更新:正如@Yusuf指出的那样,启动JFrame的正确方法是

        SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
        }
        });

在构造中设置框架可见,并在按下开始按钮时开始计算。

答案 1 :(得分:1)

首先;

无限循环不是一种正确的方法。这部分是循环和CPU,永远不会给画布刷新屏幕。如果您添加以下代码,您的代码将按预期运行。但这不是正确的解决方案。

cMain.java:

 public static void main(String[] args) {
            int windowWidth = 1000;// (int)screenSize.getWidth() - 200;
            int windowHeight = 800;// (int)screenSize.getHeight() - 50;
            int plotWidth = 400;// (int)screenSize.getWidth() - 600;
            int plotHeight = 400;// (int)screenSize.getHeight() - 150;

            JuliaSet cJuliaSet = new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
            cJuliaSet.setVisible(true);
           //While loop removed
        }

第二:点击开始按钮时可以调用run方法。但是你应该在run方法中创建一个不冻结屏幕的线程。

if (strCmd.equals("Start")) {
            m_cCanvas.init();
            m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
            m_bRunning = true;
            this.run();   // added call run method.
        } else if (aActionEvent.getSource() == m_cTReal) {

的actionPerformed:

public void run()
    {
        if(m_bRunning)
        {
            new Thread(){ //Thread to release screen
                @Override
                public void run() {
                    JuliaSet.this.handleCalculation();
                }
            }.start(); //also thread must be started
        }
    }

运行方法:

{{1}}

正如@RubioRic所说,SwingUtilities.invokeLater方法也是解决方案的一部分。但是你需要检查整个代码,你应该了解Threads。