I have recently made the change from JavaFX to SWT. It is faster. However, I am having a hard time getting custom fonts to work from inside my runnable JAR.
Getting it to work with JavaFX was also challenging (Could not find any official documentation on how I had to refer to the actual defined font name in the CSS to get it to work).
However, the problem I have now is that the SWT Font class does not accept a File of the custom font. Just the path. Therefore, if I try to open the font resource as a Stream, it won't work. If I refer to it by placing it in the package (Then I could simply refer to the path as "customFont.otf"), it still won't detect the path and register the font.
The only way I am able to get it to work outside the IDE as a solo runnable JAR file is by reading the file as a Stream, writing it to some location outside, and then referring to that path. Then on application close, I am removing the font file. I would like to avoid this since I do not want to create any files as the JAR runs.
Could it be that JavaFX does the same thing but in the background without my awareness, even when I am reading resource as a Stream? I don't want my JAR to access anything from outside the program stack. I want to be able to access all resources from within the program stack since my program is of small-scale.
I am on Windows 10 x64 & following SWT instructions:
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.");
}
This top code works inside the IDE.
But it does not work on the JAR since there is no such path in the compiled JAR. Would I somehow be able to refer to it canonically?
I would have expected the font file to be loaded on to the program stack at the very least when the related instruction was loaded on to PCB.
Could it be that the ultimate issue is boiling down to simply how to access resources from within JAR or whether a JAR even has a solid file structure?
EDIT
I forgot to mention that I did attempt a solution that involved
org.eclipse.swt.graphics.GC;
new GC().getDevice();
But I did not get very far. I am still working on it, but could this be the way to the solution?
FOLLOWUP
The aformentioned endeavour failed. Failed to work in IDE. I implemented
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);
}
PROGRAM CODE FOR TESTING
For your convenience, below is the entire code for the SWT. It is simply a minimal window with a menubar & a text display. The custom font is not loaded and the program launches with default font.
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", 18, 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();
}
}