首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >画布和System.out.println()不起作用

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

Stack Overflow用户
提问于 2016-03-18 11:54:58
回答 2查看 493关注 0票数 0

我有一个启动按钮的JFrame,它触发了一个朱莉娅集的计算。单击“开始”按钮时执行的代码如下:

代码语言:javascript
复制
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()就不会一直被阻塞,以查看这是否有用,然后在关闭窗口时调用的方法stop()中设置m_bRunning = false

代码语言:javascript
复制
public void run()
{
    if(m_bRunning)
    {
        this.handleCalculation();
    }
}

方法run()是从while(true)循环的主类调用的。

但不幸的是,这并没有解决问题,我现在也没有任何输出到画布或任何调试跟踪与System.out.println()。有人能为我指出正确的方向吗?

编辑:

以下是全部文件:

代码语言:javascript
复制
// cMain.java
package juliaSet;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.Dimension;

public class cMain {

    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(true)
        {  
            cJuliaSet.run();
        }
    }

}


// JuliaSet.java
package juliaSet;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.Random;
import java.io.*;
import java.lang.ref.*;

public class JuliaSet extends JFrame implements ActionListener 
{
    private JButton m_cBStart;
    private JTextField m_cTReal;
    private JTextField m_cTImag;
    private JTextField m_cTDivergThresh;
    private JLabel m_cLReal;
    private JLabel m_cLImag;
    private JLabel m_cLDivergThresh;
    private int m_iDivergThresh = 10;
    private String m_cMsgDivThresh = "Divergence threshold = " + m_iDivergThresh;
    private JuliaCanvas m_cCanvas;
    private int m_iPlotWidth; // number of cells
    private int m_iPlotHeight; // number of cells
    private Boolean m_bRunning = false;
    private double m_dReal = 0.3;
    private double m_dImag = -0.5;
    private String m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
    private String m_cMsgIter = "x = 0, y = 0";
    private Complex m_cCoordPlane[][];
    private double m_dAbsSqValues[][];
    private int m_iIterations[][];
    private Complex m_cSummand;
    private BufferedImage m_cBackGroundImage = null;
    private FileWriter m_cFileWriter;
    private BufferedWriter m_cBufferedWriter;
    private String m_sFileName = "log.txt";
    private Boolean m_bWriteLog = false;

    private static final double PLOTMAX = 2.0; // we'll have symmetric axes
                                                // ((0,0) at the centre of the
                                                // plot
    private static final int MAXITER = 0xff;

