为什么的paintComponent()从未被称为重绘()? [英] why is paintComponent() never called by repaint()?

查看:997
本文介绍了为什么的paintComponent()从未被称为重绘()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在工作,吸引了自定义的JComponent上到的JLayeredPane但是所有来电重绘()上的组件似乎束手无策尚paintComponent方法自动调用时,窗口的尺寸重新调整的方案。

我一直在关注一些在这里给出的建议:
为什么油漆()/的paintComponent()从来没有所谓的?

但没有解决方案似乎调用重绘()调用super.paintComponent方法(G)在重写的paintComponent(),并呼吁重新验证(前手动解决我的问题,更新的EDT摆动组件,设置组件尺寸)添加新组件(虽然这显然是在这种情况下没有问题)之后的帧

任何想法可能会停止通话?在此先感谢:)

下面是code的视图和SVGElementContainer,view.setFile()是一个新的文档需要显示时被调用的入口点。

 公共类查看扩展的JLayeredPane实现SVGViewport {    私人SVGDocument文件;
    //阵列的SVGElementContainer组件列表
    私人的ArrayList< SVGElementContainer> elemContainers;
    私人SVGFrame框架;
    私人诠释的elemcount;
    私人边境viewBorder;
    私人INT边框宽度= 1;    //上的JLayeredPane显示面板
    私人的JPanel backgroundPanel;    / **创建一个新的视图* /
    公共视图(SVGFrame帧){
        超();
        this.frame =框架;
        的elemcount = 0;        elemContainers =新的ArrayList< SVGElementContainer>();
        viewBorder = BorderFactory.createLineBorder(Color.BLACK,边框宽度);
    }    公众持股量getViewportWidth(){
        返回的getWidth();
    }    公众持股量getViewportHeight(){
        返回的getHeight();
    }    //描绘的所有元素,并将它们添加到的JLayeredPane
    公共无效paintAllElements(){        的System.out.println(画的所有元素);        //画图文件
        对于(SVGElement ELEM:文件){
            //只画风格化(矩形,线,圆)元素
            如果(ELEM的instanceof SVGStylable){
                //创建一个新SVGElementContainer
                SVGElementContainer newElemCont =新SVGElementContainer();                //添加组件的JLayeredPane
                的elemcount ++;
                this.add(newElemCont,新的整数(的elemcount + 1));                //设置其容器内的当前元素和呼叫重绘()成分上
                的System.out.println(画元素#+的elemcount);
                newElemCont.setElement(ELEM);
                newElemCont.repaint();
            }
            其他{
                的System.out.println(跳过绘画组元素!);
            }
        }
    }    / **获取当前正由视图中显示的文档。 * /
    公共SVGDocument getDocument(){
        返回文件;
    }    / **设置该视图应该显示文档。
     *
     * @参数文档的文档设置
     * /
    公共无效调用setDocument(SVGDocument文件){
        this.document =文件;
        // paintBackground();
        paintAllElements();
        重新验证();
    }    公共无效重新验证(){
        //调用验证()中的框架上,以便显示新添加的元件
        frame.getContentPane()验证()。
    }
}公共类SVGElementContainer继承JPanel {    私人SVGElement ELEM;    公共SVGElementContainer(){
        超();
    }    @覆盖
    保护无效paintComponent(图形G){
        super.paintComponent方法(G);        的System.out.println(paint方法叫来!);
        paint2D((Graphics2D的)G);
    }    //绘制元素推此JComponent
    公共无效paint2D(Graphics2D的G){
        如果(!(ELEM的instanceof SVGStylable)){
            的System.out.println(跳过非风格化的元素!);
            返回;
        }        setOpaque(假);        塑造形状= elem.createShape();        //得到填补中风和宽度属性
        SVGStylable风格=(SVGStylable)ELEM;
        SVGPaint fillPaint = style.getFill();
        SVGPaint strokePaint = style.getStroke();
        SVGLength strokeWidth = style.getStrokeWidth();        //填充形状的内部
        如果(fillPaint.getPaintType()== SVGPaint.SVG_PAINTTYPE_RGBCOLOR){
            g.setPaint(fillPaint.getRGBColor());
            g.fill(形状);
        }        //中风形状的轮廓
        如果(strokePaint.getPaintType()== SVGPaint.SVG_PAINTTYPE_RGBCOLOR){
            行程行程=的新BasicStroke(strokeWidth.getValue());
            g.setStroke(中风);
            g.setColor(strokePaint.getRGBColor());
            g.draw(形状);
        }
    }    公共无效setElement(SVGElement ELEM){
        this.elem = ELEM;
        setComponentSize();
    }    私人无效setComponentSize(){        //this.set$p$pferredSize(new尺寸(
        //(INT)elem.getDocument()。的getWidth()。的getValue(),
        //(INT)elem.getDocument()的getHeight()的getValue()))。。        this.setSize(新尺寸(
                (INT)elem.getDocument()。的getWidth()。的getValue(),
                (INT)elem.getDocument()的getHeight()的getValue()))。
    }}


解决方案

我看到你调用setOpaque(假)。从setOpaque的javadoc,重点煤矿:

