如何在Java中的for循环中的每个update()之后强制执行repaint()?

用户3782467

我编写了一个小型的基本万花筒类型程序,该程序应在六个不同的点和不同的方向上逐渐绘制相同的图案(随着时间的流逝)。

为此,我创建了一个数组来存储每个像素的颜色(其初始颜色为黑色,并由数字0表示),然后将数组中的6个起点的颜色更改为绿色(由数字1表示)。这些点应该出现在屏幕上,然后根据之前的6个点的位置再创建6个点。然后应显示更新的屏幕。重复,重复,重复...

我的问题是,在绘制屏幕之前,正在对所有新像素执行所有更新。我检查了其他一些帖子和Web教程等,并认为AWT足够友好,可以避免浪费时间重新粉刷较小的更改。似乎也有paintManager涉及的东西我相信问题是我正在for循环中重新粉刷。我发现这确实令人沮丧,因为我认为这应该很简单。确实,有一种说服java以我希望的方式绘制这些细微变化的简单方法吗?

我在下面完整地包含了代码:

package paranoid;

import javax.swing.JFrame;

public class MasterFrame {

    public static void main(String[] args) {
            // TODO Auto-generated method stub
    new MasterFrame();
    }


    public MasterFrame(){
        JFrame f = new JFrame();
        f.setTitle("Kaleidoscope");
        f.add(new Trip2());
        f.setSize(500,300);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

}

和...

package paranoid;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;


public class Trip2 extends JPanel {

    private static final long serialVersionUID = 1L;

    private int xmin = 0,
                xmax = 499,
                ymin = 0,
                ymax = 279;
    private int x = 120;
    private int y = 80;
    private int dx = 1;
    private int dy = 1;
    private int temp = 0;
    private int update_counter = 0;
    private int repaint_counter = 0;
    private int x_pos[] = new int[6];
    private int y_pos[] = new int[6];
    private int screen[][] = new int[500][280];


    public Trip2() {

        initialisation();
        for(int i = 0; i < 5000; i++)
        {
            update();
            System.out.println("Just returned from update()");

            repaint();                                          //This repaint is not being activated until all updates 
            System.out.println("Just returned from paint()");   //have been completed, but I want a repaint after EVERY update.
        }
    }

    public void initialisation(){
        System.out.println("initialising...");
        x_pos[0] = x;
        y_pos[0] = y;

        x_pos[1] = xmax - x;
        y_pos[1] = y;

        x_pos[2] = x;
        y_pos[2] = ymax - y;

        x_pos[3] = xmax - x;
        y_pos[3] = ymax - y;

        x_pos[4] = (int)(xmax/2)-50;
        y_pos[4] = (int)(ymax/2);

        x_pos[5] = (int)(xmax/2)+50;
        y_pos[5] = (int)(ymax/2);

        for(int j = 0; j<280; j++){
            for(int i = 0; i<500; i++){
                screen[i][j] = 0;
            }
        }
    } //end of initialisation()

    public void update(){
        System.out.println("updating... for the "+update_counter+"th time");

        temp = (int)Math.floor(Math.random()*100);
        if(temp < 40){ // 40% chance that the direction is changed
            dx = (int)Math.floor(Math.random()*3);
            dy = (int)Math.floor(Math.random()*3);
            dx = dx - 1;
            dy = dy - 1;
        }


        x_pos[0] = x_pos[0]+dx;
        y_pos[0] = y_pos[0]+dy;

        x_pos[1] = x_pos[1]-dx;
        y_pos[1] = y_pos[1]+dy;

        x_pos[2] = x_pos[2]+dx;
        y_pos[2] = y_pos[2]-dy;

        x_pos[3] = x_pos[3]-dx;
        y_pos[3] = y_pos[3]-dy;

        x_pos[4] = x_pos[4]-dy;
        y_pos[4] = y_pos[4]-dx;

        x_pos[5] = x_pos[5]+dy;
        y_pos[5] = y_pos[5]+dx;

        for(int k = 0; k < 6; k++){
            if(x_pos[k] < 0){
                x_pos[k] = 0;
            }
            if(x_pos[k] > 499){
                x_pos[k] = 499;
            }
        }

        for(int k = 0; k < 6; k++){
            if(y_pos[k] < 0){
                y_pos[k] = 0;
            }
            if(y_pos[k] > 279){
                y_pos[k] = 279;
            }
        }


        screen[x_pos[0]][y_pos[0]] = 1;
        screen[x_pos[1]][y_pos[1]] = 1;
        screen[x_pos[2]][y_pos[2]] = 1;
        screen[x_pos[3]][y_pos[3]] = 1;
        screen[x_pos[4]][y_pos[4]] = 1;
        screen[x_pos[5]][y_pos[5]] = 1;

        update_counter = update_counter + 1;

    } //end of update()

