【发布时间】:2020-11-09 20:12:37
【问题描述】:
我的程序创建一个 jframe > 将内容窗格设置为 jpanel > 一次或多次使用 repaint() > 将内容窗格设置为另一个 jpanel > 再次使用一些 repaint() > 等等... (注意:出于某种原因,我必须先创建 jframe,然后再添加 jpanel)
但仅调用 setContentPane(newjpanel) 之后我将无法使用 repaint(),而我知道的唯一可以解锁的方法是手动调整窗口大小
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MyJFrame extends JFrame {
private static final long serialVersionUID = 1L;
public MyJFrame() {
// default panel for visual feedback
JPanel pan = new JPanel();
pan.setBackground(Color.green);
this.setContentPane(pan);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // TODO
this.setSize(400, 400);
// other unrelated configuration stuff
// ...
this.setVisible(true);
}
public void switchPanel(JPanel pan) {
this.setContentPane(pan);
// pan.setVisible(true); doesnt work
// pan.revalidate(); neither
}
public static void main(String[] args) {
MyJFrame frame = new MyJFrame();
//...
JPanel mypan = new MyJPanel();
// there i have an IO operation to get an image, without this delay this code work just fine
// so i put this thread.sleep to simulate this delay
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
frame.switchPanel(mypan);
while (true) {
// this repaint wont work unless i change the window size
mypan.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
public static class MyJPanel extends JPanel {
private static final long serialVersionUID = 1L;
public Point pos = new Point(0, 0);
public synchronized void paintComponent(Graphics g) {
super.paintComponent(g);
// i made the square move for visual feedback
pos.x += 1;
g.fillRect(pos.x, pos.y, 10, 10);
}
}
}
这段代码应该显示一个正向 +x 方向的正方形
在调整窗口大小之前它不会发生
我知道的另一个选项是将 jframe 的可见性设置为 false 更改窗格然后将其设置为 true 但它在视觉上确实令人不快
所以我的问题是,我怎样才能在运行时添加/删除 jpanels? (在 switchPanel 中添加代码,添加容器,真的什么)
(第二个注意事项:如果可能的话,我想在运行时真正添加/删除 jpanels,我知道使用例如卡片布局并关闭和打开面板可见性,但在那里不能这样做)
【问题讨论】:
-
通常在 Swing 中,您在开始时创建所有 JPanel,然后使用 CardLayout 或 TabbedPane 显示或隐藏特定的 JPanel。如果您不想正确使用 Swing,那么您只能靠自己了。
-
我知道使用例如卡片布局 - 这就是你应该使用的。此外,您不应该使用 Thread.sleep()。对于动画,您应该使用 Swing Timer。
-
@GilbertLeBlanc 看,这有点粗鲁,不是因为我远离我不能问的约定,你可能不喜欢我上一个问题,但我真的尽力了.问题是,我有一个项目要做,我可能没有选择正确的方法来实现它,但现在我做到了,在某些时候我很想得到帮助,但我不会强迫任何人。感谢您的理解
-
@camickr 谢谢,我知道 Thread.sleep,这主要是测试代码,让我的渲染引擎在继续之前工作。关于卡片布局,我知道,但是这样做需要重构很多,而不会从中获得很多好处,如果我必须在另一个项目中以正确的方式使用 swing,但现在,它会有所帮助我更多地找到我所问的答案'^^,感谢您的理解
-
这将帮助我更多地找到我所要求的确切答案 我们需要更好地了解您的要求。创建一个面板然后在类的构造函数中立即替换它是没有意义的。为每个问题发布适当的minimal reproducible example。因此,“MRE”应该有一个带有面板的框架和一个您按下以替换内容窗格的 JButton。这将更好地代表您的应用程序。 while true 逻辑什么都不做,也不是“MRE”所必需的