2017-07-16 82 views
1

因此,我试图通过从JTextArea继承并覆盖paintComponent()来使用行号进行小型文本预览。如何获得文本组件(基础系统/操作系统设置)中使用的抗锯齿模式

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 

import javax.swing.JFrame; 
import javax.swing.JTextArea; 

public class PreviewPane extends JTextArea { 

    public PreviewPane() { 
     setText("first row\nsecond row\nthird row"); 
    } 

    @Override 
    protected void paintComponent(Graphics graphics) { 
     Graphics2D g = (Graphics2D) graphics; 
     int emWidth = g.getFontMetrics().stringWidth("m"); 
     int lineHeight = g.getFontMetrics().getHeight(); 
     int baseLine = g.getFontMetrics().getAscent(); 

     g.translate(2 * emWidth, 0); 
     super.paintComponent(g); 

     g.translate(-2 * emWidth, 0); 

     g.setColor(getBackground()); 
     g.fillRect(0, 0, 2 * emWidth - 1, getHeight() - 1); 

     g.setColor(Color.LIGHT_GRAY); 
     g.drawLine(2 * emWidth - 1, 0, 2 * emWidth - 1, getHeight() - 1); 

     g.setColor(Color.BLACK); 

     // "guessed" value for antialiasing 
     g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 
     for (int i = 1; i <= 3; i++) { 
      g.drawString(String.valueOf(i), getMargin().left, getMargin().top + baseLine + (i - 1) * lineHeight); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setBounds(0, 0, 640, 480); 
     frame.getContentPane().add(new PreviewPane(), BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

在标记的行中,我将抗混叠提示设置为RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB。这将导致确切的字体渲染的文本区域:
Rendering with <code>RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB</code>

省略此行只是使用默认:
Rendering with default

但这不会在每个系统上运行。查询FontRenderContext或从图形对象中最初分配的渲染提示仅返回Default antialiasing text mode,这不能是用于渲染文本区域的模式。

所以我的问题是:如何从文本组件/ java系统中获得实际使用的抗锯齿模式?

注:我没有试图实现一个完全成熟的行编号编辑器,所以这种解决方案的“低效率”是无关紧要的。另外,在过去的几年中,我直接在组件的绘画方法中呈现文本时遇到过这个问题,所以这只是一个例子。

+0

'getRenderingHints()'揭示了什么适用? – trashgod

+0

不,如问题中所述,它返回“文本特定的抗锯齿启用键=默认的抗锯齿文本模式”。 – dosenfant

+0

当我设置了抗锯齿提示时,我得到一个条目“文本特定的抗锯齿启用键= LCD HRGB抗锯齿文本模式”。 – trashgod

回答

0

挖掘Java lib源代码揭示了文本区域(以及其他文本组件)的字体渲染使用内部类sun.swing.SwingUtilities2。这将内部保存所需的信息并从java.awt.Toolkit查询它。

因此,代码以获得来自系统的文本抗锯齿信息:

Toolkit tk = Toolkit.getDefaultToolkit(); 
Map map = (Map) tk.getDesktopProperty(sun.awt.SunToolkit.DESKTOPFONTHINTS); 
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, map.get(RenderingHints.KEY_TEXT_ANTIALIASING)); 

地图的内容是(对我来说)

{Text-specific antialiasing enable key=LCD HRGB antialiasing text mode, Text-specific LCD contrast key=120} 

这是所需的确切信息。

请注意,sun.awt.SunToolkit.DESKTOPFONTHINTS是禁止的API,因此应替换为"awt.font.desktophints"