    public void paint(Graphics g){
        System.out.println("painting screen for the "+repaint_counter+"th time");

            g.setColor(Color.BLACK);
            g.fillRect(xmin, ymin, xmax, ymax);

            for(int j = 0; j<280; j++){
                for(int i = 0; i<500; i++){
                    if(screen[i][j] == 0){
                        g.setColor(Color.BLACK);
                    } else 
                    {   
                        g.setColor(Color.GREEN);    
                    }
                    g.drawLine(i,j,i,j); //plots pixel
                }
            }


            try{
                Thread.sleep(100);
            }
            catch(InterruptedException e){  
            }

            repaint_counter = repaint_counter + 1;


    }//end of paint(Graphics g)

}//end of Trip2 class
咆哮的ad

这里的主要问题之一是您正在调用Thread.sleep()paint方法-这不是一个好主意,因为这将停止在该期间进一步重新绘制应用程序。(事件分发线程/绘画线程不得用于任何慢速操作)

您要在此处实现的通常流程如下(可能比您需要的方式更详细):

  1. 创建一个包含所有数字变量的模型类,尤其是包含数字(没有UI代码)的模型类,还会创建各种吸气剂,以允许UI以后访问这些数字。
  2. 允许将此模型类传递给视图类(Trip1在您的情况下)并设置为实例变量。
  3. 从主控制类创建一个新的线程或计时器,该线程或计时器会根据需要定期调整您的型号/内部型号。
  4. 创建interface用于模型更改的侦听器。(例如ModelChangedListener,类似)
  5. 将侦听器列表添加到模型中-使用register方法将侦听器简单地添加到列表中。
  6. 使其对模型的任何更改(即,当数字更新时)都会触发已注册的侦听器。
  7. 在您的主控制类中,注册一个仅调用以下内容的侦听器: trip2Panel.repaint();

  8. paint()面板方法中,只需绘制当前模型即可。

完整代码发布:

package paranoid;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;

public class MasterFrame {

public static void main(String[] args) {
        // TODO Auto-generated method stub
new MasterFrame();
}


public MasterFrame(){
    JFrame f = new JFrame();
    f.setTitle("Kaleidoscope");
    final Trip2 trip2UI = new Trip2();
    final TripModel model = new TripModel();
    model.update();
    Timer timer = new Timer(1, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            model.update();
        }
    });
    timer.setRepeats(true);
    timer.start();

    model.addListener(new TripModelListener() {
        @Override
        public void modelChanged() {
            trip2UI.repaint();
        }
    });
    trip2UI.setModel(model);

    f.add(trip2UI);
    f.setSize(500,300);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
    f.setResizable(false);

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
}

TripModelListener

package paranoid;

public interface TripModelListener {
    void modelChanged();
}

Trip2(UI)

package paranoid;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;


public class Trip2 extends JPanel {

private static final long serialVersionUID = 1L;

private TripModel model;

public void paint(Graphics g){

    g.setColor(Color.BLACK);
    g.fillRect(model.getXMin(), model.getYMin(), model.getXMax(), model.getYMax());

    for (int j = 0; j < 280; j++) {
        for (int i = 0; i < 500; i++) {
            if (model.getScreen()[i][j] == 0) {
                g.setColor(Color.BLACK);
            } else {
                g.setColor(Color.GREEN);
            }
            g.drawLine(i, j, i, j); //plots pixel
        }
    }
}

public void setModel(TripModel model) {
    this.model = model;
}

}//en

