调整包含JSVGCanvas的JComponent的大小时,蜡染IllegalStateException [英] Batik IllegalStateException when resizing the JComponent containing the JSVGCanvas

查看:98
本文介绍了调整包含JSVGCanvas的JComponent的大小时,蜡染IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序似乎运行良好,但是当我尝试调整组件大小时,有时会不断收到 IllegalStateExceptions:RunnableQueue未启动或已经退出的信息。我已经将documentState设置为ALWAYS_DYNAMIC,并且我已经阅读到您应该使用JSVGCanvas的UpdateManager并调用invokelater()。我了解它在第一次使用之后就可用

My program seems to work quite well, but I keep getting "IllegalStateExceptions: RunnableQueue not started or has exited" from time to time, when I try to resize my component. I have set the documentState to ALWAYS_DYNAMIC and I have read that you are supposed to use the JSVGCanvas' UpdateManager and call invokelater(). I understand that it is available after the first time that

gvtBuildCompleted(GVTTreeBuilderEvent e)

被调用,因此在使用它之前我先检查它是否正在运行,但仍然出现异常。
以下方法被线程重复调用,并且似乎导致异常:

is called, so I check whether it is running before I use it but I still get the exception. The following method is called by a thread repeatedly and seems to cause the exception:

private void updateDomTree(final SVGComponent component, final Document doc)
{
if(component.getSvgCanvas().getUpdateManager() != null && component.getSvgCanvas().getUpdateManager().isRunning())
{
    component.getSvgCanvas().getUpdateManager().getUpdateRunnableQueue().invokeLater(new Runnable() 
    {
        public void run() 
        {
            final Node newNode = doc.getChildNodes().item(0).getFirstChild();
            //could be easier to get this value, but ... it works.
            String newNodeId = newNode.getAttributes().getNamedItem("id").getFirstChild().getNodeValue();

            NodeList nodes = component.getSvgDocument().getDocumentElement().getChildNodes();
            Node updateNode = findElementById(nodes, newNodeId);
            resizeComponent(component, doc);
            component.getSvgCanvas().getSVGDocument().adoptNode(newNode);
            component.getSvgCanvas().getSVGDocument().getDocumentElement().replaceChild(newNode, updateNode);
            component.refreshSVGCanvas();
        }
    });
}
}

实际的调整大小在此处完成:

The actual resizing is done here:

protected void resizeComponent(SVGComponent component, Document doc)
{
    Element svgRoot = doc.getDocumentElement();
    final int svgWidth = Integer.parseInt(svgRoot.getAttribute("width"));
    final int svgHeight = Integer.parseInt(svgRoot.getAttribute("height"));
    String[] viewBox = svgRoot.getAttribute("viewBox").split(" ");
    int viewBoxLeft = Integer.parseInt(viewBox[0]);
    int viewBoxTop = Integer.parseInt(viewBox[1]);
    final float factor = component.getScaleFactor();
    String[] viewBoxOld = component.getSvgDocument().getDocumentElement().getAttribute("viewBox").split(" ");
    int viewBoxLeftOld = Integer.parseInt(viewBoxOld[0]);
    int viewBoxTopOld = Integer.parseInt(viewBoxOld[1]);
    int xDiff = (int) ((viewBoxLeftOld - viewBoxLeft)*factor);
    int yDiff = (int) ((viewBoxTopOld - viewBoxTop)*factor);

    if ( viewBoxLeftOld != viewBoxLeft ) //If there is additional content left
    {
        component.setLocation(component.getLocation().x - xDiff, component.getLocation().y);
    }
    if ( viewBoxTopOld != viewBoxTop ) //If there is additional content right)
    {
        component.setLocation(component.getLocation().x, component.getLocation().y - yDiff);
    }

    component.getSvgDocument().getDocumentElement().setAttribute("width",""+svgWidth);
    component.getSvgDocument().getDocumentElement().setAttribute("height",""+svgHeight);
    component.getSvgDocument().getDocumentElement().setAttribute("viewBox", ""+viewBoxLeft+" "+viewBoxTop+" "+svgWidth+" "+svgHeight);
    component.setSize((int)(svgWidth*factor),(int)(svgHeight*factor));
}

方法

refreshJSVGCanvas()

通话

JSVGCanvas.setDocument(Document);
JSVGCanvas.setSize(int, int);

这是完整的堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: RunnableQueue not started or has exited
at org.apache.batik.util.RunnableQueue.invokeLater(RunnableQueue.java:277)
at org.apache.batik.swing.svg.AbstractJSVGComponent.updateRenderingTransform(AbstractJSVGComponent.java:1057)
at org.apache.batik.swing.gvt.AbstractJGVTComponent$1.componentResized(AbstractJGVTComponent.java:237)
at java.awt.AWTEventMulticaster.componentResized(Unknown Source)
at java.awt.Component.processComponentEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

谢谢,我已经搜索了很多地方,尝试了很多,但是找不到解决方法。

Thanks in advance, I have searched everywhere and tried a lot, but could not find a solution.

编辑:
这是实际引发异常的蜡染:

This is the invokeLater-Method of Batik where the Exception is actually thrown:

public void invokeLater(Runnable r) {
    if (runnableQueueThread == null) {
        throw new IllegalStateException
            ("RunnableQueue not started or has exited");
    }
    synchronized (list) {
        list.push(new Link(r));
        list.notify();
    }
}

runnableQueueThrad设置在该类的run()-中方法,最后设置为null。
所以我想我必须做某种同步。

runnableQueueThrad is set inside that class' run()-Method and set to null at the end. So I guess I have to do some kind of synchronization.

推荐答案

有一个猜测,公共无效运行()代码不应在另一个方法内,而实际上是一个线程类/接口对象,因此称为构造函数(实际上是接口版本)。

Hazard a guess, the "public void run()" code should not be inside another method and really is a thread class/interface objects so called constructor(interface version actually).

将其删除到自己的类中(例如嵌套子类以保留范围),并在该类上实现线程可运行接口以在其中放置 run()方法以供使用。

Remove it to its own class(e.g. nested subclass to preserve scope) and implement the "thread runnable" interface on the class to place the "run()" method in it to use.

堆栈跟踪说run方法不可用,因为它实际上没有这样的方法(或至少没有正确声明),因此处于非法状态。

Stack trace says the run method is not available because it does not actually have such a method(or at least not properly declared) so it is in an "illegal state".

这篇关于调整包含JSVGCanvas的JComponent的大小时,蜡染IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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