【问题标题】:Change JavaFX Application Start Form更改 JavaFX 应用程序启动表单
【发布时间】:2016-04-11 20:15:42
【问题描述】:

我当前的项目是一个带有 RMI 的 JavaFX 应用程序。目前我有两个三个班级,我想减少到两个,但我不知道如何。

三个类: 启动客户端.java BannerController.java AEXBanner.java

代码和错误信息:

java.lang.reflect.InvocationTargetException

在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:497) 在 com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) 在 com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:497) 在 sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) 原因:java.lang.IllegalStateException:不在 FX 应用程序线程上;当前线程 = 主线程 在 com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236) 在 com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423) 在 javafx.stage.Stage.(Stage.java:241) 在 javafx.stage.Stage.(Stage.java:227) 在 client.BannerController.(BannerController.java:71) 在 client.BannerController.main(BannerController.java:174) ... 11 更多 异常运行应用程序client.BannerController D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:1051: The following error occurred while 执行这一行: D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner 第 1 周\nbproject\build-impl.xml:805:Java 返回:1 构建失败(总时间:17 秒)

使用 StartClient 启动程序后(RMI 服务器正在运行),一切正常。但是当我直接使用 BannerController 类启动应用程序时,Netbeans 给了我上面发布的错误。

我 100% 确定 RMI 服务器工作正常,因此无需担心。

这三个类可以在下面找到:

启动客户端:

package client;

import javafx.application.Application;
import javafx.stage.Stage;

/**
 *
 * @author Max
 */
public class StartClient extends Application {

