9

I'm wondering how you would go about importing a font.

I'm trying to use a custom downloaded font but since most computers that would go to run this would not have this font as it's not a default font. How would I go about making the font work even if they don't have the font?

I'm using it for a gameover screen and need to display a score with it and want the score text to be the same font. This is the image,

enter image description here

In case it matters the font name on my computer is Terminal

Edit: I'm assuming it would have to have the font in the directory of the java file and there would be some way of using that but I'm not sure how. Or is there a better way?

Edit2: I have found a nice tutorial on how to do it but need some help on how I go about using this... click me for link

Edit3:

URL fontUrl = new URL("http://www.webpagepublicity.com/" + "free-fonts/a/Airacobra%20Condensed.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
g.setFont(font);

Error Message

File: F:\Computer Science\draw.java  [line: 252]
Error: F:\Computer Science\draw.java:252: font is not public in java.awt.Component; cannot be accessed from outside package

Here is what I'm trying:

URL fontUrl = new URL("http://img.dafont.com/dl/?f=badaboom_bb");
Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
g.setFont(font);

Edit4:

File fontfile = new File("TexasLED.ttf");
File.toURI(fontfile).toURL(fontfile);
URL fontUrl = new URL("fontfile");

Error

Error: F:\Computer Science\draw.java:250: toURI() in java.io.File cannot be applied to (java.io.File)
alaster
  • 3,821
  • 3
  • 24
  • 32
ComputerLocus
  • 3,448
  • 10
  • 47
  • 96
  • How do you intend to distribute your game: Java Web Start or platform-specific native-OS installer? – ecle Dec 03 '11 at 01:38
  • If the font name is not found, OS will try to find the one closes to it. It is called [font-substitution](http://en.wikipedia.org/wiki/Font_substitution) – ecle Dec 03 '11 at 01:45
  • @eee This will for now run from a compiler. It's for a school project. And I don't want the font to go through substitution otherwise it will look ugly. – ComputerLocus Dec 03 '11 at 01:47
  • If you intend to run the Java app from where it resides, then you can copy the font file in the same folder as the app and ask the app to refer to it. `Font font = Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf"));` – ecle Dec 03 '11 at 01:56
  • 1
    @eee Using a `File` is a short-sighted answer to a short-sighted question. The `Font` is effectively an application resource, so should be Jar'd and accessed by URL (and convert that to an `InputStream` for use in the `createFont()` method). – Andrew Thompson Dec 03 '11 at 02:00
  • @eee so why is this code not working: `Font font = Font.createFont(Font.TRUETYPE_FONT, new File("1979.ttf"));` – ComputerLocus Dec 03 '11 at 02:04
  • @AndrewThompson Sometimes, call the font from its file is the proper way if we don't want to register the font files into the OS, so that they remain private to the app. This is usually needed if the font creator wants to be exclusive with his fonts and doesn't want them to distribute at will. (Commercialism, I suppose) – ecle Dec 03 '11 at 02:04
  • @Fogest try to get the path from the running app like `new File(path + "1979.ttf")` – ecle Dec 03 '11 at 02:06
  • @AndrewThompson Of course, we can distribute private fonts as resources inside an app jar as the alternative. Anyway, Java still provides the facility to retrieve from the font file that is external to a jar like in the previous comments. No problem with that. – ecle Dec 03 '11 at 02:15
  • @eee but it's in the same location. – ComputerLocus Dec 03 '11 at 02:24
  • @AndrewThompson I don't care about doing it the "Right" way. I want to use a simple way to use it from the same directory. – ComputerLocus Dec 03 '11 at 02:26
  • @Fogest as I've said you need to get the current path of running App jar (user current working directory). Make sure to put the font in that directory from where the app jar resides. Use `new File(System.getProperty("user.dir") + "1979.ttf");` or `new File(".\\1979.ttf");` or `new File("./1979.ttf");`. – ecle Dec 03 '11 at 02:53
  • @eee The error is `cannot find symbol "file"` – ComputerLocus Dec 03 '11 at 02:55
  • @Fogest If it doesn't run, I suspect that you are running your app from an IDE (build mode). If so, copy the font into the root of your project path temporarily. – ecle Dec 03 '11 at 02:55
  • I am using Dr Java and my font has been in the root of the code the project the whole time. – ComputerLocus Dec 03 '11 at 02:59
  • @Fogest I am not familiar with that IDE, I use Eclipse IDE. In Eclipse IDE, I will put the file in the root/base of the project folder (not in the `src` folder as this will cause the file to be included in the binary - it will be inside a jar if we create the jar). Still, it will get the file if the code refers to it correctly. Use `File.getAbsolutePath()` to tell whether the file path is correct or not. – ecle Dec 03 '11 at 03:08
  • `Font font ..` is (presumably) declared within a `try` block so the reference to `font` goes out of scope before the `g.setFont(font);` line. Move the call to `setFont` to the last line the `try` block, since it makes no sense to set the font if there was a problem. Also, for debugging purposes, call `e.printStacktrace()` within the `catch`. – Andrew Thompson Dec 03 '11 at 03:29
  • @AndrewThompson Okay so I did what you said and when the text appeared it should have been numbers but instead it was simply `-` and that's it. It's not a problem with my code as it worked fine before. So I tried to use the direct link to download a font from dafont.com. I believe I did it right but it just appears in normal arial font as [this image shows](http://localhostr.com/files/0ZcVUS7/Pacman.png) – ComputerLocus Dec 03 '11 at 03:42
  • `cannot find symbol symbol: method printStacktrace()` You might be young, but if you cannot get used to finding and reading the manual, you won't get very far in programming. Look at the methods of the [`Exception`](http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html) class and see if you can spot the mistake I made when typing that suggestion. (Tip: It is a method inherited from another class.) – Andrew Thompson Dec 03 '11 at 03:48
  • @AndrewThompson Wow I can't believe that.A capital. Dang. Anyways when the text trys to display using the font here is the errors its printing repeated. [pastebin link since it's a lot](http://pastebin.com/eFfwt89G) And your font you linked me to doesn't give a error but it displays `-` with no error. I'm guessing that it's because the font doesn't have numbers in it made? – ComputerLocus Dec 03 '11 at 03:58
  • *"I'm guessing that it's because the font doesn't have numbers in it made?"* The default size of a newly created `Font` is 1px (a ridiculously small size). When printing a line of characters it comes out looking something like `......`. See my edited answer for a fix. – Andrew Thompson Dec 03 '11 at 04:13
  • @AndrewThompson Okay it worked! It now displays and I can see it! Thanks for helping me out bro! Sorry for seeming so noob. – ComputerLocus Dec 03 '11 at 04:17
  • *"Sorry for seeming so noob"* We were all noobs once. No apology needed. Glad you got it sorted. :-) – Andrew Thompson Dec 03 '11 at 04:29
  • @AndrewThompson A URL could also direct to a file directory though couldn't it? Because the game will have to use the schools internet which has a ton of sites blocked. I've never tested this font site to see if it's blocked but if it is I just would like to know if there is some fail safe. – ComputerLocus Dec 03 '11 at 04:39
  • An URL is a very handy thing for getting at resources. I 'hot-linked' to that font (something I'm not even sure that site allows) for the ease of making an [SSCCE](http://sscce.org/) (a great way of showing code problems or solutions). But an URL can also point to a `File` as you suspected, or *more importantly*, it can point to an entry in a Zip or Jar file. That is important because if this font is an inherent part of the application, it might as well be put in a Jar along with the classes. Also, you don't want to force the user machine to download 35Kb of `Font` *every* time it is run! – Andrew Thompson Dec 03 '11 at 04:45
  • @AndrewThompson Were using Dr Java and it doesn't seem to support compiling a self executable jar file that can have files archived in it. How would you read a file out of a zip file? – ComputerLocus Dec 03 '11 at 04:47
  • I neither use nor support Dr Java, but the claim that it does not support Jars is astonishing. So I did a quick search (dr+java+jar+file) and discovered [Adding And Removing JARs in DrJava](http://www.seas.upenn.edu/~cis1xx/resources/java/jar/jarindrjava.html). It still does not answer how to include the font in the *same* Jar as the app., but maybe it can point you in the right direction. A Jar is really a specific form of Zip archive, it uses a particular compression and might have other Java specific files inside it (EG a manifest that includes class-path etc.). – Andrew Thompson Dec 03 '11 at 04:56
  • @AndrewThompson I don't think you can include in it. The resource area you linked me to simply includes it, it does not actually compile it with it in it. Could I not just simply replace the URL with the file location of the font? OF course it may not be the most professional way to do it but with what we have to work in I think it will do. – ComputerLocus Dec 03 '11 at 05:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5541/discussion-between-andrew-thompson-and-fogest) – Andrew Thompson Dec 03 '11 at 05:10
  • Okay it doesn't seem to want to accept the file location. One sec I'll get you the error – ComputerLocus Dec 03 '11 at 05:24
  • `illegal escape character` Location is `"F:\Computer Science\Texas LED.ttf"` So can I not do this? – ComputerLocus Dec 03 '11 at 05:24
  • Please refrain from vandalizing your own questions. – Charles Dec 03 '11 at 06:47
  • 1
    @Fogest Illegal escape character, hmm...you need to set it like this `"F:\\Computer Science\\Texas LED.ttf"` in Java. – ecle Dec 03 '11 at 09:34
  • @eee Thanks for covering that. I had not been informed of new comments. – Andrew Thompson Dec 03 '11 at 10:35
  • @AndrewThompson Sorry I didn't include you in my comment...I was so focused with the original poster – ecle Dec 03 '11 at 10:52
  • @eee Hey, no stress. I find the system of comment notification to be 'confusing and problematic' to work with. – Andrew Thompson Dec 03 '11 at 11:05
  • As an aside. I think this has become a 'great question'. +1 – Andrew Thompson Dec 03 '11 at 11:24
  • @AndrewThompson Here is the error using the \\ instead: `java.net.MalformedURLException: unknown protocol: f` – ComputerLocus Dec 03 '11 at 14:21
  • @eee this is just so your notified. – ComputerLocus Dec 03 '11 at 14:25
  • @AndrewThompson Just a reminder. – ComputerLocus Dec 04 '11 at 03:03
  • 1) Create a `File` object 2) **Check `File.exists()`** 3) Call `File.toURI().toURL()`. – Andrew Thompson Dec 04 '11 at 03:06
  • @AndrewThompson I gave it a shot using that and I got a error. I added it to the main post. I'm not 100% sure that's what you meant. I've never used it before. – ComputerLocus Dec 04 '11 at 03:27
  • @AndrewThompson I most likely did it wrong. But am I close? – ComputerLocus Dec 04 '11 at 03:43
  • `File.toURI(fontfile)` 1) Remember what I was saying about the documentation? 2) I did not suggest passing any arguments to either method call. 3) Add to that documentation hunt the fact that I meant an instance of a `file` rather than the class `File`. 4) At now 30+ comments, it is suggesting to me that perhaps you should ask a new, specific, question about converting a `File` to an `URL`. 5) But note that the method to load a `Font` accepts **either** an `InputStream` ***or a `File`***! – Andrew Thompson Dec 04 '11 at 03:44

