Попробуйте очистить график Zest

Я пытаюсь очистить график изюминки от всех узлов и соединений, чтобы я мог перерисовать график с новыми узлами и соединениями. Чтобы понять, что я написал следующий метод

     public void clearGraph( Graph graph ) {        
     Object[] objects = graph.getConnections().toArray() ;          
         for (int i = 0 ; i < objects.length; i++){
             GraphConnection graCon = (GraphConnection) objects[i];              
             graCon.dispose();
             //graCon.setVisible(false);
         }           
     objects = graph.getNodes().toArray();      
     for ( int i = 0 ; i < objects.length; i++){
             GraphNode graNode = (GraphNode) objects[i];
             graNode.dispose();
            //graNode.setVisible(false);
     }
}

Это вылетает из моей программы с ошибкой

Исключение в потоке "основной" org.eclipse.swt.SWTException: виджет удален

В качестве обходного пути я попытался установить невидимые узлы и соединения, это работает, но невидимые объекты, похоже, портят мой макет Zest, поэтому, если есть способ фактически избавиться от узлов и соединений, я бы предпочел этот путь.

Вот массаж ошибок

Exception in thread "main" org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(Unknown Source)
at org.eclipse.swt.SWT.error(Unknown Source)
at org.eclipse.swt.SWT.error(Unknown Source)
at org.eclipse.swt.widgets.Widget.error(Unknown Source)
at org.eclipse.swt.widgets.Widget.checkWidget(Unknown Source)
at org.eclipse.swt.widgets.Item.getText(Unknown Source)
at com.mycom.timelineview.views.IndicatorFactorVisualisationView$2.mouseDoubleClick(IndicatorFactorVisualisationView.java:221)
at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at com.mycom.timelineview.views.IndicatorFactorVisualisationView.indicatorFactorWindow(IndicatorFactorVisualisationView.java:249)
at com.mycom.timelineview.views.IndicatorFactorVisualisationView.<init>(IndicatorFactorVisualisationView.java:71)
at com.mycom.timelineview.views.SpiderWebMouseListener.chartMouseClicked(SpiderWebMouseListener.java:102)
at org.jfree.experimental.chart.swt.ChartComposite.mouseDown(ChartComposite.java:1621)
at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at com.mycom.timelineview.views.SpiderWebView.createPartControl1(SpiderWebView.java:622)
at com.mycom.timelineview.views.InformationPlatformAppView2$7.handleEvent(InformationPlatformAppView2.java:628)
at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at com.mycom.timelineview.views.InformationPlatformAppView2.main(InformationPlatformAppView2.java:1330)

РЕДАКТИРОВАТЬ: благодаря Базу я нашел свою ошибку. Слушатель мыши должен был искать текст в узле графа, который я располагал ранее, поэтому, конечно, программа должна была дать сбой. Я изменил свой код, чтобы избежать этого, и теперь метод, предложенный Базом, работает отлично.


person hanneshelge    schedule 15.06.2016    source источник
comment
Вы видели это: eclipse.org/forums/index.php /t/79464 ?   -  person Baz    schedule 15.06.2016
comment
Я обновил свой ответ примером, который отлично работает.   -  person Baz    schedule 15.06.2016


Ответы (1)


Проверка isDisposed() перед вызовом dispose() предотвратит эту проблему:

public void clearGraph( Graph graph )
{       
    Object[] objects = graph.getConnections().toArray() ;           
    for (int i = 0 ; i < objects.length; i++)
    {
        GraphConnection graCon = (GraphConnection) objects[i];
        if(!graCon.isDisposed())
            graCon.dispose();
    }            

    objects = graph.getNodes().toArray();       
    for (int i = 0; i < objects.length; i++)
    {
        GraphNode graNode = (GraphNode) objects[i];
        if(!graNode.isDisposed())
            graNode.dispose();
    }
}

Вот тестовый пример, который отлично работает даже с выбранными узлами:

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Stackoverflow");
    shell.setLayout(new GridLayout(1, false));

    Graph g = new Graph(shell, SWT.NONE);
    g.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    Random random = new Random(System.currentTimeMillis());

    final List<GraphNode> nodes = new ArrayList<>();
    for (int i = 0; i < 10; i++)
    {
        GraphNode node = new GraphNode(g, SWT.NONE);
        node.setText("TEST");
        node.setLocation(random.nextInt(400), random.nextInt(400));
        nodes.add(node);
    }

    for (int i = 0; i < 50; i++)
    {
        GraphNode source;
        GraphNode target;

        do
        {
            source = nodes.get(random.nextInt(nodes.size()));
            target = nodes.get(random.nextInt(nodes.size()));
        } while (source.equals(target));

        new GraphConnection(g, SWT.NONE, source, target);
    }

    Button clear = new Button(shell, SWT.NONE);
    clear.setText("Clear");
    clear.addListener(SWT.Selection, e -> {
        for(GraphNode node : nodes)
        {
            node.dispose();
        }
        nodes.clear();
    });
    clear.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}
person Baz    schedule 15.06.2016
comment
Это не работает. Я предполагаю, что моя проблема может заключаться в том, что выбран GraphNode, который я хочу удалить. Есть ли способ отменить выбор графового узла? - person hanneshelge; 15.06.2016
comment
Попробуйте Graph#setSelection(null) или Graph#setSelection(new GraphItem[0]). - person Baz; 15.06.2016
comment
проверяя с помощью .isSelected(), я обнаружил, что нет выбранного GraphNode, поэтому я могу исключить это как проблему. Я также обнаружил, что избавление от соединений не создает никаких проблем. Однако удаление GraphNodes по-прежнему вызывает у меня ошибку удаления виджета. - person hanneshelge; 15.06.2016
comment
@hanneshelge Не могли бы вы добавить всю трассировку стека к своему вопросу? - person Baz; 15.06.2016
comment
@hanneshelge Кроме того, что произойдет, если вы просто удалите узлы, будет ли это работать, и соединения также будут работать? - person Baz; 15.06.2016
comment
Если я распоряжаюсь только узлами, а не соединениями, я получаю тот же сбой. удаление соединений кажется нормальным, но удаление узлов таким же образом приводит к сбою - person hanneshelge; 15.06.2016
comment
@hanneshelge Что вы вызываете getText() в прослушивателе двойного щелчка мыши? - person Baz; 15.06.2016