【问题标题】:java plotting using for loop versus actionListener object使用 for 循环与 actionListener 对象的 java 绘图
【发布时间】:2013-12-02 01:30:30
【问题描述】:

我想知道为什么我不能通过使用 for 循环来使用相同的效果,而不是使用带有 actionlistener 对象的内部类来刷新图像上的点图。以下是代码:

import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.util.Random;

public class MyCanvas
{
    JLabel view;
    BufferedImage surface;
    Random random = new Random();
    public void initMyCanvas()
    {
        surface = new BufferedImage(1000,1000,BufferedImage.TYPE_INT_RGB);
        view = new JLabel(new ImageIcon(surface));
        Graphics g = surface.getGraphics();
        g.setColor(Color.ORANGE);
        g.fillRect(0,0,1000,1000);
        ActionListener listener=new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                int[] xLoc = new int[10]; 
                int[] yLoc = new int[10];
                System.out.println("drawing..");
                Graphics g = surface.getGraphics();
                g.setColor(Color.ORANGE);
                g.fillRect(0,0,1000,1000);

                Random rn=new Random();

                for (int ji=0;ji<10;ji++){
                    xLoc[ji]=rn.nextInt(500);
                    yLoc[ji]=rn.nextInt(500);
                }

                drawNodes(xLoc,yLoc,g);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        Timer timer = new Timer(1000, listener);
        timer.start();
    }
    public static void main(String[] args)
    {
        MyCanvas canvas = new MyCanvas();
        canvas.initMyCanvas();
        JFrame frame = new JFrame();
        int vertexes = 0;
        vertexes = 10;
        int canvasSize = vertexes * vertexes;
        frame.setSize(canvasSize, canvasSize);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(canvas.view);        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public void drawNodes(int[] x, int[] y, Graphics g)
    {
            // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5
            g.setColor(Color.white);
            System.out.println(" In drawNodes");
            for (int i=0;i<x.length;i++){
                g.fillOval(x[i], y[i], 8, 8);
            }
            g.dispose();
            view.repaint();
    }
}

与使用 for 循环实现多次迭代代码的同一“部分”以创建绘图的方法相比。

import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.util.Random;

public class MyCanvas
{
    JLabel view;
    BufferedImage surface;
    Random random = new Random();
    public void initMyCanvas()
    {
        surface = new BufferedImage(1000,1000,BufferedImage.TYPE_INT_RGB);
        view = new JLabel(new ImageIcon(surface));
        Graphics g = surface.getGraphics();
        g.setColor(Color.ORANGE);
        g.fillRect(0,0,1000,1000);
        for (int i=0; i<5;i++){
            int[] xLoc = new int[10]; 
            int[] yLoc = new int[10];
            System.out.println("drawing..");

            g.setColor(Color.ORANGE);
            g.fillRect(0,0,1000,1000);

            Random rn=new Random();

            for (int ji=0;ji<10;ji++){
                xLoc[ji]=rn.nextInt(500);
                yLoc[ji]=rn.nextInt(500);
            }

            drawNodes(xLoc,yLoc,g);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args)
    {
        MyCanvas canvas = new MyCanvas();
        canvas.initMyCanvas();
        JFrame frame = new JFrame();
        int vertexes = 0;
        vertexes = 10;
        int canvasSize = vertexes * vertexes;
        frame.setSize(canvasSize, canvasSize);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(canvas.view);        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public void drawNodes(int[] x, int[] y, Graphics g)
    {
            // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5
            g.setColor(Color.white);
            System.out.println(" In drawNodes");
            for (int i=0;i<x.length;i++){
                g.fillOval(x[i], y[i], 8, 8);
            }
            g.dispose();
            view.repaint();
    }
}

我问的原因是因为我正在 Xtend 中编写等效的实现,作为特定领域语言构建工作的一部分;我在编写内部类和/或实现 ActionListener 接口时遇到了问题。再说一次,这对我自己来说也是一件好事!!

【问题讨论】:

    标签: java swing graphics actionlistener bufferedimage


    【解决方案1】:

    方法 2 的问题是您在 EDT 中调用循环,因为它会阻塞并且无法绘制您的组件。阅读Swing Concurency

    1)Swing Timer 适用于带间隔的绘图。有了定时器,你就不需要使用Thread.sleep(1);

    2)您可以尝试使用SwingWorker进行重绘。你可以找到很多例子。

    3)在paintComponent()方法中也可以使用自定义绘画观看下一个exampleread oracle

    【讨论】:

      猜你喜欢
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多