4 Answers4

14

'Airacobra Condensed' font available from Download Free Fonts.

Registered Font

import java.awt.*;
import javax.swing.*;
import java.net.URL;

class LoadFont {
    public static void main(String[] args) throws Exception {
        // This font is < 35Kb.
        URL fontUrl = new URL("http://www.webpagepublicity.com/" +
            "free-fonts/a/Airacobra%20Condensed.ttf");
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
        GraphicsEnvironment ge = 
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        ge.registerFont(font);
        JList fonts = new JList( ge.getAvailableFontFamilyNames() );
        JOptionPane.showMessageDialog(null, new JScrollPane(fonts));
    }
}

OK, that was fun, but what does this font actually look like?

Display Font

import java.awt.*;
import javax.swing.*;
import java.net.URL;

class DisplayFont {
    public static void main(String[] args) throws Exception {
        URL fontUrl = new URL("http://www.webpagepublicity.com/" +
            "free-fonts/a/Airacobra%20Condensed.ttf");
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
        font = font.deriveFont(Font.PLAIN,20);
        GraphicsEnvironment ge =
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        ge.registerFont(font);

        JLabel l = new JLabel(
            "The quick brown fox jumps over the lazy dog. 0123456789");
        l.setFont(font);
        JOptionPane.showMessageDialog(null, l);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • I tried using this: `URL fontUrl = new URL("http://www.webpagepublicity.com/" + "free-fonts/a/Airacobra%20Condensed.ttf"); Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream()); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(font); }catch(Exception e) { } g.setFont(font);` I got this error: `font cannot be accessed from outside package` – ComputerLocus Dec 03 '11 at 02:54
  • @AndrewThompson It would be nice to come up with a fallback mechanism just in case the user is unable to load the font from Internet especially when the font doesn't have any good system font to substitute it. – ecle Dec 03 '11 at 09:30
  • 3
    @eee (sigh) The point about loading a `Font` off the net is ..not the point, since it is not what I am suggesting. The act of hot-linking to a `Font` was merely to **create an SSCCE**. Do you have a *better* way to demonstrate loading a custom `Font` in a code that is 'SC' (self-contained)? Personally I'd include the `Font` in a Jar that is added to the run-time class-path of the app. – Andrew Thompson Dec 03 '11 at 10:26
  • @eee ..continued after 5 min. limit. .. No fuss, no muss. OTOH the OP is insisting on a `File` based location, so some of my other comments (not necessarily on this answer) also refer to loading a `Font` from a `File`. – Andrew Thompson Dec 03 '11 at 10:33
  • @AndrewThompson You point is taken... I just want to address the limitation of hot-linking a font in a non-networked environment. The best still is either to include the fonts inside a jar as resources or to get them from outside a jar (from a file directory or font file cache). It depends on font licensing as well. In my case with the current project, I am not allowed to embed licensed fonts inside a jar. So, I have to access the font files either from a special folder under the installation folder or to install them as system fonts so they can be used in the application. – ecle Dec 03 '11 at 10:48
  • @eee *"I just want to address the limitation of hot-linking a font in a non-networked environment."* And that is a good point, thanks for high-lighting the perils. (re. Font licensing) *"So, I have to access the font files either from a special folder"* (shudder) That is unfortunate. Still, we gotta' do what we gotta' do. I won't begin to describe some of the licensing hoops I had to leap through in order to create a project based around 4 holy testaments. ;) – Andrew Thompson Dec 03 '11 at 11:01
  • This answer seems to work for only half the fonts on that site, any ideas why? Also, are there any other sites that this method can be used with? The fonts on the site provided are, imo, ugly. – ylun.ca Apr 09 '14 at 21:51
  • 2
    @ylun.za *"any ideas why?"* Provide an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example) that fails. *"..are there any other sites that this method can be used with?"* It was never intended that 'real world' apps get their fonts by hot-linking to an internet site! Download the font and include it in one of the application Jars. – Andrew Thompson Apr 09 '14 at 23:19
  • I see. And simply try another url; one that i found did not work was the "Amiga Forever" font. – ylun.ca Apr 09 '14 at 23:57
  • 1
    @ylun.za I'm not going searching that site for the font you mention. If you want me to try it, post an MCVE, like I did. – Andrew Thompson Apr 10 '14 at 00:33
4

You can use GraphicsEnvironment.registerFont

http://docs.oracle.com/javase/6/docs/api/java/awt/GraphicsEnvironment.html#registerFont(java.awt.Font)

With this you can load a font from a .ttf file:

private static final Font SERIF_FONT = new Font("serif", Font.PLAIN, 24);

private static Font getFont(String name) {
    Font font = null;
    if (name == null) {
        return SERIF_FONT;
    }

    try {
        // load from a cache map, if exists
        if (fonts != null && (font = fonts.get(name)) != null) {
            return font;
        }
        String fName = Params.get().getFontPath() + name;
        File fontFile = new File(fName);
        font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
        GraphicsEnvironment ge = GraphicsEnvironment
                .getLocalGraphicsEnvironment();

        ge.registerFont(font);

        fonts.put(name, font);
    } catch (Exception ex) {
        log.info(name + " not loaded.  Using serif font.");
        font = SERIF_FONT;
    }
    return font;
}
Wouter Dorgelo
  • 11,770
  • 11
  • 62
  • 80
  • @Mr.Pallazzo BTW - sorry for hi-jacking your answer. I feel that it should be *your* answer that gets the 'tick'. I just turned your suggestion into an SSCCE (or 2, with pretty screen-shots). – Andrew Thompson Dec 03 '11 at 10:31
3

I have solved my own problem. I have done

URL fontUrl = new URL("file:///F:/Computer_Science/TexasLED.ttf");

That points to the font and works for me!

ComputerLocus
  • 3,448
  • 10
  • 47
  • 96
0

You can use fonts embedded in your application jar file too. I have used this function for many years to load fonts in my projects.

public Font getFont(String fileName) throws Exception {
    String path = "/xyz/isururanawaka/wb/fonts/" + fileName;
    URL url = getClass().getResource(path);
    return Font.createFont(Font.TRUETYPE_FONT, new File(url.toURI()));
}