2013-04-30 20 views
11

Tôi tải font aller trong java với đoạn mã sau:Sự khác biệt về JLabel khi tải font chữ ttf giữa Windows và Linux

private Font loadFont(final String path) { 
    Font font = null; 

    InputStream fontFile = null; 
    fontFile = FontLoaderClass.class.getResourceAsStream(path); 

    if (fontFile != null) { 
     try { 
      font = Font.createFont(Font.PLAIN, fontFile); 
     } catch (FontFormatException e) { 
      LOGGER.error("Error with font format {}", e); 
     } catch (IOException e) { 
      LOGGER.error("Error accessing font {}", e); 
     } 
    } 
    return font; 
} 

Font được nạp một cách chính xác:

http://www.fontsquirrel.com/fonts/Aller

phông chữ được đặt thành tất cả ".font" thay đổi cài đặt mặc định cho ứng dụng java, nhưng trong Linux được hiển thị chính xác nhưng Windows thì không.

private Font buildFont(final String key, final int size) { 
    Font f = loadFont(ALLER_LT_FONT_PATH); 
    GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(f); 
    if (f == null) { 
     f = (Font) UIManager.get(key); 
    } 
    f = f.deriveFont(Font.TRUETYPE_FONT, size); 
    return f; 
} 

Linux cho thấy: linux image pick

Windows hiển thị: enter image description here

Như bạn có thể nhìn thấy trong hình ảnh, có một số cắt đứt trong Windows gây ra hình ảnh không được hiển thị một cách chính xác.

Có ai từng gặp phải vấn đề này trước đây không?

+1

Tôi không thể thấy điều gì sai ... Chúng trông giống nhau ngoại trừ nhãn trên Windows có vẻ lớn hơn một chút. –

+0

Trong cửa sổ rõ ràng là không trơn tru như trong linux. – RamonBoza

+1

1. Sử dụng hình ảnh PNG thay vì JPEG trong trường hợp này. 2. Bạn có chắc chắn rằng sự cố không phải là do [cài đặt hệ thống cleartype] (https://www.google.com/search?q=windows+configure+anti+aliasing&aq=f&oq=windows+configure+anti+aliasing&aqs= chrome.0.57.12896j0 & sourceid = chrome & ie = UTF-8 # safe = off & sclient = psy-ab & q = windows + cấu hình + cleartype & oq = windows + cấu hình + clear & gs_l = serp.3.0.0i30j0i8i30l2.3729.4520.0.5901.5.5.0.0.0.0.289.1330. 2-5.5.0 ... 0.0 ... 1c.1.12.psy-ab.ZBXVMBdk6hA & pbx = 1 & bav = on.2, hoặc.r_cp.r_qf. & Bvm = bv.45960087, d.bGE & fp = fa702e9da3b617a & biw = 1600 & bih = 775) ? – Crozin

Trả lời

4

tìm hai trình diễn nhỏ kèm theo, cho phép chống răng cưa cho các thành phần Swing một cách tôn trọng cho hoạt động vẽ.

cho các thành phần Swing

// to enable antialiasing (AA) for Swing components 
// 
// either: 
// start the JVM with the option -Dawt.useSystemAAFontSettings=on 
// see also: http://docs.oracle.com/javase/6/docs/technotes/guides/2d/flags.html#aaFonts 
// or: 
// System.setProperty("awt.useSystemAAFontSettings", "on"); 
// - you must call it before the first Swing component is rendered 
// - if AA it's on by default you must set it "off", otherwise you can't 
//  toggle it inside the application 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

import static java.awt.RenderingHints.KEY_ANTIALIASING; 
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF; 
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON; 

public class SwingAntiAliasingDemo { 

    public static void main(String[] args) { 
     System.setProperty("awt.useSystemAAFontSettings", "off"); 
     initGui(); 
    } 

    public static void initGui() { 
     JFrame frame = new JFrame(); 

     frame.addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent we) { 
       System.exit(0); 
      } 
     }); 

     Font font = new Font("Serif", Font.TRUETYPE_FONT, 96); 
     JPanel jpanel = new JPanel(new BorderLayout()); 

     JLabel labelAA = new JLabel("Antialiasing ON") { 
      @Override 
      public void paintComponent(Graphics g) { 
       Graphics2D graphics2d = (Graphics2D) g; 
       graphics2d.setRenderingHint(KEY_ANTIALIASING, 
         VALUE_ANTIALIAS_ON); 
       super.paintComponent(g); 
      } 
     }; 
     labelAA.setFont(font); 
     labelAA.setForeground(Color.WHITE); 

     JLabel labelNoAA = new JLabel("Antialiasing OFF") { 
      @Override 
      public void paintComponent(Graphics g) { 
       Graphics2D graphics2d = (Graphics2D) g; 
       graphics2d.setRenderingHint(KEY_ANTIALIASING, 
         VALUE_ANTIALIAS_OFF); 
       super.paintComponent(g); 
      } 
     }; 
     labelNoAA.setFont(font); 
     labelNoAA.setForeground(Color.WHITE); 

     jpanel.setBackground(new Color(0, 22, 95)); 
     jpanel.add(labelAA, BorderLayout.NORTH); 
     jpanel.add(labelNoAA, BorderLayout.SOUTH); 

     frame.setTitle("stackoverflow question 16304254"); 
     frame.getContentPane().add(jpanel); 
     frame.setLocation(200, 200); 
     frame.pack(); 
     frame.setResizable(false); 
     frame.setVisible(true); 
    } 
} 