如果真组件绘制其边界内的所有像素。否则,的组件可能不绘制部分或所有像素,让底层的像素显示出来。

这可能是的paintComponent的原因()重绘()调用期间后的第一时间不会被调用。摆动可以决定该组件并没有变,从而不需要重新油漆

I've been working on an program that draws custom JComponents onto a JLayeredPane however all calls to repaint() on the components seem to do nothing yet the paintComponent method is invoked automatically when the window is re-sized.

I have been following some of the advice given here: Why is paint()/paintComponent() never called?

But none of the solutions seem to fix my problem, update swing components on the EDT, setting component size manually before calling repaint(), calling super.paintComponent(g) in the overridden paintComponent() and calling revalidate() on the frame after adding new components (although this is clearly no the issue in this case)

Any ideas what could be stopping the call? Thanks in advance :)

Here is the code for the View and the SVGElementContainer, view.setFile() is the entry-point as it is invoked when a new document needs to be displayed.

public class View extends JLayeredPane implements SVGViewport {

    private SVGDocument document;
    //Array list of the SVGElementContainer components
    private ArrayList<SVGElementContainer> elemContainers;
    private SVGFrame frame;
    private int elemCount;
    private Border viewBorder;
    private int borderWidth = 1;

    //panels displayed on the JLayeredPane
    private JPanel backgroundPanel;

    /** Creates a new view */
    public View(SVGFrame frame) {
        super();
        this.frame = frame;
        elemCount = 0;

        elemContainers = new ArrayList<SVGElementContainer>();
        viewBorder = BorderFactory.createLineBorder(Color.BLACK, borderWidth);
    }

    public float getViewportWidth() {
        return getWidth();
    }

    public float getViewportHeight() {
        return getHeight();
    }

    // paints all elements and adds them to the JLayeredPane
    public void paintAllElements(){

        System.out.println("Painting all elements");

        // Paint document
        for (SVGElement elem : document) {
            //only paint stylable (rect, line, circle) elements
            if (elem instanceof SVGStylable){
                //create a new SVGElementContainer
                SVGElementContainer newElemCont = new SVGElementContainer();

                //add component to JLayeredPane
                elemCount++;
                this.add(newElemCont, new Integer(elemCount + 1));

                //set the current element within its container and calls repaint() on the component
                System.out.println("Painting element #" + elemCount);
                newElemCont.setElement(elem);
                newElemCont.repaint();
            }
            else {
                System.out.println("Skip painting group element!");
            }
        }
    }

    /** Gets the document currently being displayed by the view. */
    public SVGDocument getDocument() {
        return document;
    }

    /** Sets the document that the view should display.
     *
     * @param document the document to set
     */
    public void setDocument(SVGDocument document) {
        this.document = document;
        //paintBackground();
        paintAllElements();
        revalidate();
    }

    public void revalidate(){
        //calls validate() on the frame in order to display newly added components
        frame.getContentPane().validate();
    }
}

public class SVGElementContainer extends JPanel{

    private SVGElement elem;

    public SVGElementContainer(){
        super();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        System.out.println("PAINT METHOD CALLED!");
        paint2D((Graphics2D) g);
    }

    //paint the element onto this JComponent
    public void paint2D(Graphics2D g){
        if (!(elem instanceof SVGStylable)){
            System.out.println("Skipping non-stylable element!");
            return;
        }

        setOpaque(false);

        Shape shape = elem.createShape();

        // get fill stroke and width properties
        SVGStylable style = (SVGStylable) elem;
        SVGPaint fillPaint = style.getFill();
        SVGPaint strokePaint = style.getStroke();
        SVGLength strokeWidth = style.getStrokeWidth();

        // Fill the interior of the shape
        if (fillPaint.getPaintType() == SVGPaint.SVG_PAINTTYPE_RGBCOLOR) {
            g.setPaint(fillPaint.getRGBColor());
            g.fill(shape);
        }

        // Stroke the outline of the shape
        if (strokePaint.getPaintType() == SVGPaint.SVG_PAINTTYPE_RGBCOLOR) {
            Stroke stroke = new BasicStroke(strokeWidth.getValue());
            g.setStroke(stroke);
            g.setColor(strokePaint.getRGBColor());
            g.draw(shape);
        }
    }

    public void setElement(SVGElement elem){
        this.elem = elem;
        setComponentSize();
    }

    private void setComponentSize(){

        //this.setPreferredSize(new Dimension(
        //  (int)elem.getDocument().getWidth().getValue(),
        //  (int)elem.getDocument().getHeight().getValue()));

        this.setSize(new Dimension(
                (int)elem.getDocument().getWidth().getValue(),
                (int)elem.getDocument().getHeight().getValue()));
    }

}

解决方案

I see that you're calling setOpaque(false). From the setOpaque javadoc, emphasis mine:

If true the component paints every pixel within its bounds. Otherwise, the component may not paint some or all of its pixels, allowing the underlying pixels to show through.

That "may" be the cause of paintComponent() not being called after the first time during a repaint() call. Swing can decide that the component has not "changed", and thus does not need repainting.

这篇关于为什么的paintComponent()从未被称为重绘()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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