2017-10-11 1 views
-1

JFrame 내부의 JLabel에 일부 고화질 유니 코드 문자를 추가하려고하지만 알려진 지원되는 글꼴을 사용함에도 불구하고 상자로만 표시됩니다. 그러나이 동일한 문자를 Eclipse 콘솔에 인쇄하면 잘 보입니다. 여기 내 코드는 "프레임"이 내 JFrame이고 "textField1"이 내 JLabel입니다. 모나코 글꼴 이클립스 콘솔이 사용하는 것과 동일한 글꼴이며,이 유니 코드 문자를 지원하기 위해 알고있다 : 나는 많은 다른 글꼴로 JLabel의 설정을 시도했습니다유니 코드 특수 문자가 Java 콘솔에 있지만 스윙에는 나타나지 않습니다.

JFrame frame = new JFrame(); 
JLabel textField1 = new JLabel(); 
frame.add(textField1); 
frame.setFocusable(true); 
frame.setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)); 
frame.setPreferredSize(new Dimension(1000, 500)); 
frame.requestFocusInWindow(); 
frame.textField1.setFont(new Font("Monaco", Font.PLAIN, 11)); 
frame.textField1.setText("\uD83C\uDF2D"); 
frame.pack(); 
frame.setVisible(true); 

,하지만 변경이 모두의 상대적인 모양입니다 "누락 된 문자"상자. 그러나이 인쇄 할 경우 :

System.out.println("\uD83C\uDF2D"); 

예상대로 문자를 콘솔에서 인쇄합니다. Swing에서 이러한 심볼이 작동하지 않도록 인코딩 문제가 있습니까?

+2

:

225 font families installed Segoe UI Emoji Segoe UI Symbol 

위의 출력뿐만 아니라, 사용자가 지정된 유니 코드 문자 (들)을 지원하는 모든 글꼴을 선택할 수있는 GUI를 표시를 생성하는 소스 코드 가장 일반적인 원인은 글꼴 표시가 문자 표시를 지원하지 않는다는 것입니다. – MadProgrammer

+0

@MadProgrammer 예.하지만이 글꼴이 문자를 지원하는지 100 % 확신합니다. 나는 그것을 완벽하게 표현했다. 나는이 문자를 쓸모없는 것으로 지원하는 것으로 알려진 여러 개의 다른 글꼴을 시도했다. – zooksman

+1

