I am trying to wrap my head around a concept to determine my best course of action. A little over a year ago I asked this question referring to picture quality. Since then I have moved on to other parts of the project, but now I find myself back at the same question, but with more knowledge!
I realized that since my windows scaling was at 125%, it is affecting the quality of my images.
My goal is to understand the process of how java swing responds to system scaling. Upon my research, I found this flag to pass to the jvm which runs my program at 100% regardless of the system scaling: -Dsun.java2d.uiScale=1.0
When using this flag, my image quality is great, in my opinion. My tiny 16x16 icons on my button are not pixelated as much as compared to letting the program scale with the system, see examples:
With scaling at 125%:
At normal 100%:
This is alright, but I have decided that I would like for the program to scale. It would help users with weak eyesight. This solution should be a last resort fix for me.
So my back to my ultimate question: How to allow the program to scale but prevent images from scaling?
I read from here on one of the comments that they thought "the scaling factor is defined in the AffineTransform of the Graphics object" And with that bit of information I have since been able to control my image quality! But I am having a few issues here (I do not fully understand the AffineTransform class, amongst other things so this is where my short comings would be)
- When I first load my app, none of my icons appear on my buttons until I hover over them. They will then stay visible until the frame is maximized or resized. I wonder if this a Graphics2D issue?
- The placement is not exactly centered like it was while using
new ImageIcon(...)
instead ofnew MyIcon(...)
. I tried addingat.setToTranslation(1.25, 1.25);
to see if that would help the placement but it didn't seem to do much. Any way to get it centered like it was in the image at 100%?
Here is my result using the MyIcon
class while still at 125% scaling:
To me the image looks great, way better than then default scaled image at 125%, and this is the result I am after aside from the two issues mentioned above.
Here is my minimal code to represent my issues, I think to see my locational issue one would need to use a 16x16 png.
import java.awt.GridBagLayout;
import common.Functions;
import java.awt.GridBagConstraints;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.geom.AffineTransform;
import java.net.URL;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
@SuppressWarnings("serial")
public class TestFrame extends JFrame {
public static void main(String[] args) {
TestFrame tf = new TestFrame();
tf.setLocationRelativeTo(null);
tf.setVisible(true);
}
public TestFrame() {
setSize(300, 150);
Icon i = new MyIcon(Functions.class.getResource("/link.png"));
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0};
gridBagLayout.rowHeights = new int[]{0, 0};
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE};
getContentPane().setLayout(gridBagLayout);
JButton btnNewButton = new JButton("Test Button");
btnNewButton.setPreferredSize(new Dimension(150, 30));
btnNewButton.setIcon(i);
btnNewButton.setFocusPainted(false);
GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
gbc_btnNewButton.gridx = 0;
gbc_btnNewButton.gridy = 0;
getContentPane().add(btnNewButton, gbc_btnNewButton);
}
public class MyIcon extends ImageIcon{
public MyIcon(String filename) {
super(filename);
}
public MyIcon(URL resource) {
super(resource);
}
@Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform at = new AffineTransform();
at.setToTranslation(1.25, 1.25);
g2d.setTransform(at);
if(getImageObserver() == null) {
g2d.drawImage(getImage(), x, y, c);
} else {
g2d.drawImage(getImage(), x, y, getImageObserver());
}
g2d.dispose();
}
}
}
Any insight would be beyond appreciated.