JLayeredPane未绘制 [英] JLayeredPane not drawing

查看:123
本文介绍了JLayeredPane未绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天,

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

Hopefully this is a quick kill question. I am writing an application that uses JPanels and JLayeredPane inside a JFrame. On the initial start of my application, one of the panels does not show up until my mouse moves over the area where the panel should be. I even call the validate and repaint methods, but I am still able to display both panels together. Any suggestions? Thank you.

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

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

    }
}

这是我的小组课程之一

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会重新绘制自身.如果在某个时候发现从控制器代码中调用c.repaint()可以解决某些问题,则说明您已经忽略了位于swing框架核心的基本合同.这绝不是一个好主意.因此,删除所有这些repaintvalidate调用是一个好的开始.下一件重要的事情是了解轻型秋千组件如何为孩子涂漆.有2种模式:优化和未优化.第一个仅适用于兄弟姐妹在容器中彼此不重叠的情况.如果它们这样做并且启用了优化绘画,那么当这些组件重新绘制自身时(例如,将鼠标指针悬停在它们之上),您将获得各种奇怪的行为.所有轻量级组件均可通过setComponentZOrder()处理重叠的子级. JLayeredPane仅介绍了层的概念,以更灵活的方式控制zorder.它试图明智地选择为孩子绘画的方式,但是可悲的是,它的工作方式有些微妙.所以这段代码可以满足您的需求:

First off, in a valid program only JComponent repaints itself. If at some point you find that calling c.repaint() from your controller code fixes some problem, you have neglected basic contracts that at the core of swing framework. And this is never a good idea. So removing all those repaint and validate calls is a good start. Next important thing is understanding how lightweight swing components go about painting their children. There are 2 modes: optimized and not optimized. The first one is only applicable when siblings don't overlap eachother in the container. If they do and optimized painting is on, you are going to get all sorts of weird behavior when those components repaint themselves(like when you hover mouse pointer over them). All lightweight components can handle overlapping children through setComponentZOrder() . JLayeredPane only introduces the concept of a layer as a means of controlling zorder in a more flexible way. It tries to be smart about what mode to choose to paint its children but, sadly there are subtleties to how this works. so this code would do what you need:

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关闭优化的绘画.

the trick is to call setLayer before you add children to the container so that JLayeredPane would turn off optimized painting.

顺便说一句,我忍不住想知道为什么JLayeredPane吗?如果您需要通过编程方式在不同的布局之间进行切换,那么无论如何JTabbedPane都是您的答案

BTW I couldn't help but wonder why JLayeredPane? If you need switching programmatically between different layouts maybe JTabbedPane is your answer anyways

这篇关于JLayeredPane未绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