모나코 글꼴에 문자 ([ 'HOT DOG'(U + 1F32D))] (http://www.fileformat.info/info/unicode/char/1f32d/index.htm)가 있다고 생각하지 않습니다. 콘솔이 특수 문자를 표시하기 위해 다른 글꼴로 자동 전환 될 가능성이 큽니다. 해당 문자를이 페이지에 붙여 넣으면 작동하지 않습니다. https://www.myfonts.com/fonts/apple/monaco/ – Andreas

답변

3

Font.canDisplayUpTo(String) 방법은 여기에 당신의 친구입니다. 텍스트를 지원하는 글꼴 조합을 만드는 방법입니다.

 String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment(). 
       getAvailableFontFamilyNames(); 
     System.out.println(fonts.length + " font families installed"); 
     Vector<String> supportedFonts = new Vector<>(); 
     for (String fontName : fonts) { 
      Font f = new Font(fontName, Font.PLAIN, 1); 
      if (f.canDisplayUpTo(text)<0) { 
       System.out.println(fontName); 
       supportedFonts.add(fontName); 
      } 
     } 
     fontComboBox = new JComboBox(supportedFonts); 

의 (a 핫도그 문자) 텍스트를 표시 할 글꼴의 목록 다음에이 컴퓨터에 설치된 글꼴의 수를 보여줍니다.

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 
import java.util.Vector; 

public class FontCheck { 

    private JComponent ui = null; 

    private final String text = "\uD83C\uDF2D"; 
    private JComboBox fontComboBox; 
    private JTextField outputField = new JTextField(text, 5); 

    FontCheck() { 
     initUI(); 
    } 

    public void initUI() { 
     if (ui!=null) return; 

     ui = new JPanel(new BorderLayout(4,4)); 
     ui.setBorder(new EmptyBorder(4,4,4,4)); 

     ui.add(outputField); 
     ui.add(getToolBar(), BorderLayout.PAGE_START); 

     refreshFont(); 
    } 

    private JToolBar getToolBar() { 
     JToolBar tb = new JToolBar(); 
     tb.setLayout(new FlowLayout()); 

     String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment(). 
       getAvailableFontFamilyNames(); 
     System.out.println(fonts.length + " font families installed"); 
     Vector<String> supportedFonts = new Vector<>(); 
     for (String fontName : fonts) { 
      Font f = new Font(fontName, Font.PLAIN, 1); 
      if (f.canDisplayUpTo(text)<0) { 
       System.out.println(fontName); 
       supportedFonts.add(fontName); 
      } 
     } 
     fontComboBox = new JComboBox(supportedFonts); 
     ActionListener refreshListener = new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       refreshFont(); 
      } 
     }; 
     fontComboBox.addActionListener(refreshListener); 

     tb.add(fontComboBox); 
     return tb; 
    } 

    private void refreshFont() { 
     String fontName = fontComboBox.getSelectedItem().toString(); 
     Font f = new Font(fontName, Font.PLAIN, 60); 
     outputField.setFont(f); 
    } 

    public JComponent getUI() { 
     return ui; 
    } 

    public static void main(String[] args) { 
     Runnable r = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (Exception useDefault) { 
       } 
       FontCheck o = new FontCheck(); 

       JFrame f = new JFrame(o.getClass().getSimpleName()); 
       f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       f.setLocationByPlatform(true); 

       f.setContentPane(o.getUI()); 
       f.pack(); 
       f.setMinimumSize(f.getSize()); 

       f.setVisible(true); 
      } 
     }; 
     SwingUtilities.invokeLater(r); 
    } 
} 
+0

, 나는 NPE 얻을 시험에서 .FontCheck.initUI (FontCheck.java:37) \t at test.FontCheck. (FontCheck.java:23)' – Optional

+1

* "설치하지 않은 경우 중요합니다. * It It 당신이 코드를 이해하고 ** ** 제거되지 않은 글꼴 **을 포함하지 않을 것이며 위에서 ** 표시된대로 정확하게 NPE **를 던지지 않을 것입니다. –

+0

그리고 어떻게 새로운 지원되지 않는 글꼴을 설치하겠습니까? @ andrew-thompson도 중요합니까? 그럼에도 불구하고, 약간의 응용 OP의 문제도 해결할 수 있습니다. – Optional

3

가장 먼저.

1) \uD83C\uDF2D은 Moncaco 글꼴에서 지원되지 않습니다. LastResport, Symbola and Unifont Upper가 :

2)이 문자에 대해 작동하는 것 같다 fileformat

3) 지원되는 글꼴에서이 문자를 지원하는 글꼴을 확인할 수 있습니다이있다 나와. link

지금 Java에서 어떻게 지원합니까? font을 다운로드하고 레이블을 설정하고 아래와 같이 사용하십시오.

import java.awt.Dimension; 
import java.awt.Font; 
import java.io.File; 
import java.net.URI; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.WindowConstants; 

public class FrameMain1 { 

    public static void main(String[] args) throws Exception { 

     File fontFile = new File(new URI("file:///D:/tmp/Symbola.ttf")); 
     Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile); 
     font = font.deriveFont(Font.PLAIN, 24f); 
     JFrame frame = new JFrame(); 
     JLabel label1 = new JLabel("\uD83C\uDF2D"); 
     frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS)); 
     frame.add(label1); 
     frame.setFocusable(true); 
     //frame.setPreferredSize(new Dimension(1000, 500)); 
     frame.requestFocusInWindow(); 
     label1.setFont(font); 
     frame.add(label1); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

} 

See the image

관련 문제