2008-10-21 20 views
27

Có cách nào để SWT có được phông chữ đơn cách đơn giản, hoạt động trên nhiều hệ điều hành khác nhau không?SWT - OS cách bất khả tri để có được phông chữ đơn cách

Ví dụ: này hoạt động trên Linux, nhưng không phải Windows:

 

Font mono = new Font(parent.getDisplay(), "Mono", 10, SWT.NONE); 
 

hay tôi cần phải có một phương pháp mà cố gắng tải khác nhau phông chữ (Consolas, Terminal, Monaco, Mono) cho đến khi một người không null? Ngoài ra tôi có thể chỉ định nó trong một tập tin thuộc tính khi khởi động.

Tôi đã cố gắng lấy phông chữ hệ thống từ Hiển thị, nhưng không được đơn cách.

Trả lời

15

Theo phần trên Font Configuration Files trong tài liệu JDK của Internationalization Support API -related, khái niệm về Font logic s được sử dụng để xác định phông chữ nền tảng độc lập nhất định mà được ánh xạ tới phông chữ vật lý trong các tập tin cấu hình phông chữ mặc định:

Nền tảng Java xác định năm tên phông chữ logic mà mọi triển khai phải hỗ trợ: Serif, SansSerif, Monospaced, Dialog và DialogInput. Các tên phông chữ logic này được ánh xạ tới các phông chữ vật lý trong các cách phụ thuộc thực hiện.

Vì vậy, trong trường hợp của bạn, tôi muốn thử

Font mono = new Font(parent.getDisplay(), "Monospaced", 10, SWT.NONE);

để có được một xử lý để các font chữ đơn vật lý của các nền tảng hiện mã của bạn đang chạy trên.

Chỉnh sửa: Có vẻ như SWT không biết bất kỳ điều gì về phông chữ hợp lý (Bug 48055 trên eclipse.org mô tả chi tiết này). Trong báo cáo lỗi này, giải pháp khắc phục sự cố đã được đề xuất, trong đó tên của phông chữ vật lý có thể được truy xuất từ ​​phông chữ AWT ...

+3

này cũng nên có sẵn như java.awt.Font.MONOSPACED – nos

+0

