如何获得文本组件中使用的抗锯齿模式(基础 system/OS 设置)
How to get antialiasing mode as used in text components (underlying system/OS setting)
所以我试图通过继承 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
。这将导致与文本区域完全相同的字体呈现:
省略此行仅使用默认值:
但这并不适用于所有系统。从图形对象中查询 FontRenderContext
或最初分配的渲染提示只是 return Default antialiasing text mode
,这不能是用于渲染文本区域的模式。
所以我的问题是:如何从文本component/java系统中获取实际使用的抗锯齿模式?
注意:我并不是要实现一个完全成熟的行编号编辑器,所以这个解决方案的 "inefficiency" 是无关紧要的。另外,在过去的几年里,我在组件的 paint 方法中直接渲染文本时遇到过几次这个问题,所以这只是一个例子。
深入研究 Java lib 源代码可以发现文本区域(可能还有其他文本组件)的字体渲染使用内部 class 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"
。
所以我试图通过继承 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
。这将导致与文本区域完全相同的字体呈现:
省略此行仅使用默认值:
但这并不适用于所有系统。从图形对象中查询 FontRenderContext
或最初分配的渲染提示只是 return Default antialiasing text mode
,这不能是用于渲染文本区域的模式。
所以我的问题是:如何从文本component/java系统中获取实际使用的抗锯齿模式?
注意:我并不是要实现一个完全成熟的行编号编辑器,所以这个解决方案的 "inefficiency" 是无关紧要的。另外,在过去的几年里,我在组件的 paint 方法中直接渲染文本时遇到过几次这个问题,所以这只是一个例子。
深入研究 Java lib 源代码可以发现文本区域(可能还有其他文本组件)的字体渲染使用内部 class 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"
。