JFileChooser icons on 2K Displays
Asked Answered
E

3

9

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.

Elisabetta answered 22/4, 2015 at 9:45 Comment(2)
possible duplicate of How to set the dpi of java swing apps on Windows/Linux?Orabelle
AFAIK, it's not possible right now. Please submit a bug/RFE at bugreport.java.comGosport
I
0

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.

Invertebrate answered 5/10, 2015 at 21:23 Comment(1)
Ok, might give it a try soon. BTW: I noticed that a lot of apps have scaling issues, for example the Android SDK download manager looks awful on a 2K display and is nearly not usable. Strange that this is not addressed by Oracle, Google, etc..Elisabetta
H
0

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();
        }
    
    
    }
Holst answered 21/9, 2022 at 22:3 Comment(0)
M
0

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.

Medea answered 8/9, 2023 at 14:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.