【问题标题】:Changing graph with EventHandler使用 EventHandler 更改图形
【发布时间】:2020-06-03 14:21:43
【问题描述】:

每当用户按下箭头DOWN 时,我的程序都会绘制不同的图形。我为此使用 Enum 并且正在浏览每一个,并在按下向下箭头时显示所选类型的图表。

此时我有 3 种类型的图表,每当我遍历所有类型的图表回到第一个类型时,我的程序都会抛出 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);
    }
}

所有draw... 方法都可以为空。

我遇到的错误

我遇到了这个错误。

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)

当我像这样使用Platform.runLater() 时:

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

这就是发生的事情:

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)

我该如何解决这个问题? 这个问题可以是JavaFXSwing的组合吗?

【问题讨论】:

  • 这些信息不足以帮助您。您得到的异常是因为您正在操作 JavaFX 对象但在错误的线程上(在这种情况下是 AWT 线程,而它应该是 JavaFX 事件线程)。堆栈跟踪应该向您显示发生这种情况的位置。通常,解决方案是在更新 JavaFX 对象的地方使用Platform.runLater()。请至少包含完整的堆栈跟踪以及属于该堆栈跟踪的任何代码。
  • 我添加了完整的堆栈跟踪,还添加了使用 Platform.runLater() 后发生的情况。另外我不明白这不是最小的可重现示例吗?这段代码很少,只包含对我不起作用的部分代码。它是主要代码的较小副本,并且可重现。

标签: java swing javafx graph event-handling


【解决方案1】:

好的,所以主要错误多于 2 个,而不是 1 个。第一个是我写的命令中显示的那个,所以我会先回答它。

这可以通过Platform.runLater() 修复为评论中提到的@john16384。但是这个应该用在class Charts

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

这样,它会用 FX 线程 修复错误。但可能会出现下一个错误。

例如,如果您要尝试绘制BarChart,则必须在此方法中初始化CategoryAxisNumberAxis,当我之前声明并初始化它们时,不像我。 因为如果你这样做,这些Axis 将扩大大约 50%,这意味着你的图表将缩小 50%。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2021-10-22
    • 2013-01-24
    相关资源
    最近更新 更多