    @Override
    public void start(Stage primaryStage) {
        BannerController.main(null);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

横幅控制器: 打包客户端;

/**
 *
 * @author Max
 */
import shared.IEffectenBeurs;
import shared.IFonds;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.stage.Stage;

public class BannerController extends Application {

    private AEXBanner banner;
    private IEffectenBeurs effectenbeurs;
    private Timer pollingTimer;
    private String bindingName = "Effectenbeurs";
    private Registry registry = null;
    private static boolean locateRegistry = true;

    public BannerController(String ip, int port) {
        banner = new AEXBanner();
        pollingTimer = new Timer();

        System.out.println("Client: IP Address: " + ip);
        System.out.println("Client: Port number " + port);

        if (locateRegistry) {
            // Locate registry at IP address and port number
            registry = locateRegistry(ip, port);

            // Print result locating registry
            if (registry != null) {
                printContentsRegistry();
                System.out.println("Client: Registry located");
            } else {
                System.out.println("Client: Cannot locate registry");
                System.out.println("Client: Registry is null pointer");
            }
            if (registry != null) {
                effectenbeurs = bindEffectenbeursUsingRegistry();
            }
        } else {
            // Bind fonds using Naming
            effectenbeurs = bindEffectenbeursUsingNaming(ip, port);
        }
        if (effectenbeurs != null) {
            System.out.println("Client: Effectenbeurs bound");
        } else {
            System.out.println("Client: Effectenbeurs is null pointer");
        }
        banner.start(new Stage());
        pollingTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    StringBuilder sb = new StringBuilder();
                    for (IFonds f : effectenbeurs.getKoersen()) {
                        sb.append(f.toString() + " ");
                    }
                    System.out.println(sb.toString());
                    banner.setKoersen(sb.toString());
                } catch (RemoteException ex) {
                    Logger.getLogger(BannerController.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
        }, 0, 2000);

    }

    // Print contents of registry
    private void printContentsRegistry() {
        try {
            String[] listOfNames = registry.list();
            System.out.println("Client: list of names bound in registry:");
            if (listOfNames.length != 0) {
                for (String s : registry.list()) {
                    System.out.println(s);
                }
            } else {
                System.out.println("Client: list of names bound in registry is empty");
            }
        } catch (RemoteException ex) {
            System.out.println("Client: Cannot show list of names bound in registry");
            System.out.println("Client: RemoteException: " + ex.getMessage());
        }
    }

    private IEffectenBeurs bindEffectenbeursUsingRegistry() {
        IEffectenBeurs effectenbeurs1 = null;
        try {
            Object object = registry.lookup(bindingName);
            effectenbeurs1 = (IEffectenBeurs) registry.lookup(bindingName);
        } catch (RemoteException ex) {
            System.out.println("Client: Cannot bind Effectenbeurs");
            System.out.println("Client: RemoteException: " + ex.getMessage());
            effectenbeurs1 = null;
        } catch (NotBoundException ex) {
            System.out.println("Client: Cannot bind Effectenbeurs");
            System.out.println("Client: NotBoundException: " + ex.getMessage());
            effectenbeurs1 = null;
        }
        return effectenbeurs1;
    }

    private Registry locateRegistry(String ipAddress, int portNumber) {
        Registry registry = null;
        try {
            registry = LocateRegistry.getRegistry(ipAddress, portNumber);
        } catch (RemoteException ex) {
            System.out.println("Client: Cannot locate registry");
            System.out.println("Client: RemoteException: " + ex.getMessage());
            registry = null;
        }
        return registry;
    }

    private IEffectenBeurs bindEffectenbeursUsingNaming(String ipAddress, int portNumber) {
        IEffectenBeurs Effectenbeurs = null;
        try {
            Effectenbeurs = (IEffectenBeurs) Naming.lookup("rmi://" + ipAddress + ":" + portNumber + "/" + bindingName);
        } catch (MalformedURLException ex) {
            System.out.println("Client: Cannot bind Effectenbeurs");
            System.out.println("Client: MalformedURLException: " + ex.getMessage());
            Effectenbeurs = null;
        } catch (RemoteException ex) {
            System.out.println("Client: Cannot bind Effectenbeurs");
            System.out.println("Client: RemoteException: " + ex.getMessage());
            Effectenbeurs = null;
        } catch (NotBoundException ex) {
            System.out.println("Client: Cannot bind Effectenbeurs");
            System.out.println("Client: NotBoundException: " + ex.getMessage());
            Effectenbeurs = null;
        }
        return Effectenbeurs;
    }

    public static void main(String[] args) {
        if (locateRegistry) {
            System.out.println("CLIENT USING LOCATE REGISTRY");
        } else {
            System.out.println("CLIENT USING NAMING");
        }

//        // Get ip address of server
        Scanner input = new Scanner(System.in);
        System.out.print("Client: Enter IP address of server: ");
        String ipAddress = input.nextLine();

        // Get port number
        System.out.print("Client: Enter port number: ");
        int portNumber = input.nextInt();
        // Create client
        BannerController client = new BannerController(ipAddress, portNumber);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

    }
}

我非常怀疑第三类与这个问题有什么关系,但以防万一:我包括了它。

AEX横幅: 打包客户端;

import java.rmi.RemoteException;
import javafx.animation.AnimationTimer;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class AEXBanner extends Application {

    public static final int WIDTH = 1000;
    public static final int HEIGHT = 100;
    public static final int NANO_TICKS = 20000000;
    // FRAME_RATE = 1000000000/NANO_TICKS = 50;

    private Text text;
    private double textLength;
    private double textPosition;
    private BannerController controller;

    private AnimationTimer animationTimer;
    private Timeline timeline;
    private int TIMERTICK = 200;
    private int frame = 0;
    private String koersen;

    public void setController(BannerController banner) {
        //controller = banner(this);
    }
    @Override
    public void start(Stage primaryStage) {

        Font font = new Font("Arial", HEIGHT);
        text = new Text();
        //controller = new BannerController(this);

        text.setFont(font);
        text.setFill(Color.BLACK);

        Pane root = new Pane();
        root.getChildren().add(text);
        Scene scene = new Scene(root, WIDTH, HEIGHT);

        primaryStage.setTitle("AEX banner");
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.toFront();

        timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(false);

        // Start animation: text moves from right to left
        animationTimer = new AnimationTimer() {
            private long prevUpdate;

            @Override
            public void handle(long now) {
                long lag = now - prevUpdate;
                if (lag >= NANO_TICKS) {
                    // calculate new location of text
                    // TODO
                    if (textPosition < 0 - textLength) {
                        textPosition = WIDTH;
                    }
                    textPosition -= 5;

                    text.relocate(textPosition, 0);
                    prevUpdate = now;
                }
            }

            @Override
            public void start() {
                prevUpdate = System.nanoTime();
                textPosition = WIDTH;
                text.relocate(textPosition, 0);
                //setKoersen("Nothing to display");
                super.start();
            }
        };
        animationTimer.start();
    }

    public void setKoersen(String koersen) {

        text.setText(koersen);

        textLength = text.getLayoutBounds().getWidth();
    }
}

所以以我的问题结束(只是为了说清楚):当 RMI 服务器运行时,我需要使用 StartClient 启动这个项目。 StartClient 启动 BannerController。我希望能够直接使用 BannerController 类启动程序。

任何提示或可能的解决方案将不胜感激!

编辑: 在Lasagna建议的changeg之后,当我启动BannerController时直接出现这个错误:

Exception in Application constructor
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class client.BannerController
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: client.BannerController.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:818)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    ... 1 more
Exception running application client.BannerController
D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 0 seconds)