    JuliaSet(String aTitle, int aFrameWidth, int aFrameHeight, int aPlotWidth, int aPlotHeight) 
    {
        super(aTitle);
        this.setSize(aFrameWidth, aFrameHeight);
        m_iPlotWidth = aPlotWidth;
        m_iPlotHeight = aPlotHeight;
        m_cSummand = new Complex(m_dReal, m_dImag);

        m_cBackGroundImage = new BufferedImage(aFrameWidth, aFrameHeight, BufferedImage.TYPE_INT_RGB);

        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                stop();
                super.windowClosing(e);
                System.exit(0);
            }
        });

        GridBagLayout cLayout = new GridBagLayout();
        GridBagConstraints cConstraints = new GridBagConstraints();

        this.setLayout(cLayout);
        m_cCanvas = new JuliaCanvas(m_iPlotWidth, m_iPlotHeight);
        m_cCanvas.setSize(m_iPlotWidth, m_iPlotHeight);

        m_cBStart = new JButton("Start");
        m_cBStart.addActionListener(this);
        m_cTReal = new JTextField(5);
        m_cTReal.addActionListener(this);
        m_cTImag = new JTextField(5);
        m_cTImag.addActionListener(this);
        m_cTDivergThresh = new JTextField(5);
        m_cTDivergThresh.addActionListener(this);
        m_cLReal = new JLabel("Re(c):");
        m_cLImag = new JLabel("Im(c):");
        m_cLDivergThresh = new JLabel("Divergence Threshold:");

        cConstraints.insets.top = 3;
        cConstraints.insets.bottom = 3;
        cConstraints.insets.right = 3;
        cConstraints.insets.left = 3;

        // cCanvas
        cConstraints.gridx = 0;
        cConstraints.gridy = 0;
        cLayout.setConstraints(m_cCanvas, cConstraints);
        this.add(m_cCanvas);

        // m_cLReal
        cConstraints.gridx = 0;
        cConstraints.gridy = 1;
        cLayout.setConstraints(m_cLReal, cConstraints);
        this.add(m_cLReal);

        // m_cTReal
        cConstraints.gridx = 1;
        cConstraints.gridy = 1;
        cLayout.setConstraints(m_cTReal, cConstraints);
        this.add(m_cTReal);

        // m_cLImag
        cConstraints.gridx = 0;
        cConstraints.gridy = 2;
        cLayout.setConstraints(m_cLImag, cConstraints);
        this.add(m_cLImag);

        // m_cTImag
        cConstraints.gridx = 1;
        cConstraints.gridy = 2;
        cLayout.setConstraints(m_cTImag, cConstraints);
        this.add(m_cTImag);

        // m_cLDivergThresh
        cConstraints.gridx = 0;
        cConstraints.gridy = 3;
        cLayout.setConstraints(m_cLDivergThresh, cConstraints);
        this.add(m_cLDivergThresh);

        // m_cTDivergThresh
        cConstraints.gridx = 1;
        cConstraints.gridy = 3;
        cLayout.setConstraints(m_cTDivergThresh, cConstraints);
        this.add(m_cTDivergThresh);

        // m_cBStart
        cConstraints.gridx = 0;
        cConstraints.gridy = 4;
        cLayout.setConstraints(m_cBStart, cConstraints);
        this.add(m_cBStart);
        if (m_bWriteLog) 
        {
            try 
            {
                m_cFileWriter = new FileWriter(m_sFileName, false);
                m_cBufferedWriter = new BufferedWriter(m_cFileWriter);
            } catch (IOException ex) {
                System.out.println("Error opening file '" + m_sFileName + "'");
            }
        }

        this.repaint();

        this.transformCoordinates();
    }

    public synchronized void stop() 
    {
        if (m_bRunning) 
        {
            m_bRunning = false;
            boolean bRetry = true;
        }
        if (m_bWriteLog) 
        {
            try {
                m_cBufferedWriter.close();
                m_cFileWriter.close();
            } catch (IOException ex) {
                System.out.println("Error closing file '" + m_sFileName + "'");
            }
        }
    }
    public void collectGarbage() 
    {
        Object cObj = new Object();
        WeakReference ref = new WeakReference<Object>(cObj);
        cObj = null;
        while(ref.get() != null) {
            System.gc();
        }
    }

    public void setSummand(Complex aSummand) 
    {
        m_cSummand.setIm(aSummand.getIm());
        m_dImag = aSummand.getIm();
        m_cSummand.setRe(aSummand.getRe());
        m_dReal = aSummand.getRe();
        m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
    }

    public void paint(Graphics aGraphics) 
    {
        Graphics cScreenGraphics = aGraphics;
        // render on background image
        aGraphics = m_cBackGroundImage.getGraphics();

        this.paintComponents(aGraphics);
        // drawString() calls are debug code only....
        aGraphics.setColor(Color.BLACK);
        aGraphics.drawString(m_cSMsg, 10, 450);
        aGraphics.drawString(m_cMsgIter, 10, 465);
        aGraphics.drawString(m_cMsgDivThresh, 10, 480);

        // rendering is done, draw background image to on screen graphics
        cScreenGraphics.drawImage(m_cBackGroundImage, 0, 0, null);
    }

    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;
        } 
        else if (aActionEvent.getSource() == m_cTReal) 
        {
            m_dReal = Double.parseDouble(m_cTReal.getText());
            m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
            m_cSummand.setRe(m_dReal);
        } 
        else if (aActionEvent.getSource() == m_cTImag) 
        {
            m_dImag = Double.parseDouble(m_cTImag.getText());
            m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
            m_cSummand.setIm(m_dImag);
        } 
        else if (aActionEvent.getSource() == m_cTDivergThresh) 
        {
            m_iDivergThresh = Integer.parseInt(m_cTDivergThresh.getText());
            m_cMsgDivThresh = "Divergence threshold = " + m_iDivergThresh;
        }

        this.update(this.getGraphics());
    }

    public void transformCoordinates() 
    {
        double dCanvasHeight = (double) m_cCanvas.getHeight();
        double dCanvasWidth = (double) m_cCanvas.getWidth();
        // init matrix with same amount of elements as pixels in canvas
        m_cCoordPlane = new Complex[(int) dCanvasHeight][(int) dCanvasWidth];
        double iPlotRange = 2 * PLOTMAX;

        for (int i = 0; i < dCanvasHeight; i++) 
        {
            for (int j = 0; j < dCanvasWidth; j++) 
            {

                m_cCoordPlane[i][j] = new Complex((i - (dCanvasWidth / 2)) * iPlotRange / dCanvasWidth,
                        (j - (dCanvasHeight / 2)) * iPlotRange / dCanvasHeight);
            }
        }

    }

    public void calcAbsSqValues() 
    {
        int iCanvasHeight = m_cCanvas.getHeight();
        int iCanvasWidth = m_cCanvas.getWidth();
        // init matrix with same amount of elements as pixels in canvas
        m_dAbsSqValues = new double[iCanvasHeight][iCanvasWidth];
        m_iIterations = new int[iCanvasHeight][iCanvasWidth];
        Complex cSum = new Complex();

        if (m_bWriteLog) {
            try 
            {
                m_cBufferedWriter.write("m_iIterations[][] =");
                m_cBufferedWriter.newLine();
            } 
            catch (IOException ex) 
            {
                System.out.println("Error opening file '" + m_sFileName + "'");
            }
        }

        for (int i = 0; i < iCanvasHeight; i++) 
        {
            for (int j = 0; j < iCanvasWidth; j++) 
            {
                cSum.setRe(m_cCoordPlane[i][j].getRe());
                cSum.setIm(m_cCoordPlane[i][j].getIm());
                m_iIterations[i][j] = 0;
                do 
                {
                    m_iIterations[i][j]++;
                    cSum.square();
                    cSum.add(m_cSummand);
                    m_dAbsSqValues[i][j] = cSum.getAbsSq();
                } while ((m_iIterations[i][j] < MAXITER) && (m_dAbsSqValues[i][j] < m_iDivergThresh));
                this.calcColour(i, j, m_iIterations[i][j]);
                m_cMsgIter = "x = " + i + " , y = " + j;

                 if(m_bWriteLog)
                 {
                    System.out.println(m_cMsgIter);
                    System.out.flush();
                 }

                if (m_bWriteLog) {
                    try 
                    {
                        m_cBufferedWriter.write(Integer.toString(m_iIterations[i][j]));
                        m_cBufferedWriter.write(" ");
                    } 
                    catch (IOException ex) {
                        System.out.println("Error writing to file '" + m_sFileName + "'");
                    }
                }
            }
            if (m_bWriteLog) {
                try 
                {
                    m_cBufferedWriter.newLine();
                } 
                catch (IOException ex) {
                    System.out.println("Error writing to file '" + m_sFileName + "'");
                }
            }
        }
        m_dAbsSqValues = null;
        m_iIterations = null;
        cSum = null;
    }

    private void calcColour(int i, int j, int aIterations) 
    {
        Color cColour = Color.getHSBColor((int) Math.pow(aIterations, 4), 0xff,
                0xff * ((aIterations < MAXITER) ? 1 : 0));
        m_cCanvas.setPixelColour(i, j, cColour);
        cColour = null;
    }

    private void handleCalculation()
    {
        Complex cSummand = new Complex();

        for(int i = -800; i <= 800; i++)
        {
            for(int j = -800; j <= 800; j++)
            {
                cSummand.setRe(((double)i)/1000.0);
                cSummand.setIm(((double)j)/1000.0);
                this.setSummand(cSummand);
                this.calcAbsSqValues();
                this.getCanvas().paint(m_cCanvas.getGraphics());
                this.paint(this.getGraphics());
            }
        }
        cSummand = null;
        this.collectGarbage();
        System.gc();
        System.runFinalization();
    }

    public boolean isRunning() 
    {
        return m_bRunning;
    }

    public void setRunning(boolean aRunning) 
    {
        m_bRunning = aRunning;
    }

    public Canvas getCanvas()
    {
        return m_cCanvas;
    }

    public void run()
    {
        if(m_bRunning)
        {
            this.handleCalculation();
        }
    }
}

