Reputation:
Any idea how to make the Java Swing file chooser look better on 2K displays where the windows font scaling is > 125%?
I am using ordinary code such as:
JFileChooser fc = new JFileChooser();
if (settings.currentdir != null)
fc.setCurrentDirectory(new File(settings.currentdir));
int returnVal = fc.showOpenDialog((Window) holder);
if (returnVal == JFileChooser.APPROVE_OPTION) {
But the file chooser is only displaying tiny icons for the listed files and directories. I am using JDK 8. What is going wrong?
P.S.: Scope of the question is only Windows, not Unixes. On Windows, the two default L&F, they scale the font. But they don't scale icons. The application has to do that, since it might use a different bitmap resources for higher scales. It seems that JFileChooser is not coded this way.
But it might be that the JFileChooser can be instructed to do so. I don't see that the other question addresses icon size and the JFileChooser on Windows: How to set the DPI of Java Swing apps on Windows/Linux? The other question deals with font size, which is not an issue for the JFileChooser on Windows with one of the two Windows L&F.
Upvotes: 9
Views: 518
Reputation: 11878
Java 8 does not support High DPI, its UI is scaled up by Windows to the correct size. Yet it means the UI is blurry.
Java 11 and later support High DPI, the icons in JFileChooser
will be scaled up by Java if the icon is not a MultiResolutionImage
that provides different icons for different display scales in High DPI environment. In Java 17, most icons used by the file chooser are multi-resolution icons.
Upvotes: 0
Reputation: 26
I very recently ran into same problem. the only work around is not using java build in ImageIcon class but to write one yourself, This one took the provided image, scale it to fit current component size and paint it. I tried to make is as simple as possible and as close to original class as able, but its not perfect and need improvement, especially in component-icon alignment
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
/**
*
* @author Rastislav
*/
public class ScaleToFitAndAntialiasIcon extends ImageIcon{
private ImageIcon icon;
public ScaleToFitAndAntialiasIcon(ImageIcon icon)
{
this.icon = icon;
}
public int getIconWidth()
{
return icon.getIconWidth();
}
public int getIconHeight()
{
return icon.getIconHeight();
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y)
{
Graphics2D g2d = (Graphics2D)g.create();
AffineTransform at = g2d.getTransform();
double scaleToFit = ((double)c.getHeight() / (double)icon.getIconHeight());
if((int)icon.getIconHeight()*scaleToFit == c.getHeight()){
scaleToFit = ((double)c.getHeight() / (double)icon.getIconHeight()) - 0.1;
}
AffineTransform scaled = AffineTransform.getScaleInstance(scaleToFit, scaleToFit);
at.concatenate( scaled );
g2d.setTransform( at );
//need improvement
/* int lineupMinus = (int)((double)icon.getIconWidth() *((double)c.getHeight() / (double)icon.getIconHeight()));
int lineup = (int)((double)icon.getIconWidth() * scaleToFit);
int ff = (int)(lineupMinus - lineup);
System.out.println(ff);
*/
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
//improved code goes here
icon.paintIcon(c, g2d, x, 4);
if(c instanceof AbstractButton a){
a.setIconTextGap((int)(-icon.getIconWidth()/2));
}
g2d.dispose();
}
}
Upvotes: 0
Reputation: 471
Just a quick idea while i came across this thread. You can try to deliver your own iconset:
new JFileChooser().setFileView(new FileView() {
@Override
public Icon getIcon(File f) {
return fancy2kIconForExtension(StringUtils.substringAfterLast("."));
}
});
be careful to load your Icons from a Cache, as this method is called very often from inside JFileChooser
, otherwise you end up reloading icon all the time.
Upvotes: 0