Java SWT:使用自定义 .otf/.ttf 字体

问题描述

我最近将 JavaFX 更改为 SWT。它更快。 但是,我很难让自定义字体从我的可运行 JAR 内部工作。

让它与 JavaFX 一起工作也很有挑战性(找不到任何关于我如何必须在 CSS 中引用实际定义的字体名称才能使其工作的官方文档)。

但是,我现在遇到的问题是 SWT 字体类不接受自定义字体的文件。只是路径。因此,如果我尝试将字体资源作为流打开,它将无法正常工作。如果我通过将它放在包中来引用它(然后我可以简单地将路径称为 "customFont.otf"),它仍然不会检测路径并注册字体。

我能够将其作为可单独运行的 JAR 文件在 IDE外部工作的唯一方法是将文件作为流读取,将其写入外部的某个位置,然后参考那条路。然后在应用程序关闭时,我正在删除字体文件。我想避免这种情况,因为我不想在 JAR 运行时创建任何文件

会不会是 JavaFX 做了同样的事情,但在我不知道的情况下在后台执行,即使我正在将资源作为 Stream 读取?我不希望我的 JAR 访问程序堆栈之外的任何内容。我希望能够从程序堆栈中访问所有资源,因为我的程序是小规模的。

我使用的是 Windows 10 x64 并遵循 SWT 说明:

boolean loadFont = shell.getdisplay().loadFont("appfont.otf");
if(loadFont)
{
    Font f = new Font(shell.getdisplay(),"appfont",18,SWT.norMAL);
    textdisplay.setFont(f);
}
else
{
    System.out.println("Font wasn't loaded.");
}

上面的代码在 IDE 中内部工作。

但它在 JAR 上不起作用,因为在编译的 JAR 中没有这样的路径。 我能以某种方式规范地引用它吗?

我希望至少在相关指令加载到 PCB 时字体文件会加载到程序堆栈中。

最终的问题是否会归结为简单的如何从 JAR 中访问资源,或者 JAR 是否具有可靠的文件结构?

编辑

我忘了提到我确实尝试了一个涉及到的解决方

org.eclipse.swt.graphics.GC;

new GC().getDevice();

但我没有走多远。我仍在研究它,但这可能是解决方案的方法吗?

跟进

上述尝试失败。无法在 IDE 中工作。我实现了

GC gc = new GC(shell);
boolean loadFont = shell.getdisplay().loadFont("appfont.otf");
if(loadFont)
{
    Font f = new Font(gc.getDevice(),"uifont.otf",12,SWT.norMAL);
    gc.setFont(f);
}

测试程序代码

为方便起见,以下是 SWT 的完整代码。它只是一个带有菜单栏和文本显示的最小窗口。自定义字体未加载,程序使用认字体启动。

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class MainWindow
{
    public static void main(String args[])
    {
        display display = new display();
        Shell shell = new Shell(display);
        shell.setText("APP");
        GridLayout mainLayout = new GridLayout(1,false);
        shell.setLayout(mainLayout);
        //----
        GridData gd = new GridData(SWT.FILL,SWT.FILL,true,true);
        Text textdisplay = new Text(shell,SWT.MULTI | SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
        textdisplay.setLayoutData(gd);

        boolean loadFont = shell.getdisplay().loadFont("src/appfont.otf");
        if(loadFont)
        {
            Font f = new Font(shell.getdisplay(),"appfont.otf",SWT.norMAL);
            textdisplay.setFont(f);
        }
        else
        {
            System.out.println("OK");
        }

        Menu menuBar = new Menu(shell,SWT.BAR);
        MenuItem fileMenuLabel = new MenuItem(menuBar,SWT.CASCADE);
        fileMenuLabel.setText("File");

        Menu fileMenu = new Menu(shell,SWT.DROP_DOWN);
        fileMenuLabel.setMenu(fileMenu);

        MenuItem saveFile = new MenuItem(fileMenu,SWT.PUSH);
        saveFile.setText("Edit");

        saveFile.addListener(SWT.Selection,new Listener()
        {
            @Override
            public void handleEvent(Event event)
            {
                if(saveFile.getText().equals("Edit"))
                {
                    saveFile.setText("Save");
                    textdisplay.setEditable(true);
                }
                else
                {
                    saveFile.setText("Edit");
                    textdisplay.setEditable(false);
                }
            }
        });
        //----
        shell.setMenuBar(menuBar);
        shell.open();

        while(!shell.isdisposed())
        {
            if(!display.readAnddispatch())
            {
                display.sleep();
            }
        }
        display.dispose();
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)