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.
Related
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);
What i want to achieve:
I am using a FileChooser and the user selects an appropriate .jpg image file . Then i am copying that image , renaming it background.jpg to a known folder and trying to set it as the background image of the application using .setStyle(...); There is not problem of copying the image [ i am checking it]
The Problem that occurs:
I have a Stage with a BorderPane . The BorderPane has an background Image , i do that using
borderPane.setStyle("-fx-background-image:url('filepath')");
!It works well the first time!
->Then i am deleting that file [background.jpg] and i am replacing it with another file named also [background.jpg] . The background image of the BorderPane isn't changing ....
I have tried also resetting the same style using again :
borderPane.setStyle("-fx-background-image:url('filepath')");
Finally when i am changing the filename , for example to [background-12.jpg] and reseting the style using the above it changes the background image.
Which exactly is the problem ? I mean i am sure that the background.jpg has been created , i am checking it and also when i am changing the name to something other again and again it works .
Is the Java CSS Parser lazy to parse the new style which is the same but has other -fx-background-image resource ?
As for the File path i am sure it is well , i am using the code below :
//Maou is the File URL in appropriate format for CSS
String maou = file.getAbsoluteFile().toURI().toString()
//Here i add the appropriate file separator, if not JavaFX will report error
maou = maou.replaceAll("\\Q\\\\E", "//");
//Print maou
System.out.println("Maou=\n" + maou);
Solution :
I found as best solution using James_D answer , a little bit modified so it covers the whole window:
BackgroundImage bgImg = new BackgroundImage(image, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
new BackgroundSize(window.getWidth(), window.getHeight(), true, true, true, true));
Rather than using an inline style, I would recommend setting the background via the background property directly:
Image img = new Image(file.getAbsoluteFile().toURI().toString());
BackgroundImage bgImg = new BackgroundImage(img,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.DEFAULT,
BackgroundSize.DEFAULT);
borderPane.setBackground(new Background(bgImg));
The Background class provides Java API programmatic access to all the same properties that can be set by CSS.
While I don't know exactly what's going on, presumably it's some form of caching which JavaFX is doing to try to be "helpful". I may look into the source code later.
To be honest, though, setting a background via CSS feels like the wrong approach to me. I always avoid setting any styles explicitly, like:
borderPane.setStyle("something");
and prefer to add and remove style classes:
borderPane.getStyleClass().add("foo");
borderPane.getStyleClass().remove("foo");
I don't think this is possible in your situation, so I would instead use a StackPane
to layer your content over an ImageView.
ImageView img = new ImageView(new Image(new URL("path")));
StackPane stack = new StackPane();
stack.getChildren.addAll(img, /*overlaid content*/);
I was wondering if by javafx-css it's possible to set label text.
On the official documentation i found a reference to
-fx-text: "whatever";
but isn't working, basically i'm searching for and equivalent of css3
content: "whatever";
specified here: W3School
This is not possible in JavaFX and you can easily verify this by getting all the styleable properties from a Label:
Label label = new Label();
label.getCssMetaData().stream().map(CssMetaData::getProperty).sorted().forEach(System.out::println);
Which yields the following list (not including -fx-text or anything that allows you to set the content according to the CSS Reference Guide):
-fx-alignment
-fx-blend-mode
-fx-content-display
-fx-cursor
-fx-effect
-fx-ellipsis-string
-fx-focus-traversable
-fx-font
-fx-graphic
-fx-graphic-text-gap
-fx-label-padding
-fx-line-spacing
-fx-max-height
-fx-max-width
-fx-min-height
-fx-min-width
-fx-opacity
-fx-opaque-insets
-fx-padding
-fx-position-shape
-fx-pref-height
-fx-pref-width
-fx-region-background
-fx-region-border
-fx-rotate
-fx-scale-shape
-fx-scale-x
-fx-scale-y
-fx-scale-z
-fx-shape
-fx-skin
-fx-snap-to-pixel
-fx-text-alignment
-fx-text-fill
-fx-text-overrun
-fx-translate-x
-fx-translate-y
-fx-translate-z
-fx-underline
-fx-wrap-text
visibility
In the project I am currently working on I have several pieces of information that I would like to make visible via Jlabel. There are a few buttons and textfields elsewhere in the GUI that allow for altering said information I would like to update the JLabel but the text never changes, or updates upon startup.
I have attempted to use concurrency to update the labels, as suggested in other questions on this site, but I have had no luck with the labels updating. The concurrency does work with updating textfields and comboBoxes as needed.
The current iteration of my code looks as follows,
The JFrame
//// This is a snippet from the JFrame
public void start()
{
this.setSize(900, 700);
this.setVisible(true);
devicePanel.populateDeviceDefinitions();
updateServiceInfo();
updateCommandInfo();
startUpdateTimer();
}
public void updateServiceInfo()
{
EventService service = JetstreamApp.getService();
generalPanel.updateServiceInfo(service.getBaseUri(),
service.getAccessKey(), String.valueOf(service.getWindowTime()));
}
public void updateCommandInfo()
{
JetstreamServiceClient client = JetstreamApp.getClient();
generalPanel.updateCommandInfo(client.getBaseUri(), client.getAccessKey());
}
The JPanel named generalPanel
//// This is a snippet from the generalPanel
//// All of the variables in the following code are JLabels
public void updateServiceInfo(String baseUrl, String accessKey,
String windowTime)
{
serviceUrl.setText(baseUrl);
serviceAccessKey.setText(accessKey);
serviceWindowTime.setText(windowTime);
}
public void updateCommandInfo(String baseUrl, String accessKey)
{
commandUrl.setText(baseUrl);
commandAccessKey.setText(accessKey);
}
The labels start with an Empty string for their text and upon window start it is intended that they be updated by grabbing the information from the relevant sources. Can I please have some insight as to why the JLabels never update and display their information?
How did you create the JLabel? If the text starts out as "", and you've created it with new JLabel(""), the width of the JLabel may be initialized to 0 and then none of your text would show up when you update it. I believe I've had that sort of problem in the past. As a test, try using new JLabel("aaaaaaaaaa") or some longer string to create the label, then setText(""); then later, when you setText(somethingElse), see if that causes text to show up. If it does, then the width is probably the problem and you can work on it from there. – ajb 19 mins ago
This comment is the actual answer, when creating a JLabel with an empty string as the text the label's dimensions do not get set properly when using WindowBuilderPro. My labels did exist, and were being updated with the code provided in my question but the labels were not visible.
Starting with a label that has text in it, then setting the text to an empty string works properly.
The method paintImmediately() can be used to cause a Swing component to get updated immediately. after setText(), you should call paintImmediately() like below.
jLabel.setText("new text")
jLabel.paintImmediately(jLabel.getVisibleRect());
You should try to call revalidate() or repaint() on the component that contains your JLabels.
Cheers
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 :)