【问题讨论】:

  • 您能否在此处发布一些代码以及错误,以供我们这些不想点击您的链接的人使用。谢谢。
  • 我未能以正确的方式发布代码(四个空格并没有以某种方式做到这一点)。我也不能发布超过 2 个链接,因为我没有 1500 声望点。我现在再试一次,希望这次能成功。
  • 您可以通过选择代码并执行“ctrl + k”来格式化代码。每个帖子旁边都有一个“帮助”链接,如果您点击它会添加一些示例,但如果您点击“了解更多...”,它会将您发送到格式指南:)。 stackoverflow.com/editing-help#comment-formatting

标签: java javafx launch


【解决方案1】:

让我们看看你的错误。

sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) 原因:java.lang.IllegalStateException:不在 FX 应用程序线程上; currentThread = main

这表示您没有“FX 应用程序线程”并且您当前的线程是“主线程”。

这是因为您正在尝试使用 main 方法作为您的“主要方法”,但在 FX 中,它不是那样工作的(很时髦吧?:))。 main 只是启动 FX 应用程序本身的一种方法,这就是您收到此错误的原因。


应用程序的启动方法是事情发生的地方。

在您的第一个类“StartClient”中,您使用“BannerController”的主要部分,然后在您的主要部分中使用“launch(args)”,这是您启动 FX 应用程序的方式。

在您的横幅应用程序中,您有一个包含一堆东西的主类,但没有 launch(args)

我也不确定为什么“start”会抛出一个没有代码的异常。


所以你需要做的是

  1. 从除主类之外的所有类中删除应用程序。
  2. 确保主类在主方法中有"launch(args)"。
  3. 确保主类覆盖“start”方法,并从那里“启动”代码。

所以拿这个代码

public static void main(String[] args) {
        if (locateRegistry) {
            System.out.println("CLIENT USING LOCATE REGISTRY");
        } else {
            System.out.println("CLIENT USING NAMING");
        }

//        // Get ip address of server
        Scanner input = new Scanner(System.in);
        System.out.print("Client: Enter IP address of server: ");
        String ipAddress = input.nextLine();

        // Get port number
        System.out.print("Client: Enter port number: ");
        int portNumber = input.nextInt();
        // Create client
        BannerController client = new BannerController(ipAddress, portNumber);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

    }

并将其更改为

public static void main(String[] args) {
       launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
 if (locateRegistry) {
            System.out.println("CLIENT USING LOCATE REGISTRY");
        } else {
            System.out.println("CLIENT USING NAMING");
        }

//        // Get ip address of server
        Scanner input = new Scanner(System.in);
        System.out.print("Client: Enter IP address of server: ");
        String ipAddress = input.nextLine();

        // Get port number
        System.out.print("Client: Enter port number: ");
        int portNumber = input.nextInt();
        // Create client
        BannerController client = new BannerController(ipAddress, portNumber);
    }

【讨论】:

  • 当我改变这个时我得到的错误更奇怪:
  • 嗯...张贴!您可以在此处尝试,或在原始帖子中进行编辑。如果你这样做 ------------- 它将创建一个新行,你可以更容易地将事情分成几个部分。
  • 我似乎无法发布整个消息,也许这足以帮助您:
    Application constructor java.lang.reflect.InvocationTargetException中的异常

    再往下一点:
    原因:java.lang.RuntimeException:无法构造应用程序实例:sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 处的类 client.BannerController
  • 不,需要整个东西!尝试编辑您的原始消息,并使用代码格式当然:)。另请记住,您的 AEXBanner 类的“start”方法中有一堆东西,需要创建一个新方法,并调用该方法......不过我不太确定它是如何运行的。跨度>
  • 好吧,你调用 BannerController 是值得的 client = new BannerController(ipAddress, portNumber);从它自己的类中,为什么不创建一个方法来做你需要做的事情,而不是构造函数?至于错误...您的代码中似乎只需要清理几件事。看来你是 Swing 用户(来自 Scanner),所以你可能想多读一点关于 FX 结构等的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 2013-03-17
  • 2018-06-06
  • 2012-12-02
  • 2014-11-05
  • 1970-01-01
相关资源
最近更新 更多