java - JLayeredPane 不绘图

标签 java jframe jpanel paint jlayeredpane

美好的一天,

希望这是一个快速解决的问题。我正在编写一个在 JFrame 内使用 JPanels 和 JLayeredPane 的应用程序。在我的应用程序首次启动时,其中一个面板不会显示,直到我的鼠标移到该面板应在的区域上。我什至调用了 validate 和 repaint 方法,但我仍然能够同时显示两个面板。有什么建议么?谢谢。

这是我的 JFrame 类(具有 main 方法)

import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;


public class Application extends JFrame
{
    public Application()
    {   
        this.setSize(500,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        JLayeredPane lp = new JLayeredPane();
        lp.setBounds(0,0,500,500);
        this.setLayeredPane(lp);

        Mypanel p1 = new Mypanel();
        Mypanel2 p2 = new Mypanel2();

        this.getLayeredPane().add(p1,0);
        this.getLayeredPane().add(p2,1);

        this.validate();
        this.repaint();
        this.validate();
    }


    public static void main(String[] args)
    {
        Application app = new Application();

    }
}

这是我的面板类(class)之一

import javax.swing.JButton;
import javax.swing.JPanel;

public class Mypanel extends JPanel
{
    public JButton button;

    public Mypanel()
    {
        this.setLayout(null);
        this.setBounds(0, 0, 500, 500);
        JButton b = new JButton("Hello");
        b.setBounds(20,20,300,300);
        this.add(b);
    }
}

最后是我的最后一堂小组课

import javax.swing.JButton;
import javax.swing.JPanel;


public class Mypanel2 extends JPanel
{
    public JButton button;

    public Mypanel2()
    {
        this.setLayout(null);
        this.setBounds(0, 0, 500, 500);
        JButton b = new JButton("SUP");
        b.setBounds(20,10,200,200);
        this.add(b);
        this.repaint();
        this.validate();
        this.repaint();
    }
}

最佳答案

首先,在有效的程序中,只有 JComponent 会重新绘制自身。如果在某个时候您发现从 Controller 代码中调用 c.repaint() 可以解决某些问题,那么您就忽略了 Swing 框架核心的基本契约。这绝不是一个好主意。因此,删除所有这些 repaintvalidate 调用是一个好的开始。接下来重要的事情是了解轻量级 Swing 组件如何为 children 上色。有两种模式:优化和未优化。第一个仅适用于容器中 sibling 不相互重叠的情况。如果它们这样做并且启用了优化绘制,那么当这些组件重新绘制自身时(例如当您将鼠标指针悬停在它们上方时),您将得到各种奇怪的行为。所有轻量级组件都可以通过 setComponentZOrder() 处理重叠的子组件。 JLayeredPane只是引入了层的概念,作为以更灵活的方式控制zorder的手段。它试图明智地选择选择哪种模式来绘制其子项,但遗憾的是,其工作原理存在微妙之处。所以这段代码可以满足您的需要:

Mypanel p1 = new Mypanel();
Mypanel2 p2 = new Mypanel2();

getLayeredPane().setLayer(p1,0);
getLayeredPane().setLayer(p2,1);

getLayeredPane().add(p1);
getLayeredPane().add(p2);

这不会:

Mypanel p1 = new Mypanel();
Mypanel2 p2 = new Mypanel2();

getLayeredPane().add(p1);
getLayeredPane().add(p2);

getLayeredPane().setLayer(p1,0);
getLayeredPane().setLayer(p2,1);

诀窍是在将子项添加到容器之前调用setLayer,以便 JLayeredPane 关闭优化绘制。

顺便说一句,我忍不住想知道为什么JLayeredPane?如果您需要以编程方式在不同布局之间切换,也许 JTabbedPane 就是您的答案

关于java - JLayeredPane 不绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11196587/

相关文章:

Java Driver.getConnection() 在实时系统上从 mysql 产生 "Connection Refused",而不是开发

java - 如何在命令行编译使用 Apache Commons IO 的 Java 应用程序

java - 看不到 JFrame 中的一个组件

java - JFrame/JPanel 刷新和文本字段

java - Jackson CSV Writer 抛出 ArrayIndexOutOfBoundsException

用于在 Python 中引发错误的 Java 模拟

java - 我如何设置 Jframe 窗口的默认外观

Java - 无法从文本字段获取数据

java - 扫描 jtextfield 进行输入,写入文本文件,再次扫描新输入,直到用户关闭面板

java - 像在 Firefox 中一样制作带有标题的 JPanel 边框