旅行模式

package paranoid;

import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class TripModel {
private List<TripModelListener> listeners = new CopyOnWriteArrayList<TripModelListener>();
private int xmin = 0,
            xmax = 499,
            ymin = 0,
            ymax = 279;
private int x = 120;
private int y = 80;
private int dx = 1;
private int dy = 1;
private int temp = 0;
private int update_counter = 0;
private int x_pos[] = new int[6];
private int y_pos[] = new int[6];
private int screen[][] = new int[500][280];


public TripModel() {

    initialisation();
}

public void initialisation(){
    System.out.println("initialising...");
    x_pos[0] = x;
    y_pos[0] = y;

    x_pos[1] = xmax - x;
    y_pos[1] = y;

    x_pos[2] = x;
    y_pos[2] = ymax - y;

    x_pos[3] = xmax - x;
    y_pos[3] = ymax - y;

    x_pos[4] = (int)(xmax/2)-50;
    y_pos[4] = (int)(ymax/2);

    x_pos[5] = (int)(xmax/2)+50;
    y_pos[5] = (int)(ymax/2);

    for(int j = 0; j<280; j++){
        for(int i = 0; i<500; i++){
            screen[i][j] = 0;
        }
    }
} //end of initialisation()

public void update(){
    //System.out.println("updating... for the "+update_counter+"th time");

    temp = (int)Math.floor(Math.random()*100);
    if(temp < 40){ // 40% chance that the direction is changed
        dx = (int)Math.floor(Math.random()*3);
        dy = (int)Math.floor(Math.random()*3);
        dx = dx - 1;
        dy = dy - 1;
    }


    x_pos[0] = x_pos[0]+dx;
    y_pos[0] = y_pos[0]+dy;

    x_pos[1] = x_pos[1]-dx;
    y_pos[1] = y_pos[1]+dy;

    x_pos[2] = x_pos[2]+dx;
    y_pos[2] = y_pos[2]-dy;

    x_pos[3] = x_pos[3]-dx;
    y_pos[3] = y_pos[3]-dy;

    x_pos[4] = x_pos[4]-dy;
    y_pos[4] = y_pos[4]-dx;

    x_pos[5] = x_pos[5]+dy;
    y_pos[5] = y_pos[5]+dx;

    for(int k = 0; k < 6; k++){
        if(x_pos[k] < 0){
            x_pos[k] = 0;
        }
        if(x_pos[k] > 499){
            x_pos[k] = 499;
        }
    }

    for(int k = 0; k < 6; k++){
        if(y_pos[k] < 0){
            y_pos[k] = 0;
        }
        if(y_pos[k] > 279){
            y_pos[k] = 279;
        }
    }


    screen[x_pos[0]][y_pos[0]] = 1;
    screen[x_pos[1]][y_pos[1]] = 1;
    screen[x_pos[2]][y_pos[2]] = 1;
    screen[x_pos[3]][y_pos[3]] = 1;
    screen[x_pos[4]][y_pos[4]] = 1;
    screen[x_pos[5]][y_pos[5]] = 1;

    update_counter = update_counter + 1;
    fireModelChangedListener();
} //end of update()

private void fireModelChangedListener() {
    for (TripModelListener listener : listeners) {
        listener.modelChanged();
    }
}


public int getXMin() {
    return xmin;
}

public int getYMin() {
    return ymin;
}

public int getYmin() {
    return ymin;
}

public void setYmin(int ymin) {
    this.ymin = ymin;
}

public int getXMax() {
    return xmax;
}

public int getXmax() {
    return xmax;
}

public void setXmax(int xmax) {
    this.xmax = xmax;
}

public int getYMax() {
    return ymax;
}

public int[][] getScreen() {
    return screen;
}

public void addListener( TripModelListener listener) {
    listeners.add(listener);
}
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在for循环中强制执行多个QComboBox中的任何一个的最小索引?

来自分类Dev

如何在Java中强制执行构造函数

来自分类Dev

如何在 Java <= 8 中强制执行模块边界

来自分类Dev

如何在.Net中强制执行OutOfMemoryException

来自分类Dev

如何在Perl中强制执行long double

来自分类Dev

如何在Chrome中强制执行504错误

来自分类Dev

如何在vb.net中调试强制执行?

来自分类Dev

如何在Perl中强制执行long double

来自分类Dev

如何在GNOME Web中强制执行大文本?

来自分类Dev

如何在Jenkins DSL中强制执行参数排序?

来自分类Dev

如何在matplotlib中的网格内强制执行图?

来自分类Dev

如何在 Antlr 中强制执行某些规则

来自分类Dev

如何在Java或C#中强制执行ddd聚合?

来自分类Dev

while指令之后的指令如何在循环中执行?

来自分类Dev

如何在循环中执行()?在C中

来自分类Dev

Spark SQL如何在循环中为输入DataFrame中的每个记录执行SQL命令

来自分类Dev

MongoDB分片键-在每个查询中强制执行

来自分类Dev

如何在python中从python中强制执行或呈现浏览器中的脚本?

来自分类Dev

Python中的枚举:如何在方法参数中强制执行

来自分类Dev

如何在Spark SQL中强制执行内存中的分块排序?

来自分类Dev

如何在git中强制执行“文件名中没有空格”策略?

来自分类Dev

如何在Spark SQL中强制执行内存中的分块排序?

来自分类Dev

Eclipse:如何在调试时强制执行特定的Java语句?

来自分类Dev

Eclipse:如何在调试时强制执行特定的Java语句?

来自分类Dev

如何在phpstorm中对数组声明强制执行长语法?

来自分类Dev

GHC如何在多线程应用程序中强制执行评估?

来自分类Dev

如何在Play 2.x中强制执行JSON的严格序列化

来自分类Dev

如何在Sublime中强制执行50个字符的提交摘要行?

来自分类Dev

如何在RedShift中强制执行参照完整性?

Related 相关文章

  1. 1

    如何在for循环中强制执行多个QComboBox中的任何一个的最小索引?

  2. 2

    如何在Java中强制执行构造函数

  3. 3

    如何在 Java <= 8 中强制执行模块边界

  4. 4

    如何在.Net中强制执行OutOfMemoryException

  5. 5

    如何在Perl中强制执行long double

  6. 6

    如何在Chrome中强制执行504错误

  7. 7

    如何在vb.net中调试强制执行?

  8. 8

    如何在Perl中强制执行long double

  9. 9

    如何在GNOME Web中强制执行大文本?

  10. 10

    如何在Jenkins DSL中强制执行参数排序?

  11. 11

    如何在matplotlib中的网格内强制执行图?

  12. 12

    如何在 Antlr 中强制执行某些规则

  13. 13

    如何在Java或C#中强制执行ddd聚合?

  14. 14

    while指令之后的指令如何在循环中执行?

  15. 15

    如何在循环中执行()?在C中

  16. 16

    Spark SQL如何在循环中为输入DataFrame中的每个记录执行SQL命令

  17. 17

    MongoDB分片键-在每个查询中强制执行

  18. 18

    如何在python中从python中强制执行或呈现浏览器中的脚本?

  19. 19

    Python中的枚举:如何在方法参数中强制执行

  20. 20

    如何在Spark SQL中强制执行内存中的分块排序?

  21. 21

    如何在git中强制执行“文件名中没有空格”策略?

  22. 22

    如何在Spark SQL中强制执行内存中的分块排序?

  23. 23

    Eclipse:如何在调试时强制执行特定的Java语句?

  24. 24

    Eclipse:如何在调试时强制执行特定的Java语句?

  25. 25

    如何在phpstorm中对数组声明强制执行长语法?

  26. 26

    GHC如何在多线程应用程序中强制执行评估?

  27. 27

    如何在Play 2.x中强制执行JSON的严格序列化

  28. 28

    如何在Sublime中强制执行50个字符的提交摘要行?

  29. 29

    如何在RedShift中强制执行参照完整性?

热门标签

归档