java - Is there a non-proprietary equivalent to FontUtilities.getCompositeFontUIResource(Font)? -


if create font using new font("arial", font.plain, 10), later, when try display missing glyphs in font, familiar squares indicating missing glyphs.

a long time ago, found workaround - pass font fontutilities.getcompositefontuiresource(font) , font handles fallback characters aren't in font itself.

problem is, utility in sun.font, , eliminate compiler warning.

given many years have passed in meantime, there proper way this?

demo:

import java.awt.font; import java.awt.gridlayout;  import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.swingutilities;  import sun.font.fontutilities;  public class testfonts implements runnable {     @override     public void run()     {         font font = new font("arial", font.plain, 20);          jlabel label1 = new jlabel("before \u30c6\u30b9\u30c8");         label1.setfont(font);          jlabel label2 = new jlabel("after \u30c6\u30b9\u30c8");         label2.setfont(fontutilities.getcompositefontuiresource(font));          jframe frame = new jframe("font test");         frame.setlayout(new gridlayout(2, 1));         frame.add(label1);         frame.add(label2);         frame.pack();         frame.setdefaultcloseoperation(jframe.exit_on_close);         frame.setvisible(true);     }      public static void main(string[] args)     {         swingutilities.invokelater(new testfonts());     } } 

result:

enter image description here

you can exploit fact jcomponents able display html, , override font characters jcomponent's font cannot display, placing characters in <span>:

import java.util.formatter;  import java.awt.font; import java.awt.gridlayout;  import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.swingutilities;  import sun.font.fontutilities;  public class testfonts implements runnable {     /**      * replaces plain text meant displayed in jcomponent      * html forces font dialog characters      * specified font cannot natively display.      *      * @param originaltext text transform html, forced fonts      *                     needed      * @param font default font used display text      *      * @return html version of original text, forces fonts      *         necessary ensure characters displayed      */     static string tocompositefonttext(string originaltext,                                       font font) {         formatter html = new formatter();         html.format("%s", "<html><body style='white-space: nowrap'>");          boolean fontoverride = false;         int len = originaltext.length();         (int = 0; < len; = originaltext.offsetbycodepoints(i, 1)) {             int c = originaltext.codepointat(i);              if (font.candisplay(c)) {                 if (fontoverride) {                     html.format("%s", "</span>");                     fontoverride = false;                 }             } else {                 if (!fontoverride) {                     html.format("<span style='font-family: \"%s\"'>",                         font.dialog);                     fontoverride = true;                 }             }              if (c == '<' || c == '>' || c == '&' || c < 32 || c >= 127) {                 html.format("&#%d;", c);             } else {                 html.format("%c", c);             }         }          if (fontoverride) {             html.format("%s", "</span>");         }          html.format("%s", "</body></html>");          return html.tostring();     }      /**      * replaces text of specified jlabel html contains      * same text, forcing font dialog characters      * jlabel's current font cannot display.      *      * @param label jlabel text adjusted , replaced      */     static void adjusttext(jlabel label) {         label.settext(tocompositefonttext(label.gettext(), label.getfont()));     }      @override     public void run()     {         font font = new font("arial", font.plain, 20);          jlabel label1 = new jlabel("before \u30c6\u30b9\u30c8");         label1.setfont(font);          jlabel label2 = new jlabel("after \u30c6\u30b9\u30c8");         label2.setfont(fontutilities.getcompositefontuiresource(font));          jlabel label3 = new jlabel("corrected \u30c6\u30b9\u30c8");         label3.setfont(font);         adjusttext(label3);          jframe frame = new jframe("font test");         frame.setlayout(new gridlayout(3, 1));         frame.add(label1);         frame.add(label2);         frame.add(label3);         frame.pack();         frame.setdefaultcloseoperation(jframe.exit_on_close);         frame.setvisible(true);     }      public static void main(string[] args)     {         swingutilities.invokelater(new testfonts());     } } 

update:

in addition, can monitor label's text property, make happen automatically:

label.addpropertychangelistener("text", new propertychangelistener() {     @override     public void propertychange(propertychangeevent event) {         string text = (string) event.getnewvalue();         if (text != null && !text.startswith("<html>")) {             adjusttext((jlabel) event.getsource());         }     } }); 

the obvious drawback there no (easy) way adjust text starts <html>. (actually i'm sure done loading label's text htmldocument.)


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -