2013-04-30 18 views
11

mam przesyłaniem czcionkę aller w java z następującego kodu:Różnice w JLabel podczas ładowania czcionki ttf pomiędzy Windows i 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; 
} 

Czcionka jest prawidłowo załadowany:

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

czcionka jest ustawiona na wszystkie ".font" zmieniające domyślne ustawienia dla aplikacji java, ale w Linuksie jest wyświetlane poprawnie, ale Windows nie.

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 pokazuje: pokazuje linux image pick

Windows: enter image description here

Jak widać na zdjęciach, jest trochę odcięty w systemie Windows, który powoduje, że obraz nie być prawidłowo wyświetlane.

Czy ktoś wcześniej doświadczył tego problemu?

+1

Nie widzę niczego złego ... Wyglądają tak samo, chyba że etykieta w systemie Windows wydaje się nieco większa. –

+0

W systemie Windows wyraźnie nie jest gładka, jak w systemie Linux. – RamonBoza

+1

1. W takim przypadku użyj obrazów PNG zamiast JPEG. 2. Czy jesteś pewien, że problem nie wynika z [ustawień kodów usterek systemu] (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 + configure + cleartype & oq = windows + configure + 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, or.r_cp.r_qf. & Bvm = bv.45960087, d.bGE & fp = fa702e9da3b617a & biw = 1600 & bih = 775) ? – Crozin

Odpowiedz

4

znaleźć dwa małe dema dołączone, co umożliwia wygładzenie antyaliasingu dla komponentów Swing w sposób właściwy dla operacji rysowania.

komponentów 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); 
    } 
} 

dla operacji wyciągania

// 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); 
    } 
} 

Cheers Frank

+0

Zgodnie z dokumentem JAVA (twój link) "awt.useSystemAAFontSettings" jest domyślnie włączony i właśnie go przetestowałem, a moje ustawienia pulpitu wyraźnie mówią, że należy użyć AA. To jest twój pierwszy przykład bez System.setProperty pokazuje identyczne etykiety dla mnie. Więc myślę, że to zachowanie jest w porządku. Jeśli RamonBoza chce się upewnić, że jego aplikacja używa AA bez względu na ustawienia pulpitu, powinien użyć rozwiązania parametru JVM, które wydaje się najłatwiejsze. – Trilarion

+0

@Trilarion JVM sprawdza automatycznie, czy obsługa systemu operacyjnego dla AA jest włączona, czy nie. Może być krzyż sprawdzane 'System.out.println (Toolkit.getDefaultToolkit() getDesktopProperty ("awt.font.desktophints").);' Opcja JVM "-Dawt.useSystemAAFontSettings = on" wymusić AA wsparcie na (z domyślnym ustawieniem systemów operacyjnych). Jeśli chcesz użyć innego ustawienia, możesz użyć jednej z możliwych wartości, opisanych pod linkiem javadoc. – SubOptimal

1

Wydaje mi się, że system operacyjny Windows nie używa ClearType. ClearType jest opcją, po włączeniu wygładza czcionki. Czasami jest wyłączony ze względu na strojenie lub wydajność. Zobacz http://support.microsoft.com/kb/306527. Spróbuj włączyć.

Aby korzystać ClearType do czcionek ekranowych:

  1. Kliknij przycisk Start, kliknij polecenie Panel sterowania, kliknij polecenie Wygląd i kompozycje, a następnie kliknij przycisk Wyświetl .
  2. Na karcie Wygląd kliknij Efekty.
  3. Kliknij, aby zaznaczyć pole wyboru Użyj poniższej metody, aby wygładzić krawędzie czcionek ekranowych, a następnie kliknij pozycję ClearType na liście.
+1

w rzeczywistości aplikacja jest wykonywana w systemie Windows 8, który ma domyślnie włączony tryb ClearType, wyłączenie go powoduje, że aplikacja działa poprawnie, ale system Windows nie wygląda dobrze. – RamonBoza

+0

Moja sugestia dotyczy włączenia, * nie * wyłączenia. Ponadto renderowanie może prowadzić do niewielkich różnic. Zobacz http://www.oracle.com/technetwork/java/javase/tech/faq-jsp-138165.html - Section Text Rendering. – cinhtau

+0

Czy będzie potrzeba tuningu ClearType, mimo że może być włączony, jak zasugerowano w http://windows.microsoft.com/en-us/windows7/make-text-easier-to-read-using-cleartype . –

1

mam przed obliczu podobnego problemu aż znalazłem tej biblioteki w SourceForge który nazywa Smooth Metal możesz go pobrać od Here

Biblioteka Główna Smooth Metal

Smooth Metal wygląd i jest dodatkiem do niektórych z wyglądu i czuje się z tym Java, wzmacniając je anti-aliased text.

Można zauważyć, że opcja ClearType w systemie Windows nie wpłynie na Wynik ...

Po dodaniu pliku JAR biblioteki w ścieżce klasy Napisałem tę małą aplikację Java, który renderuje JLabel i cofnąć renderowania z dwóch JButtons wyniki były krystalicznie jasne:

Oto kod, który można przetestować :

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

Cześć, po uruchomieniu przykład jako 'java cp; smoothmetal.jar -Dawt.useSystemAAFontSettings = on LabelRender' potwierdza to, co już wspomniałem w moim pierwszym. Przykład:„jeśli AA to domyślnie musisz ustaw go na "off", w przeciwnym razie nie można go przełączyć wewnątrz aplikacji " okrzyki, Frank – SubOptimal

Powiązane problemy