cho các hoạt động bốc thăm

// to enable antialiasing (AA) for draw operations 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import javax.swing.JFrame; 

import static java.awt.RenderingHints.KEY_ANTIALIASING; 
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF; 
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON; 

public class DrawAntiAliasingDemo extends JFrame { 

    private Font font; 
    private Color backGroundColor; 

    public static void main(String[] args) { 
     new DrawAntiAliasingDemo(); 
    } 

    public DrawAntiAliasingDemo() { 
     font = new Font("Serif", Font.TRUETYPE_FONT, 96); 
     backGroundColor = new Color(0, 22, 95); 
     addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent we) { 
       System.exit(0); 
      } 
     }); 

     setTitle("stackoverflow question 16304254"); 
     setSize(850, 260); 
     setResizable(false); 
     setVisible(true); 
    } 

    @Override 
    public void paint(Graphics g) { 
     Graphics2D d = (Graphics2D) g; 
     d.setColor(backGroundColor); 
     d.fillRect(0, 0, getWidth(), getHeight()); 
     d.setFont(font); 
     d.setPaint(Color.white); 

     d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); 
     d.drawString("Antialiasing ON", 10, 115); 

     d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF); 
     d.drawString("Antialiasing OFF", 10, 230); 
    } 
} 

cổ vũ Frank

+0

Theo tài liệu JAVA (liên kết của bạn) "awt.useSystemAAFontSettings" được bật theo mặc định và tôi vừa thử nghiệm nó và cài đặt máy tính để bàn của tôi rõ ràng nói rằng AA nên được sử dụng. Đó là ví dụ đầu tiên của bạn mà không có System.setProperty hiển thị các nhãn giống hệt nhau cho tôi. Vì vậy, tôi đoán rằng hành vi là okay. Nếu RamonBoza muốn đảm bảo rằng ứng dụng của mình sử dụng AA bất kể cài đặt máy tính để bàn thì anh ta nên sử dụng giải pháp tham số JVM có vẻ dễ nhất. – Trilarion

+0

@Trilarion JVM tự động kiểm tra nếu hệ điều hành hỗ trợ AA có được bật hay không. Nó có thể được kiểm tra chéo với 'System.out.println (Toolkit.getDefaultToolkit(). GetDesktopProperty (" awt.font.desktophints "));' Tùy chọn JVM "-Dawt.useSystemAAFontSettings = on" buộc AA hỗ trợ bật (với cài đặt mặc định của hệ điều hành). Nếu bạn muốn sử dụng một cài đặt khác, bạn có thể sử dụng một trong các giá trị possiblbe, được mô tả trong liên kết javadoc. – SubOptimal

1

