Šimon Slabý
Šimon Slabý

Reputation: 613

Changing graph with EventHandler

My program is drawing different graphs whenever user push arrow DOWN. I'm using Enum for this and I am going through each one and I display chosen type of graph on press of DOWN arrow.

In this moment I have 3 types of graph and whenever I go through all of them back to the first one my program throw java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0

public class Main extends javax.swing.JFrame {

    private static void initAndShowGUI() {
        JFrame frame = new JFrame("JavaFX in Swing");
        frame.setLayout(new BorderLayout());

        Charts charts = new Charts();

        frame.setContentPane(charts);

        frame.setSize(1024, 720); //Size of dispalayed window
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            //java.awt.EventQueue.invokeLater
            public void run() {
                initAndShowGUI();
            }
        });
    }             
}

public class Charts extends JPanel{
    private JFXPanel jfxPanel = new JFXPanel();
    private i = 0;

    public Charts(){
        //show first graph so window won't be empty
        drawLineChart(jfxPanel);

        registerKeyboardAction((ActionEvent e) -> {

            switch(chartParams[i].toString()){
                case "BarChart":
                    drawBarChart(jfxPanel);
                    i++;
                    break;

                case "PieChart":
                    drawPieChart(jfxPanel);
                    i++;
                    break;

                case "LineChart":
                    i = 0;
                    drawLineChart(jfxPanel);
                    break;

                default:
                    i = 0;
                    System.out.println("Wrong Parameters!");
            }
            System.out.println(i+ ", ");
        }, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), WHEN_IN_FOCUSED_WINDOW);

        add(jfxPanel,BorderLayout.CENTER);
    }
}

All the draw... methods can be empty.

Error I am getting

This error I am getting.

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
    at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
    at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:329)
    at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:221)
    at javafx.scene.Parent$1.onChanged(Parent.java:246)
    at com.sun.javafx.collections.TrackableObservableList.lambda$new$29(TrackableObservableList.java:45)
    at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:102)
    at com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:237)
    at com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:103)
    at javafx.scene.chart.XYChart.<init>(XYChart.java:444)
    at javafx.scene.chart.BarChart.<init>(BarChart.java:154)
    at javafx.scene.chart.BarChart.<init>(BarChart.java:142)
    at cz.test.hibernate.Charts.drawBarChart(Charts.java:210)
    at cz.test.hibernate.Charts.lambda$new$0(Charts.java:73)
    at javax.swing.JComponent$ActionStandin.actionPerformed(JComponent.java:3425)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
    at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:307)
    at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:250)
    at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2974)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2966)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
    at javafx.embed.swing.JFXPanel.processKeyEvent(JFXPanel.java:497)
    at java.awt.Component.processEvent(Component.java:6310)
    at java.awt.Container.processEvent(Container.java:2237)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:835)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1103)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:974)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:800)
    at java.awt.Component.dispatchEventImpl(Component.java:4760)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:733)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.security.AccessController.doPrivileged(Native Method)1, 

    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

And when I use Platform.runLater() like this:

Platform.runLater(new Runnable() {
            @Override
            //java.awt.EventQueue.invokeLater
            public void run() {
                initAndShowGUI();
            }
        });

this is what happens:

Exception in thread "main" java.lang.IllegalStateException: Toolkit not initialized
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)
    at javafx.application.Platform.runLater(Platform.java:83)
    at cz.test.hibernate.Main.main(Main.java:109)

How can I solve this issue? Can this problem be combination of JavaFX and Swing?

Upvotes: 1

Views: 138

Answers (1)

Šimon Slab&#253;
Šimon Slab&#253;

Reputation: 613

Alright so there were more like 2 main mistakes then one. First one is the one that shows in command I wrote about so I am gonna answer it first.

This can be fixed by Platform.runLater() as @john16384 mentioned in comment. But this should be used in class Charts

case "BarChart":
    Platform.runLater(new Runnable() {
        drawBarChart(jfxPanel);
    });
    i++;
break;

By this it's gonna repair error with FX thread. But the next error's may appear.

For example if you gonna try to draw BarChart you have to initialize CategoryAxis and NumberAxis in this method not like me when I declared them and initialized before. Because if you do it that way these Axis will expand about 50% more which means your graphs will be 50% smaller.

Upvotes: 1

Related Questions