我试图通过屏幕外图像双缓冲来修复文本质量,因此被困(超出了乐趣的极限)。 Screen capture worth a thousand words.
String
被绘制到屏幕外图像,然后被复制到paintComponent
的{{1}}参数。Graphics
会直接写入String
的{{1}}参数,绕过屏幕外图像。两个paintComponent
实例(屏幕上和屏幕外)在渲染质量,抗锯齿等方面都是相同的设置......
非常感谢您的智慧。
非常简单的代码如下:
Graphics
答案 0 :(得分:0)
您没有使用相同的颜色绘制两个字符串。屏幕外图形的默认颜色是rgb(0,0,0)(即纯黑色),而Swing会将Graphics对象的颜色设置为外观的默认颜色 - 对于我而言,在Windows上7,使用默认主题,是rgb(51,51,51),或深灰色。
尝试在您的setupGraphics方法中放置g.setColor(Color.BLACK);
,以确保使用相同的颜色绘制两个字符串。
答案 1 :(得分:0)
感谢您的回复。
提到DPI后,MadProgrammer引导我找到了一个可行的解决方案,我在这里提供的解决方法更多的是干净的'清洁'解决方案值得骄傲。无论如何,它解决了这个问题。
我注意到,当我的屏幕分辨率为2880x1800(Retina显示屏)时,MouseEvent
的{{1}}方法在屏幕的右下角显示x = 1440,y = 900。然后,getPoint()
大小是屏幕分辨率的一半,尽管它覆盖了整个屏幕。
这看到,解决方案如下:
首先,创建一个与屏幕分辨率匹配的屏幕外图像,而不是几十个双缓冲文章中建议的JPanel
。
然后,使用放大变换绘制屏幕外图像,大于需要,特别是通过r =屏幕尺寸/面板尺寸比例进行缩放。
最后,将缩小版的幕外图像复制回屏幕,应用收缩因子r(或比例因子1 / r)。
解决方案实现分为两种方法:
JPanel.getSize()
的修订版paintComponent
。修改后的getDPIFactor()
方法如下:
paintComponent
要完成任务,必须获取屏幕分辨率。
拨打public final void paintComponent(Graphics g) {
super.paintComponent(g);
double dpiFactor = getDPIFactor();
// --------------------------------------
//OffScreen painting
Graphics2D osg2D = getOffscreenGraphics();
setupGraphics(osg2D);
//Paint stuff bigger than needed
osg2D.setTransform(AffineTransform.getScaleInstance(dpiFactor, dpiFactor));
//Custom painting
performPainting(osg2D);
//Shrink offscreen buffer to screen.
((Graphics2D)g).drawImage(
osi,
AffineTransform.getScaleInstance(1.0/dpiFactor, 1.0/dpiFactor),
this);
// --------------------------------------
// OnScreen painting
Graphics2D gg = (Graphics2D)g;
setupGraphics(gg);
gg.drawString("Direct painting", 10, 35);
}
并不能解决问题,因为它会返回覆盖整个屏幕的Toolkit.getDefaultToolkit().getScreenResolution()
的大小。如上所示,这个数字与物理点中的实际屏幕尺寸不匹配。
Sarge Bosch在this stackoverflow post中清除了获取此数据的方法。
我已经调整了他的代码来实现拼图的最后一部分JPanel
。
getDPIFactor()
此代码解决了Mac Retina显示的问题,但我对其他任何地方都感到害怕,因为/*
* Adapted from Sarge Bosch post in StackOverflow.
* https://stackoverflow.com/questions/40399643/how-to-find-real-display-density-dpi-from-java-code
*/
private Double getDPIFactor() {
GraphicsDevice defaultScreenDevice =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
// on OS X, it would be CGraphicsDevice
if (defaultScreenDevice instanceof CGraphicsDevice) {
CGraphicsDevice device = (CGraphicsDevice) defaultScreenDevice;
// this is the missing correction factor.
// It's equal to 2 on HiDPI a.k.a. Retina displays
int scaleFactor = device.getScaleFactor();
// now we can compute the real DPI of the screen
return scaleFactor * (device.getXResolution() + device.getYResolution()) / 2
/ Toolkit.getDefaultToolkit().getScreenResolution();
} else
return 1.0;
}
明确提到CGraphicsDevice
的专有实现。
我没有其他HDPI硬件可供使用,有机会提供更广泛的解决方案。