Dường như với tôi rằng hệ điều hành Windows không sử dụng ClearType. ClearType là một tùy chọn, khi được kích hoạt, nó sẽ làm mượt các phông chữ. Đôi khi nó bị vô hiệu hóa vì lý do điều chỉnh hoặc hiệu suất. Xem http://support.microsoft.com/kb/306527. Hãy thử kích hoạt nó.

Để sử dụng ClearType cho các phông chữ màn hình:

  1. Bấm Start, chọn Control Panel, nhấn Appearance and Themes, và sau đó nhấp vào Hiển thị.
  2. Trên tab Giao diện, nhấp vào Hiệu ứng.
  3. Bấm để chọn hộp kiểm Sử dụng phương pháp sau để làm mịn các cạnh của phông chữ màn hình, sau đó bấm ClearType trong danh sách.
+1

trên thực tế, ứng dụng được thực thi trong Windows 8 có ClearType theo mặc định được bật, vô hiệu hóa nó làm cho ứng dụng hoạt động tốt nhưng Windows không ổn. – RamonBoza

+0

Đề xuất của tôi là bật tính năng này, * không * tắt. Hơn nữa kết xuất có thể dẫn đến sự khác biệt nhỏ. Xem http://www.oracle.com/technetwork/java/javase/tech/faq-jsp-138165.html - Phần Hiển thị Văn bản. – cinhtau

+0

Sẽ có nhu cầu điều chỉnh ClearType được yêu cầu mặc dù nó có thể được bật, như được đề xuất trong http://windows.microsoft.com/en-us/windows7/make-text-easier-to-read-using-cleartype . –

1

tôi đã phải đối mặt với một vấn đề tương tự trước cho đến khi tôi tìm thấy trong thư viện này SourceForge được gọi là kim loại mượt mà bạn có thể tải xuống từ Here

Library Trang chủ Smooth Metal

Các Smooth Metal nhìn và cảm nhận là một sự bổ sung cho một số giao diện và cảm thấy bị bao gồm với Java, tăng cường chúng với anti-aliased text.

Bạn sẽ nhận thấy rằng tùy chọn ClearType trong Windows sẽ không ảnh hưởng đến kết quả ...

Sau khi thêm file jar của thư viện trong đường dẫn lớp tôi đã viết ứng dụng này nhỏ java mà ám chỉ rằng JLabel và undo rendering với hai JButtons kết quả là tinh thể rõ ràng:

Đây là đoạn mã mà bạn có thể kiểm tra :

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import javax.swing.plaf.basic.BasicLabelUI; 
import smoothmetal.SmoothLabelUI; // UI Class to set for the JLabel 


public class LabelRender extends JFrame{ 

    JPanel panel = new JPanel(); 
    JPanel panel2 = new JPanel(); 
    JButton button = new JButton("RENDER"); 
    JButton button2 = new JButton("UNDO"); 
    JLabel label = new JLabel("HELLO WORLD"); 

    public LabelRender(){ 
     setSize(600, 250); 
     setLocationRelativeTo(null); 
     setTitle("JLabel Renderer"); 


     setLayout(new BorderLayout()); 

     label.setFont(new Font("Aller", Font.PLAIN, 70)); 
     label.setForeground(Color.WHITE); 

     panel.add(label); 
     panel2.add(button); 
     panel2.add(button2); 

     panel.setBackground(Color.BLACK); 

     this.add(panel2, BorderLayout.NORTH); 
     this.add(panel,BorderLayout.CENTER); 

     setVisible(true); 
     validate(); 


     // System.out.println(label.getUI()); 

     button.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       label.setUI(new SmoothLabelUI()); 
      } 
     }); 

     button2.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       label.setUI(new BasicLabelUI()); 
      } 
     }); 

    } 

    public static void main(String args[]){ 
     new LabelRender(); 
    } 
} 
+0

Hi, khi bạn chạy ví dụ của bạn như 'java -cp; smoothmetal.jar -Dawt.useSystemAAFontSettings = on LabelRender' nó khẳng định những gì tôi đã đề cập trong ví dụ đầu tiên của tôi. "Nếu AA nó theo mặc định bạn phải thiết lập nó "tắt", nếu không bạn không thể chuyển đổi nó bên trong ứng dụng " cổ vũ, Frank – SubOptimal

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