class JuliaCanvas extends Canvas 
{
    private int m_iWidth;
    private int m_iHeight;
    private Random m_cRnd;
    private BufferedImage m_cBackGroundImage = null;
    private int m_iRed[][];
    private int m_iGreen[][];
    private int m_iBlue[][];

    JuliaCanvas(int aWidth, int aHeight) 
    {
        m_iWidth = aWidth;
        m_iHeight = aHeight;
        m_cRnd = new Random();

        m_cRnd.setSeed(m_cRnd.nextLong());

        m_cBackGroundImage = new BufferedImage(m_iWidth, m_iHeight, BufferedImage.TYPE_INT_RGB);

        m_iRed = new int[m_iHeight][m_iWidth];
        m_iGreen = new int[m_iHeight][m_iWidth];
        m_iBlue = new int[m_iHeight][m_iWidth];
    }

    public void init() {

    }

    public void setPixelColour(int i, int j, Color aColour) 
    {
        m_iRed[i][j] = aColour.getRed();
        m_iGreen[i][j] = aColour.getGreen();
        m_iBlue[i][j] = aColour.getBlue();
    }

    private int getRandomInt(double aProbability) 
    {
        return (m_cRnd.nextDouble() < aProbability) ? 1 : 0;
    }

    @Override
    public void paint(Graphics aGraphics) 
    {
        // store on screen graphics
        Graphics cScreenGraphics = aGraphics;
        // render on background image
        aGraphics = m_cBackGroundImage.getGraphics();


        for (int i = 0; i < m_iWidth; i++) 
        {
            for (int j = 0; j < m_iHeight; j++) 
            {
                Color cColor = new Color(m_iRed[i][j], m_iGreen[i][j], m_iBlue[i][j]);
                aGraphics.setColor(cColor);
                aGraphics.drawRect(i, j, 0, 0);
                cColor = null;
            }
        }
        // rendering is done, draw background image to on screen graphics
        cScreenGraphics.drawImage(m_cBackGroundImage, 1, 1, null);
    }

