【问题标题】:Applet is invisible in JavaFX applicationApplet 在 JavaFX 应用程序中不可见
【发布时间】:2016-06-04 19:33:18
【问题描述】:

我正在将我的 GUI 从 Swing 转换为 JavaFX(这样我可以更轻松地添加自定义样式)。

我的应用程序在 Swing 中运行,但无法在 JavaFX 中运行。

我想要的是将外部小程序加载到 SwingNode 中。小程序有自动播放的音乐,我可以听到但我什么都看不到。

我正在努力寻找任何相关文档或帮助。

我的代码:

ClientNew.java

package rsclient.coregui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.concurrent.ExecutionException;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import rsloader.Loader;

public class ClientNew extends Application {

    @Override
    public void start(Stage stage) throws InterruptedException, ExecutionException {

        SwingNode swingNode = new SwingNode();

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final Loader loader = new Loader(Loader.Game.OSRS);
                loader.applet.setLayout(null);
                loader.applet.resize(800, 550);

                JPanel gamepanel = new JPanel(new BorderLayout());
                gamepanel.add(loader.applet, BorderLayout.CENTER);

                swingNode.setContent(gamepanel);

                gamepanel.setVisible(true);
            }
        });

        Tab tab = new Tab();
        tab.setText("My Tab");
        tab.setClosable(false);
        tab.setContent(swingNode);

        TabP ane tabPane = new TabPane();
        tabPane.getStyleClass().add("tabbedPane");
        tabPane.getTabs().add(tab);

        stage.setScene(
            new Scene(
                tabPane,
                1000, 650
            )
        );

        stage.setTitle("My APplication");
        stage.show();
    }

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

Loader.java(不是我的代码,但它似乎可以工作。当然以后会重构)

package rsloader;

import java.applet.Applet;
import java.applet.AppletContext;
import java.applet.AppletStub;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import rsreflection.Reflector;

/***
 *@author Xel
 *@version 1.0
 *@project RSLoader
 *@file Loader.java
 *@date 18.10.2013
 *@time 10.43.48
 */
public class Loader implements AppletStub{
    //insane declarations
    public enum Game{OSRS, RS3, CLASSIC};
    public static final HashMap<String, String> Parameters = new HashMap<String, String>();
    public Game game;
    public URL GamePack;
    public Applet applet;
    public String gameUrl;
    public String MClass;
    public Reflector loader;

    public Loader(Game g)
    {
        game = g;
        if(game == Game.OSRS)
            gameUrl = "http://oldschool69.runescape.com/";
        else if(game == Game.RS3)
            gameUrl = "http://world1.runescape.com/";
        else
            gameUrl = "http://classic2.runescape.com/plugin.js?param=o0,a0,s0";

        try {
            GetParams(new URL(gameUrl));
                        loader  = new Reflector(new URL[]{GamePack});
            applet = (Applet)loader.loadClass(MClass).newInstance();
            applet.setStub(this);
            applet.init();
            applet.start();
        } catch (IOException | InstantiationException | IllegalAccessException | ClassNotFoundException e1) {
            e1.printStackTrace();
        }
    }

    public void GetParams(URL url) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
        String line;
        List<String> params = new ArrayList<String>();
        while((line = reader.readLine()) != null)
        {
            if(line.contains("param name"))
                params.add(line);
            if(GamePack == null) //retarted block
                if(line.contains("archive"))
                    if(game != Game.CLASSIC)
                        GamePack = new URL(gameUrl + line.substring(line.indexOf("archive=") + 8, line.indexOf(" ');")));
                    else
                        GamePack = new URL("http://classic2.runescape.com/" + line.substring(line.indexOf("archive=") + 8, line.indexOf(" code")));
            if(MClass == null)
                if(line.contains("code="))

                        MClass = line.substring(line.indexOf("code=") + 5, line.indexOf(".class"));
        }
        reader.close();

        for(String s : params)
        {
            Parameters.put(GetParamName(s), GetParamValue(s));
        }
    }

    public String GetParamName(String param)
    {
        try{
            int StartIndex = param.indexOf("<param name=\"") + 13;
            int EndIndex = param.indexOf("\" value");
            return param.substring(StartIndex, EndIndex);
        }catch(StringIndexOutOfBoundsException e)//classic handles some differently so why not just catch it =P
        {
            int StartIndex = param.indexOf("<param name=") + 12;
            int EndIndex = param.indexOf(" value");
            return param.substring(StartIndex, EndIndex);
        }
    }

    public String GetParamValue(String param)
    {
        try{
            int StartIndex = param.indexOf("value=\"") + 7;
            int EndIndex = param.indexOf("\">');");
            return param.substring(StartIndex, EndIndex);
        }catch(StringIndexOutOfBoundsException e)//and again :D
        {
            int StartIndex = param.indexOf("value=") + 6;
            int EndIndex = param.indexOf(">');");
            return param.substring(StartIndex, EndIndex);
        }
    }

    @Override
    public void appletResize(int arg0, int arg1) {
    }

    @Override
    public AppletContext getAppletContext() {
        return null;
    }

    @Override
    public URL getCodeBase() {
        try
        {
            if(game == Game.OSRS)
                return new URL("http://oldschool1.runescape.com/");
            else if(game == Game.RS3)
                return new URL("http://world1.runescape.com/");
            else
                return new URL("http://classic2.runescape.com/");
        }catch(MalformedURLException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public URL getDocumentBase() {
        try
        {
            if(game == Game.OSRS)
                return new URL("http://oldschool1.runescape.com/");
            else if(game == Game.RS3)
                return new URL("http://world1.runescape.com/");
            else
                return new URL("http://classic2.runescape.com/");
        }catch(MalformedURLException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getParameter(String arg0) {
        return Parameters.get(arg0);
    }

    @Override
    public boolean isActive() {
        return false;
    }
}

【问题讨论】:

  • 据我所知,SwingNode 只会显示轻量级节点。 Applet 是一个重量级的类。
  • 有趣的是,我确实尝试过 JLabel 和 JButton 之类的东西,它们运行起来没有问题。我该如何验证这一点?
  • 你用 webview 怎么样?将其嵌入您的框架中。
  • @Bravo 你知道我不会把它放到网站上,对吧?
  • 参见javadocs:他们明确声明它应该只用于轻量级组件。我已经有 15 年没有写小程序了(有人吗?),但是 IIRC 你的小程序类只是提供了一些生命周期方法,并为小程序本身添加了某种面板。因此,如果小程序的内容是轻量级 Swing 组件,只需将其直接放在 SwingNode 中即可。如果不是,你很可能不走运。

标签: java swing javafx applet


【解决方案1】:

致任何因使用 JavaFX 呈现小程序而遇到此问题的人

Swing 不支持重量级组件的渲染。 仍然存在并且还没有对重量级组件的任何支持,这对于希望使用 javafx 渲染重量级游戏或应用程序的人来说显然很糟糕。

【讨论】:

【解决方案2】:

我还尝试在 JavaFX 中实现一个摆动小程序。我看不到应用程序。在获得根窗格的大小后,我看到它的 Dimension 为 0,0。小程序不使用 JavaFX 自动调整大小。我在 JApplet 的 init 方法中添加了以下行。

this.getRootPane().setMinimumSize(new Dimension(900,600)); 

这让我可以设置小程序的大小。我正在努力实现一个侦听器,以便它可以随窗口调整大小。

【讨论】:

  • 太棒了,让我知道这是怎么回事。
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 2016-01-08
  • 1970-01-01
  • 2014-08-03
  • 2014-08-02
  • 2011-05-19
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多