动态更新时,不需要重新绘制JPanel

时间:2013-06-23 14:17:16

标签: java swing jpanel bufferedimage javax.swing.timer

我有一个窗口,使用javax.swing.Timer

动态更新JPanel上的缓冲图像集

一切都按预期工作,但每次调用动态更新时,似乎都会在当前更新的图像下方显示另一个缓冲图像。

单击列车按钮(触发动态更新)之前和之后的窗口图像如下所示。

enter image description here

由于动态更新图像下方的图像看起来像初始屏幕。我重新检查了以下内容

  1. 我是否将两个动态网格对象添加到同一个面板
  2. 多次调用repaint()
  3. 动态点阵的不需要的初始化
  4. 我在代码中找不到任何这些内容。我不能发布代码,因为它是巨大的,每当我创建一个最小的集合来重现相同的行为它不存在。所以我确定我在项目代码中遗漏了某些东西或做了些什么来触发这种行为。关于如何调试这个或者为什么这样做的建议?

    谢谢

    修改

    SSCCE如下。如果正在执行,请单击加载按钮,然后单击列车按钮以获取错误。

    (MapScreen.java - Main Class)
    package test;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import java.awt.Font;
    import javax.swing.JButton;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import test.DisplayLattice;
    import test.SelfOrganizingMap;
    
    public class MapScreen extends JFrame {
    
    private double NUM_ITERATIONS = 0.0;
    private double ETA = 0.0;
    private double SPREAD_FACTOR = 0.0;
    private double RADIUS = 0.0;
    private int WIDTH = 0;
    private int HEIGHT = 0;
    private SelfOrganizingMap SOM = null;
    private Timer REFRESH_TIMER = null; 
    private JPanel pnlMap;
    private JButton btnLoadParameters;
    private JButton btnTrain;
    private DisplayLattice displayScreen;
    
    
    public MapScreen(double iterations, double learningRate, double spreadFactor, double radius, int option, int width, int height, int mapOption) {
    
        NUM_ITERATIONS = iterations;
        ETA = learningRate;
        SPREAD_FACTOR = spreadFactor;
        RADIUS = radius;
        WIDTH = width;
        HEIGHT = height;
    
        setType(Type.UTILITY);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("Map");
        setSize(650, 800);
        setLocation(150,150);
        getContentPane().setLayout(null);
    
        displayScreen = new DisplayLattice();
        pnlMap = displayScreen;
        pnlMap.setBounds(6, 130, 600, 600);
        getContentPane().add(pnlMap);
    
    
        btnLoadParameters = new JButton("Load Parameters");
        btnLoadParameters.setFont(new Font("Tahoma", Font.PLAIN, 11));
        btnLoadParameters.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0)
            {
                SOM = new SelfOrganizingMap(10000,0,0,13,displayScreen);
            }
        });
        btnLoadParameters.setBounds(192, 46, 126, 23);
        getContentPane().add(btnLoadParameters);
    
        btnTrain = new JButton("Train");
        btnTrain.setFont(new Font("Tahoma", Font.PLAIN, 11));
        btnTrain.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                initialObjectSetUp();
            }
        });
        btnTrain.setBounds(192, 72, 62, 23);
        getContentPane().add(btnTrain); 
    }
    
    private void initialObjectSetUp()
    {
        SOM.initTrainSOM(null, 100, 0.25);
        REFRESH_TIMER = new Timer(100, SOM);
        REFRESH_TIMER.start();
    }
    
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                MapScreen frame = new MapScreen(100,0.25,0.0,0.0,1,100,0,0);
                frame.setVisible(true);
            }
        });
    
    }   
    }
    
    (SelfOrganizingMap.java)
    package test;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class SelfOrganizingMap implements ActionListener {
    
    private Node[][] SOM = null;
    private double[][] NORM_MAP = null; //holds the L2 norm of each vector in the SOM[][].
    @SuppressWarnings("unused")
    private int GRID_OPTION = 0;
    private int INPUT_DIMENSION = 0;
    private int NUMER_OF_ITERATIONS = 0;
    private int CURRENT_ITERATION=0;
    private int SOM_HORIZONTAL_LENGTH = 0;
    private int SOM_VERTICAL_LENGTH = 0;
    private double INITIAL_LEARNING_RATE = 0.0;
    private double LEARNING_RATE = 0.0;
    private double MAX_RADIUS = 0.0; //radius at first epoch (t = 0)
    private double RADIUS = 0.0;
    private double TIME_STEP = 0.0; //lambda of X(t) = t0 * exp(-t/lambda)
    private String INPUT_SAMPLES = null;
    private DisplayLattice DISPLAY_SCREEN = null;
    
    
    public SelfOrganizingMap(int numberOfNodes, int depth, int grid, int inputDimensison, DisplayLattice screen)
    {
        INPUT_DIMENSION = inputDimensison;
    
        if(grid == 0)
        {
            int side = (int)Math.sqrt(numberOfNodes);
            SOM = new Node[side][side];
            NORM_MAP = new double[side][side];
            GRID_OPTION = grid;
            MAX_RADIUS = side/2;
            DISPLAY_SCREEN = screen;
        }
    
    
        RADIUS = MAX_RADIUS;
    }
    
    public void initTrainSOM(String input, int iterations, double learningRate)
    {
    
        NUMER_OF_ITERATIONS = iterations;
        INITIAL_LEARNING_RATE = learningRate;
        LEARNING_RATE = INITIAL_LEARNING_RATE;
        TIME_STEP = NUMER_OF_ITERATIONS/Math.log(MAX_RADIUS);
        INPUT_SAMPLES = input;
    
    }
    
    private void singleCompleteRun()
    {
        DISPLAY_SCREEN.render();
        System.out.println(CURRENT_ITERATION);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if(CURRENT_ITERATION <= NUMER_OF_ITERATIONS)
        {
            singleCompleteRun();    
            CURRENT_ITERATION++;
        }
    
    }
    
    }
    
    (DisplayLattice.java)
    package test;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class DisplayLattice extends JPanel  {
    
    private BufferedImage img = new BufferedImage(500, 500, 1); 
    
    public void paintComponent(Graphics g) {
        if (img == null)
            super.paintComponents(g);
        else
            g.drawImage(img, 0, 0, this);
    }
    
    
    public void render() {
    
    float cellWidth = 100;
    float cellHeight = 100;
    
        int imgW = img.getWidth();
        int imgH = img.getHeight();
        float r, g, b;
        Graphics2D g2 = img.createGraphics();
        g2.setBackground(Color.black);
        g2.clearRect(0,0,imgW,imgH);
        for (int x=0; x<100; x++) {
            for (int y=0; y<100; y++) {
                r = (float)Math.random();
                g = (float)Math.random();
                b = (float)Math.random();
                g2.setColor(new Color(r,g,b));
                g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight),
                            (int)cellWidth+1, (int)cellHeight+1);
            }
        }
        g2.setColor(Color.black);
        g2.dispose();
        repaint();
    }
    
    public BufferedImage getImage() {
        if (img == null)
            img = (BufferedImage)createImage(500, 500);
    
        return img;
    }
    
    public void setImage(BufferedImage bimg) {
        img = bimg;
    }
    }
    (Node.java - Structure class for the SOM)
    package test;
    public class Node {
    
    private int DIMENSION = 0;  
    private int POSITION_X = 0;
    private int POSITION_Y = 0; 
    private double ACTIVATION_VALUE = 0.0; 
    
    public Node(int Dimensions, int x, int y)
    {
        DIMENSION = Dimensions; 
        setWeightVector();
        POSITION_X = x;
        POSITION_Y = y;
    }
    
    public int getX() {
        return POSITION_X;
    }
    
    public int getY() {
        return POSITION_Y;
    }
    
    public double getACTIVATION_VALUE() {
        return ACTIVATION_VALUE;
    }
    
    public void setPOSITION_X(int x) {
        POSITION_X = x;
    }
    
    public void setPOSITION_Y(int y) {
        POSITION_Y = y;
    }
    
    public void setACTIVATION_VALUE(double y) {
        ACTIVATION_VALUE= y;
    }
    
    private void setWeightVector()
    {
        double temp[] = new double[DIMENSION];
    
        for(int i = 0; i<temp.length ; i++)
        {
            temp[i] =  Math.random();
        }
    
    }
    
    }
    

1 个答案:

答案 0 :(得分:4)

问题在于您的DiaplyLattice课程。

您覆盖了paintComponent,但您调用了super.paintComponents(g)。请注意s末尾的额外paintComponents!这当然是不受欢迎的,应该是super.paintComponent(g);

我想方法如下:

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (img != null) {
        g.drawImage(img, 0, 0, this);
    }
}

现在,作为一个好的建议/提示,不要使用null布局,而是使用LayoutManager,并且可能使用几个级别的嵌套。它总是更容易。

另外,你错过了SSCCE中的重要事项:SHORT部分。这意味着你应该删除任何不必要的东西,并有一个文件来复制/粘贴。