我有一个自定义JPanel
,位于另一个自定义JPanel
之后,位于JLayeredPane
。我只想绘制一次背景JPanel
。因为它没有改变。这样可以节省系统资源。我该如何成功地完成这项工作?
我知道如果我允许像前景JPanel那样重复绘制背景JPanel,就会看到它。但这无视我的目标。这只是画了一次。
重新迭代。我如何绘制背景JPanel一次,并以递归方式绘制前景JPanel,同时在JLayeredPane中看到两个JPanel,其中背景JPanel位于前景JPanel后面
这是我目前的尝试。这不起作用。此代码的问题在于背景JPanel
根本不可见
这个问题并不重复,因为人们正在解决不相关的问题。我现在已经提出这个问题来解决我想要解决的问题。如果它可以帮助您解决我的问题。然后是问题的链接。 question。 这个问题也有一个坏的,毫无意义的答案。我甚至还试过并且正在努力工作。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JLayeredPane {
static JFrame frame;
static Main main;
static Dimension screenSize;
public Main() {
JPanel backPanel = new BackPanel();
JPanel frontPanel = new FrontPanel();
add(backPanel, new Integer(7));
add(frontPanel, new Integer(8));
new Thread(() -> {
while (true){
repaint();
}
}).start();
RepaintManager.currentManager(backPanel).markCompletelyClean(backPanel);
}
public static void main(String[] args) {
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("Game"); // Just use the constructor
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main = new Main();
frame.add(main, BorderLayout.CENTER);
frame.pack();
frame.setSize(screenSize);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class BackPanel extends JPanel{
public boolean drawn = false;
public BackPanel(){
setVisible(true);
setOpaque(false);
setSize(screenSize);
JLabel test1 = new JLabel("Test1");
JLabel test2 = new JLabel("Test2");
add(test1);
add(test2);
}
@Override
public void paintComponent(Graphics g){
if (!drawn){
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, screenSize.width, 200);
System.out.println("Reccursion");
drawn = true;
}
}
}
public class FrontPanel extends JPanel{
public FrontPanel(){
setVisible(true);
setOpaque(false);
setSize(screenSize);
JLabel test = new JLabel("Test");
add(test);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(0+screenSize.width/2, 0, screenSize.width/4, 300);
}
}
}
答案 0 :(得分:2)
首先是一些一般性评论。你不应该:
如果这是MCVE,那不重要。 MCVE应该使用适当的结构,否则我们可能会假设您在实际代码中犯了上述错误。
在你的while循环中使用:
repaint();
好吧,您的代码扩展了JLayeredPane,因此分层窗格的所有图层都会被绘制。
如果您只想重新绘制一个面板,则仅在该面板上调用repaint()。然而,这可能会导致问题,因为您需要确保在对其进行任何绘制之前清除背景,这就是为什么背景也需要绘制。
如果您不想重新绘制整个背景,那么您需要具体说明哪些区域需要重新绘制。查看Custom Painting上Swing教程中的部分,其中展示了如何优化绘制的内容。注意moveSquare(...)
方法如何在两个不同的区域上两次调用repaint()。这将导致重新绘制较小的背景区域。