本文介绍了如何成功绘制背景JPanel一次并不断更新前景JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的JLayeredPane,我正在重绘它在我的游戏循环中。 JLayeredPane中添加了两个自定义JPanel。这些是前景和背景JPanels。我怎样才能成功地只绘制一次背景JPanel(当重新调整窗口大小或任何其他原因时重绘)以减少对系统资源的影响,同时不断更新我的前景JPanel。

要重新迭代,我不想在循环中不断重绘背景JPanel。因为背景没有改变,所以我只想重新绘制它。并且很大。

在我尝试这样做时,我只画了一次背景。然而。后台JPanel根本不可见。而前台JPanel更新正常。这就好像前台JPanel描绘了背景JPanel的顶层,即使我已经将JPanel设置为 setOpaque(false)



我做了一个mvce,它显示了我只尝试一次绘制背景JPanel,而不断更新前景JPanel。



代码是背景JPanel不显示。

现在。我知道,如果我不断绘制它会显示。但是这打破了我想要做的事情的目的。我试图只绘制一次,并同时被看到。

我的代码成功地只绘制了一次背景JPanel。问题是后台JPanel不显示。我该如何解决这个问题?

  import javax.swing。*; 

import java.awt。*;
import java.awt.event。*;

public class Main扩展JLayeredPane {
静态JFrame框架;
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)); $() - > {
while(true){
repaint();
}
}}。start();


$ b public static void main(String [] args){
screenSize = Toolkit.getDefaultToolkit()。getScreenSize();

frame = new JFrame(Game); //只需使用构造函数

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){
super.paintComponent(g);
drawOnce(g);

public void drawOnce(Graphics g){
if(!drawn){
g.setColor(Color.red);
g.fillRect(0,0,screenSize.width,200);
drawn = true;



$ b 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);




解决方案

我不知道这两行代码是什么?

  super.paintComponent(g); 
drawOnce(g);

是问题的根源,我真的不记得paintComponent是如何工作的(测试可以帮助)但尝试将它们交换:

  drawOnce(g); 
super.paintComponent(g);

也许,在您的原始版本中,您告诉JVM绘制整个组件,并且仅在AWTEvent已被添加到队列中,以绘制您需要的内容。
我想awt的文档会解释它。


I have a custom JLayeredPane, and I am repainting it in my game loop. There are two custom JPanels added into the JLayeredPane. These are foreground and background JPanels. How do I successfully only draw my background JPanel once, (And repaint when window is re-sized or any other reason) to reduce impact on system resources, while continuing to update my foreground JPanel constantly.

To re-iterate, I dont want to constantly repaint the background JPanel in a loop. I want to repaint it only when it is nessessary, as the background does not change. and is large.

In my attempt to do this, I have only drawn the background once. However. the background JPanel is simply not visible. while the foreground JPanel updates as normal. It is almost as if the foreground JPanel paints ontop of the background JPanel, even though I have both of the JPanels set to setOpaque(false)

I have made a mvce which shows my attempt at only drawing the background JPanel once, while updating the foreground JPanel constantly.

The problem with my code is that the background JPanel does not show.

Now. I know that if I were to draw it constantly it would show. But that defeats the purpose of what i'm trying to do. I am trying to only draw it once, and have be seen at the same time

My code successfully only draws the background JPanel once. The problem is that the background JPanel does not show. How do I fix THIS problem

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

    }

    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){
            super.paintComponent(g);
            drawOnce(g);
        }
        public void drawOnce(Graphics g){
            if (!drawn){
                g.setColor(Color.red);
                g.fillRect(0, 0, screenSize.width, 200);
                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);
        }
    }
}
解决方案

I don't know if this two lines of code

super.paintComponent(g);
drawOnce(g);

are the root of problem, I sincerly don't remember how paintComponent works (a test could help) but try to swap them :

drawOnce(g);
super.paintComponent(g);

maybe, on your original version, you tells JVM to paint the whole component and, only after the AWTEvent has been added to the queue, to draw what you need.I guess that the awt's documentation will explain it.

这篇关于如何成功绘制背景JPanel一次并不断更新前景JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 14:19