gpt4 book ai didi

Java Swing : JPanels painting over each other

转载 作者:行者123 更新时间:2023-11-30 04:34:22 29 4
gpt4 key购买 nike

好吧,我有两个 JFrame,每个 JFrame 都有不同的 JPanel 实现。当我在 JPanel 上调用 repaint() 时,在一个 JPanel 上绘制的内容也会在另一个 JPanel 上绘制。

我知道我可以通过调用诸如 g.clearRect() 之类的方法来解决这个问题,但是每次都有太多组件需要重新绘制。

知道为什么会发生这种情况吗?

//This makes the two JFrames and JPanels, sets everything up

public void makeSpaceSimulation() {
int dimen = 10000;
int scale = 20;
int numOfClusters = 30;
int planPerCluster = 2000;
SpaceShip s = new SpaceShip(dimen, scale);

QuadTree t = new QuadTree(dimen, 20);
new PlanetCreationTest(t, dimen, scale, numOfClusters, planPerCluster);

makeMap(dimen, scale, s, t);
makePOV(s, t, scale, dimen);
}

public void makeMap(int dimen, int scale, SpaceShip s, QuadTree t) {

final JFrame f = new JFrame();
f.setSize(dimen / scale, dimen / scale);
f.setLocation(0, 0);
f.setTitle("Map Panel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

mapP = new MapPanel(scale, s, dimen);
mapP.setLayout(new BorderLayout());
mapP.addTree(t);

f.add(mapP);
f.setVisible(true);
Insets i = f.getInsets();
f.setSize(dimen / scale + (i.left + i.right) + 2, dimen / scale
+ (i.top + i.bottom) + 2);

Thread th = new Thread() {
public void run() {
while (true) {
mapP.repaint();
}

}
};
th.start();

}

public void makePOV(final SpaceShip s, QuadTree t, int scale, int dimen) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JFrame f = new JFrame();
f.setSize(500, 500);
f.setLocation(screenSize.width - 500, 0);
f.setTitle("POV Panel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

povP = new POVPanel(s, scale, dimen);
povP.setLayout(new BorderLayout());
povP.addTree(t);
povP.setFocusable(true);

povP.addKeyListener(new KeyListener() {

@Override
public void keyPressed(KeyEvent arg0) {
final int i = arg0.getKeyCode();
Thread th = new Thread() {
public void run() {
if (i == 39) {
s.moveRight();
} else if (i == 37) {
s.moveLeft();
} else if (i == 40) {
s.moveDown();
} else if (i == 38) {
s.moveUp();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
};
th.start();
}

@Override
public void keyReleased(KeyEvent arg0) {

}

@Override
public void keyTyped(KeyEvent arg0) {

}

});

f.add(povP);
f.setVisible(true);
Insets i = f.getInsets();
f.setSize(dimen / 20 + (i.left + i.right) + 2, dimen / 20
+ (i.top + i.bottom) + 2);

Thread th = new Thread() {
public void run() {
while (true) {
povP.repaint();
}

}
};
th.start();

}

//here's the MapPanel

public class MapPanel extends JPanel {

private QuadTree q;
private int scale;
private int dimen;
private SpaceShip s;
private boolean firstDraw;

public MapPanel(int scale, SpaceShip s, int dimen) {
this.dimen = dimen;
q = new QuadTree(0, 0);
this.scale = scale;
this.s = s;
firstDraw = true;
}

public void addTree(QuadTree q) {
this.q = q;

}

public void paintComponent(Graphics g) {
if (firstDraw) {
q.draw(g, scale, new Point(0, 0));
s.drawScaledGeometry(g);
System.out.println("Totally drew that");
firstDraw = false;
} else {
g.clearRect(s.viewDistance.x/scale, s.viewDistance.y/scale,
s.viewDistance.width/scale, s.viewDistance.height/scale);
q.quadDraw(g, scale, s.viewDistance, new Point(0, 0));
s.drawScaledGeometry(g);
}
}

}

//and this is the POVPanel 

public POVPanel(SpaceShip s, int scale, int dimen) {
super();
this.s = s;
// this.scale = scale;
this.dimen = dimen;
}

public void addTree(QuadTree q) {
this.q = q;
}

public void paintComponent(Graphics g) {
g.clearRect(0, 0, dimen / 20, dimen / 20);
q.quadDraw(g, 1, s.viewDistance, s.getMoved());
s.drawGeometry(g);
}

最佳答案

这是你的问题(之一)...

public void paintComponent(Graphics g) {
if (firstDraw) {
q.draw(g, scale, new Point(0, 0));
s.drawScaledGeometry(g);
System.out.println("Totally drew that");
firstDraw = false;
} else {
g.clearRect(s.viewDistance.x/scale, s.viewDistance.y/scale,
s.viewDistance.width/scale, s.viewDistance.height/scale);
q.quadDraw(g, scale, s.viewDistance, new Point(0, 0));
s.drawScaledGeometry(g);
}
}

Graphics 上下文在绘制周期期间共享,这意味着当您获取它时,您将获得用于绘制屏幕上所有其他组件的相同上下文。

您必须调用super.paintComponent(g),它将负责准备图形上下文,以便该组件开始绘画。

更新#1

再次...

public void paintComponent(Graphics g) {
super.paintComponent(g); // <-- Call me instead...
//g.clearRect(0, 0, dimen / 20, dimen / 20);
q.quadDraw(g, 1, s.viewDistance, s.getMoved());
s.drawGeometry(g);
}

更新#2

我也很担心这个问题

while (true) {
mapP.repaint();
}

这可能会严重影响应用程序的性能。您无法控制绘制周期,这是重绘经理的责任。重绘经理将决定何时需要重绘。像这样重复调用repaint实际上可能会导致重绘管理器延迟实际安排绘制周期。

使用 javax.swing.Timer 更好,更简单、更安全...

Timer timer = new Timer(25, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
mapP.repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();

您可能会发现通读

有帮助

更新 #3

避免使用KeyListener,它只会让你哭泣。相反,请使用key bindings API

关于Java Swing : JPanels painting over each other,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13853114/

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