gpt4 book ai didi

java - 动态更新时 JPanel 出现不需要的重画

转载 作者:行者123 更新时间:2023-12-01 18:47:16 25 4
gpt4 key购买 nike

我有一个窗口,可以使用 javax.swing.Timer 动态更新 JPanel 上设置的缓冲图像

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

下面给出了单击训练按钮(触发动态更新)之前和之后的窗口图像。

enter image description here

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

  1. 是否将两个动态晶格对象添加到同一面板
  2. 多次调用 repaint()
  3. 动态晶格不需要的初始化

我在我的代码中找不到任何这些。我无法发布代码,因为它很大,并且每当我创建一个最小集来重现相同的行为时,它就不在那里。所以我确信我在项目代码中遗漏了某些内容或执行了某些操作,从而触发了此行为。关于如何调试这个或者为什么它要做这样的事情有什么建议吗?

谢谢

编辑

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();
}

}

}

最佳答案

问题出在您的 DiaplyLattice 类上。

您覆盖了paintComponent,但调用了super.paintComponents(g)。请注意 paintComponents 末尾的额外 s!这当然是不需要的,应该是 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 部分。这意味着您应该删除任何不必要的内容并复制/粘贴一个文件。

关于java - 动态更新时 JPanel 出现不需要的重画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17261618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com