    @Override
    public void update(Graphics aGraphics) 
    {
        paint(aGraphics);
    }
}

class Complex {
    private double m_dRe;
    private double m_dIm;

    public Complex() 
    {
        m_dRe = 0;
        m_dIm = 0;
    }

    public Complex(double aRe, double aIm)
    {
        m_dRe = aRe;
        m_dIm = aIm;
    }

    public Complex(Complex aComplex)
    {
        m_dRe = aComplex.m_dRe;
        m_dIm = aComplex.m_dIm;
    }

    public double getRe() {
        return m_dRe;
    }

    public void setRe(double adRe)
    {
        m_dRe = adRe;
    }

    public double getIm() {
        return m_dIm;
    }

    public void setIm(double adIm)
    {
        m_dIm = adIm;
    }

    public void add(Complex acComplex) 
    {
         m_dRe += acComplex.getRe();
         m_dIm += acComplex.getIm();
    }

    public void square() 
    {
        double m_dReSave = m_dRe;
        m_dRe =  (m_dRe * m_dRe) - (m_dIm * m_dIm);
        m_dIm = 2 * m_dReSave * m_dIm;
    }

    public double getAbsSq()
    {
        return ((m_dRe * m_dRe) + (m_dIm * m_dIm));
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-18 12:35:55

第一;

没完没了的循环并不是正确的方法。这一部分是循环和CPU,从来没有给画布刷新屏幕。如果在下面添加代码,您的代码将按预期运行。但这不是正确的解决办法。

cMain.java:

代码语言:javascript
复制
while (true) {
    cJuliaSet.run();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

第二:当单击start按钮时,您可以调用run方法。但是,您应该在run方法中创建一个线程,以避免冻结屏幕。

代码语言:javascript
复制
 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
        }

actionPerformed:

代码语言:javascript
复制
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) {

运行方法:

代码语言:javascript
复制
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
        }
    }

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

票数 1
EN

Stack Overflow用户

发布于 2016-03-18 12:37:33

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

Swing是单线程的,您无法改变这一点,所有事件都被提交到事件队列并由事件分派线程处理,有关更多细节,请参见http://docs.oracle.com/javase/tutorial/uiswing/concurrency/,并查看http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html以获得至少一种可能的解决方案

代码中只有一个线程。该线程忙于计算,无法响应位于GUI中的事件。您必须在另一个线程中分隔计算,该线程定期更新窗口中出现的数量。更多有关这方面的信息,在链接,由@MadProgrammer,我坚持。

更新:正如@Yusuf所指出的,启动JFrame的正确方式是

代码语言:javascript
复制
        SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
        }
        });

当按下“开始”按钮时,将框架设置为“结构”可见,并开始计算。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36083712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档