How can I embed a custom font in a JavaFX Application? I've tried making a fonts.mf file, and following the instructions to a similar question linked below. I don't want to use CSS if I don't have to. I want to focus on learning core JavaFX stuff.
Here is what I've been messing around with:
private static Label makeTitle() {
Label title = new Label("Bandit King");
Font font = new Font("OldStyle", 40);
title.setFont(font);
return title;
}
my fonts.mf file contains just this line:
OldStyle = /home/myName/Desktop/My_Java_Projects/Bandit_King/banditKing/OLDSH.TTF
This is not a duplicate of this question. Eclipse says, "CustomFontApp, cannot be resolved to a type".
I've tried making a fonts.mf file
You don't need it.
This is not a duplicate of this question. Eclipse says, "CustomFontApp, cannot be resolved to a type".
CustomFontApp is just the name of a class used in the answer you linked - your class name is obviously different, and you should've changed it.
This line:
Font font = new Font("OldStyle", 40);
will load OldStyle font only if it's installed on your system. You aren't using an installed font, but the embedded one, so that won't work.
You need to use Font.loadFont(InputStream, double) or Font.loadFont(String, double) to load your custom font from disk:
// use this to load font from your application's resource folder (`res/fonts/OLDSIH.TTF`)
Font font = Font.loadFont(getClass().getResourceAsStream("/fonts/OLDSIH.TTF"), 40);
// or this one to load font from the specified (absolute) path
// (not recommended, use the method above or, at least, change this into relative path):
Font font = Font.loadFont("file:///home/myName/Desktop/My_Java_Projects/Bandit_King/banditKing/OLDSH.TTF", 40);
Related
I have created a GUI with Java Swing and wanting to create a custom toolbar according to my modules. Below are the images am wanting to use:
These images are placed in the same level as the src folder within my application. I am aware that I can perhaps create a jar with these images so that I can easily access them from within my application but do not know how. I have spent hours trying to make this work.
Below is my GUI that I have created ad wanting to beautify with these images for the toolbar else create an array of labels that will act as a navigation but either approach I couldn't get it to work.
The code below was my last attempt on this:
JToolBar toolbar1 = new JToolBar();
ImageIcon client = new ImageIcon("clients.png");
ImageIcon timesheet = new ImageIcon("timesheets.png");
JButton clientTB = new JButton(client);
JButton timesheetTB = new JButton(timesheet);
toolbar1.add(clientTB );
toolbar1.add(timesheetTB);
add(toolbar1, BorderLayout.NORTH);
I even moved these images and placed them within the class that's calling them.
What could I be doing wrong, please help?
You have a look at the JavaDocs for ImageIcon(String), the String value is "a String specifying a filename or path"
This is a problem, because your images aren't actually files, any more, they have been embedded within your application (typically within the resulting jar file) and no longer be treated like "normal files".
Instead, you need to use Class#getResource which searches the application's classpath for the named resource, something like...
// This assumes that the images are in the default package
// (or the root of the src directory)
ImageIcon client = new ImageIcon(getClass().getResource("/clients.png"));
Now, I have a personal dislike for ImageIcon, because it won't tell you when the image is loaded for some reason, like it can't be found or it's the wrong format.
Instead, I'd use ImageIO to read the image
ImageIcon client = new ImageIcon(ImageIO.read(getClass().getResource("/clients.png")));
which will do two things, first, it will throw a IOException if the image can't be loaded for some reason and two, it won't return until the image is fully loaded, which is helpful.
See Reading/Loading an Image for more details
I've got a problem with formatting a string using javas String.format.
I'm adding the string containing a description and a price to a swing JList component. I want that the prices are always under each other.
So I use:
String ret = String.format( "%s %-" + Integer.toString(articleNameLength) + "s %3s %9.2f EUR",
(new SimpleDateFormat("dd.MM.yyyy")).format(date), article, " ", price );
You can also see the code at line 205 at:
https://github.com/hanneseilers/MyBudget/blob/master/MyBudget/src/de/hanneseilers/core/Article.java
That's working fine if I start the application using eclipse or a simple batch file that runs
java -jar MyBudget.ja
But if i use a doubleclick in file explorer to start the jar, the layout breaks up and the prices aren't under each other.
Any idea why this happens?
I found a working solution for this.
The problem was that the application only can load a speficic monospaced font (that has same width for each character) if I start the jar using a batch script. Using a double script, java can not find the spefific font and uses default not-monospaced (irregular width for each character).
I changed the font of the JList swing component that displays the string to a not further specified monospaced font. That causes the application to load any monospaced font and it's working!
list.setFont(new Font("Monospaced", Font.BOLD, 12));
I am extending TitleAreaDialog in my class.
The default font for the title in the title area does not look very nice.
Is it possible to change the font for the title?
I don't need to change the font any where else in the code, just the title text.
I have tried using FontRegistry, as well as StyledText.
But I can not figure out how to assign the new font to setTitle().
FontRegistry fontRegistry = JFaceResources.getFontRegistry();
FontData mainFont = new FontData("Garamond", 18, SWT.NORMAL);
fontRegistry.put("mainFont", new FontData[]{mainFont});
?.setText("Title Text");
?.setFont(fontRegistry.get("mainFont"));
setTitle(?);
I really don't think that's possible. The title String you set via setTitle(String) is displayed in the private field titleLabel. You cannot access this Label when you subclass TitleAreaDialog. Consequently, you cannot apply a Font to it.
So the only possibility I could think of is to create your own MyTitleAreaDialog extends TrayDialog based on the code of the original TitleAreaDialog and set you Font there. You can find the source in your SWT.jar or online.
This is an answer to an old question but it may help someone. You can do it by changing the font in the JFaceResources font registry.
static
{
JFaceResources.getFontRegistry().put(JFaceResources.BANNER_FONT, yourFont.getFontData());
};
I've added this code inside a static block so it only executes once.
I use Netbeans 7.0 with JDK6 under Windows 7 to design the user interface of my Java application. I apply System look and feel. But it looks the way I want in Windows but differs in MacOS and even worse, it looks different in different window managers in Linux (LXDE, GNOME, KDE, XFCE).
By different I mean the fonts look and their size. In Windows, if a label looks "v 1.23", it looks like "v ..." in other OSes because the fonts become bigger in that OS and the JLabel do not have enough place to show. This happens in several places.
I don't want to increase the label width. I want the label to look the same in that given width in all OS. By default, Netbeans uses the font Tahoma 11pt on my pc. I think it's not available in all OSes so the other OSes use different font.
Is Arial a common font?
Should I change the font of every element to Arial manually? Or any other options?
Instead, use a layout manager and a logical font family. This example with the Font below adds 24-point italic serif text to the center of a (default) BorderLayout to achieve a pleasing result on disparate platforms.
ta.setFont(new Font("Serif", Font.ITALIC, 24));
Mac OS X:
Windows 7:
Ubuntu Linux:
When it comes to window managers there is a lot more to it than just font size, for instance the width between 2 controls are handled differently in gnome & KDE. when it comes down to using the same font size across all platforms you can use Sans Serif font, this is available in all the OS'es I've worked with.
it would also be better (if you can't find serif in an OS where you want to run your app) you can download a font (free ones from GNU Free Fonts).
when it comes to setting the font sizes & the fonts, why don't you try using a theme & set the font there...
you can use the UIManager.setLookAndFeel() method to change themes.
here is a link on Look & Feel
An old question, but I've found it because I was looking for a solution.
And my solution is: use DejaVu fonts.
The Java dialog font looks different in Linux and Windows, but DejaVuSans 12 is very like the dialog font in Linux and looks the same in Windows (in Windows 8.1 at least).
My code:
...
static Font dejaVuSans;
static final String resPath = "<classpath>/resources/"; // no leading "/"
...
public static void main(String[] args) {
/* See:
* https://stackoverflow.com/questions/7434845/setting-the-default-font-of-swing-program
* https://stackoverflow.com/questions/8361947/how-to-get-getclass-getresource-from-a-static-context
*/
dejaVuSans = null;
Font f;
try {
InputStream istream = <ClassName>.class.getClassLoader().getResourceAsStream(
resPath + "DejaVuSans.ttf");
dejaVuSans = Font.createFont(Font.TRUETYPE_FONT, istream);
f = dejaVuSans.deriveFont(Font.PLAIN, 12);
} catch (Exception e) {
System.err.println(e.getMessage());
f = null;
}
if (f == null)
f = new Font("Dialog", Font.PLAIN, 12);
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get (key);
if (value != null && value instanceof javax.swing.plaf.FontUIResource)
UIManager.put (key, f);
}
...
}
Of course, if DejaVuSans.ttf is not embedded in the jar file you can import it at runtime. See How do you import a font?.
Lucida Sans Regular is always bundled with Java but I don't think it will solve the problem that some text/labels go out of format. That depends also on the users's screen resulotion.
How can I create a Java/Swing text component that is both styled and has a custom font? I want to highlight a small portion of the text in red, but at the same time use a custom (embedded via Font.createFont) font. JLabel accepts HTML text, which allows me to highlight a portion of the text, but it ignores font settings when rendering HTML. Other text components such as JTextArea will use the custom font, but they won't render HTML. What's the easiest way to do both?
Here's an example of using JTextPane unsuccessfully:
JTextPane textPane = new JTextPane();
textPane.setFont(myCustomFont);
textPane.setText(text);
MutableAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setForeground(attributes, Color.RED);
textPane.getStyledDocument().setCharacterAttributes(
text.indexOf(toHighlight),
toHighlight.length(),
attributes, true
);
This successfully displays the text with the "toHighlight" portion highlighted in red, but it doesn't use myCustomFont. Note that I could set a String font with StyleConstants.setFontFamily(), but not a custom font.
OK, I see the problem better now.
After checking some Swing source code, it is clear you cannot use the DefaultStyledDocument and have it use a physical font (one you created yourself with createFont) out of the box.
However, what I think you could do is implement your own StyleContext this way:
public class MyStyleContext extends javax.swing.text.StyleContext
{
#Override public Font getFont(AttributeSet attr)
{
Font font = attr.getAttribute("MyFont");
if (font != null)
return font;
else
return super.getFont(attr);
}
}
Then you have to:
create a DefaultStyledDocument with
a new MyStyleContext()
"attach" it to the JTextPane
call attributes.addAttribute("MyFont", myCustomFont); in your snippet above
I did not try it but I think it should work or it might be a good path to investigate.
jfpoilpret's solution worked perfectly! For posterity's sake, here's a working code snippet:
JTextPane textPane = new JTextPane();
textPane.setStyledDocument(new DefaultStyledDocument(new StyleContext() {
#Override
public Font getFont(AttributeSet attr) {
return myCustomFont;
}
}));
textPane.setText(text);
MutableAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setForeground(attributes, Color.RED);
textPane.getStyledDocument().setCharacterAttributes(
text.indexOf(toHighlight),
toHighlight.length(),
attributes, true
);
Thanks, jfpoilpret!
You should try to use JEditorPane or JTextPane instead.
They allow rich style in the content, at the price of a more complex API.
Unfortunately, if you are in search of a pixel-prefect UI, they also have an additional problem: they don't support baseline-alignment (Java 6 feature).
I had the same problem when writing a program in Clojure, ie. using fonts loaded from TTF in a JEditorPane displaying HTML text. The solution here worked all right - I copy the interesting part here for future reference:
(def font1 (with-open [s (FileInputStream. "SomeFont.ttf")]
(.deriveFont (Font/createFont Font/TRUETYPE_FONT s) (float 14))))
(def font2 (Font. "SansSerif") Font/PLAIN 14)
(let [editor (JEditorPane. "text/html" "")]
(.setDocument editor
(proxy [HTMLDocument] []
(getFont [attr]
(if (= (.getAttribute attr StyleConstants/FontFamily)
"MyFont")
font1
font2)))))
This assumes that the HTML document refers to a font-family "MyFont", e.g. with a CSS snippet like
p { font-family: "MyFont" }
Note that with this you have to handle all font requests. This is because of the limitation of proxy not being able to call the member functions of the superclass. Also, if you want to handle different font sizes, you have to do that "manually", checking the StyleConstants/FontSize attribute and creating a font with deriveFont accordingly.
I hope this will help somebody :)