Có vẻ như họ đã cung cấp một lớp [SWTFontUtils] (https://bugs.eclipse.org/bugs/attachment.cgi?id=238603) cho điều này ngay bây giờ. – Campa

4

Theo hiểu biết của tôi, API AWT không hiển thị thông tin phông chữ cơ bản. Nếu bạn có thể nhận được nó, tôi hy vọng nó sẽ được thực hiện phụ thuộc. Chắc chắn, so sánh các tệp ánh xạ phông chữ trong một vài thư mục lib JRE, tôi có thể thấy rằng chúng không được định nghĩa một cách nhất quán.

Bạn có thể tải phông chữ của riêng mình, nhưng điều đó có vẻ hơi lãng phí vì bạn biết nền tảng đi kèm với những gì bạn cần.

Đây là một hack mà tải một phông chữ JRE:

private static Font loadMonospacedFont(Display display) { 
    String jreHome = System.getProperty("java.home"); 
    File file = new File(jreHome, "/lib/fonts/LucidaTypewriterRegular.ttf"); 
    if (!file.exists()) { 
     throw new IllegalStateException(file.toString()); 
    } 
    if (!display.loadFont(file.toString())) { 
     throw new IllegalStateException(file.toString()); 
    } 
    final Font font = new Font(display, "Lucida Sans Typewriter", 10, 
      SWT.NORMAL); 
    display.addListener(SWT.Dispose, new Listener() { 
     public void handleEvent(Event event) { 
      font.dispose(); 
     } 
    }); 
    return font; 
} 

Nó hoạt động trên IBM/Win32/JRE1.4, Sun/Win32/JRE1.6, Sun/Linux/JRE1.6, nhưng là một cách tiếp cận khá mong manh. Tùy thuộc vào nhu cầu của bạn cho I18N, nó có thể là rắc rối có quá (tôi đã không kiểm tra).

Hack khác là để kiểm tra các phông chữ có sẵn trên nền tảng này:

public class Monotest { 

    private static boolean isMonospace(GC gc) { 
     final String wide = "wgh8"; 
     final String narrow = "1l;."; 
     assert wide.length() == narrow.length(); 
     return gc.textExtent(wide).x == gc.textExtent(narrow).x; 
    } 

    private static void testFont(Display display, Font font) { 
     Image image = new Image(display, 100, 100); 
     try { 
      GC gc = new GC(image); 
      try { 
       gc.setFont(font); 
       System.out.println(isMonospace(gc) + "\t" 
         + font.getFontData()[0].getName()); 
      } finally { 
       gc.dispose(); 
      } 
     } finally { 
      image.dispose(); 
     } 
    } 

    private static void walkFonts(Display display) { 
     final boolean scalable = true; 
     for (FontData fontData : display.getFontList(null, scalable)) { 
      Font font = new Font(display, fontData); 
      try { 
       testFont(display, font); 
      } finally { 
       font.dispose(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     Display display = new Display(); 
     try { 
      walkFonts(display); 
     } finally { 
      display.dispose(); 
     } 
    } 

} 

Điều này có lẽ không phải là một phương pháp tốt vì nó có thể để lại cho bạn tiếp xúc đối với ngôn ngữ vấn đề này. Bên cạnh đó, bạn không biết nếu phông chữ đơn cách đầu tiên bạn gặp phải không phải là một bộ biểu tượng cuộn dây.

Cách tiếp cận tốt nhất có thể là đưa ra dự đoán tốt nhất dựa trên danh sách trắng ánh xạ phông chữ/ngôn ngữ và đảm bảo rằng người dùng có thể dễ dàng định cấu hình lại giao diện người dùng cho phù hợp với mình qua FontDialog.

+0

Cảm ơn câu trả lời chi tiết. Tôi tin rằng tùy chọn tốt nhất là như bạn nói - cụ thể là một mặc định nhạt nhẽo như Courier có sẵn trên tất cả các nền tảng và cho phép người dùng thay đổi thuộc tính này bằng hộp thoại cấu hình phông chữ. – JeeBee

+0

Có cách nào để tải 'Phông chữ' từ tài nguyên Java hoặc 'InputStream' thay vì đường dẫn tệp trong SWT không? – parxier

+0

@parxier - không phải là tôi biết. Điều này sẽ tốt hơn như một câu hỏi mới. – McDowell

1

Nếu bạn muốn chỉ là một sử dụng các font chữ đơn "Courier" =>new Font(display, "Courier", 10, SWT.NORMAL)

35

tôi đã dành một thời gian bashing đầu tôi chống lại cái này cho đến khi tôi nhận ra rằng rõ ràng là che khuất phải có quyền truy cập vào một phông chữ monospace để sử dụng trong văn bản của nó các trường, bảng điều khiển, v.v. Một chút đào lên được bật lên:

Font terminalFont = JFaceResources.getFont(JFaceResources.TEXT_FONT); 

Hoạt động nào nếu tất cả những gì bạn quan tâm là giữ một số phông chữ đơn điệu.

Edit: Hoặc dựa trên bình luận @ ctron của:

Font font = JFaceResources.getTextFont(); 
+1

Rất đẹp! Đây là câu trả lời có thể sử dụng duy nhất ở đây – pmf

+6

Hoặc thậm chí đơn giản hơn một chút: Phông chữ = JFaceResources.getTextFont(); – ctron

+1

** Điều này không nhất thiết phải là phông chữ đơn điệu. ** Ví dụ, trong một ứng dụng Eclipse, nó sẽ là phông chữ mà người dùng đã định cấu hình trong * Tùy chọn> Chung> Màu và Phông> Cơ bản> Phông chữ *. Nó là cùng một phông chữ được sử dụng bởi trình soạn thảo văn bản cơ bản trong Eclipse. Hầu như tất cả người dùng sẽ có một phông chữ đơn điệu tất nhiên, nhưng bạn không thể chắc chắn. – Lii

3

Đối với những người có cùng một vấn đề, bạn có thể tải về bất kỳ tập tin ttf font chữ, đặt nó trong thư mục tài nguyên (trong trường hợp của tôi/font/* * .ttf) và thêm methode này vào ứng dụng của bạn. Nó hoạt động 100%.

public Font loadDigitalFont(int policeSize) { 
    URL fontFile = YouClassName.class 
      .getResource("/fonts/DS-DIGI.TTF"); 
    boolean isLoaded = Display.getCurrent().loadFont(fontFile.getPath()); 
    if (isLoaded) { 
     FontData[] fd = Display.getCurrent().getFontList(null, true); 
     FontData fontdata = null; 
     for (int i = 0; i < fd.length; i++) { 
      if (fd[i].getName().equals("DS-Digital")) { 
       fontdata = fd[i]; 
       break; 
      }} 
     if (fontdata != null) { 
      fontdata.setHeight(policeSize); 
      fontdata.setStyle(SWT.BOLD);return new Font(getDisplay(), fontdata));} 
    }return null; } 
+0

Điều này làm việc cho tôi trên Ubuntu 12.04 + Eclipse 3.7, nhưng trên Windows 7 + Eclipse 4.3 loadFont() trả về false khi đối số của nó là một URL gói chứ không phải là một tệp. –

+0

Bạn nên rằng đường dẫn tương đối đã cho "/fonts/DS-DIGI.TTF" nằm trong thư mục tài nguyên, bạn có đang sử dụng maven không? – freesniper

Các vấn đề liên quan