6

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.

Community
  • 1
  • 1
  • possible duplicate of [How to set the dpi of java swing apps on Windows/Linux?](http://stackoverflow.com/questions/15659044/how-to-set-the-dpi-of-java-swing-apps-on-windows-linux) – Joe Apr 22 '15 at 09:59
  • AFAIK, it's not possible right now. Please submit a bug/RFE at http://bugreport.java.com – Hendrik Jul 30 '15 at 14:03

2 Answers2

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.

gantners
  • 471
  • 4
  • 16
  • 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.. –  Oct 06 '15 at 09:15
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();
        }
    
    
    }
Rjelinek
  • 26
  • 6