javaswinggraphicsdrawstring

How can I make drawString faster in Windows 10?


My ancient application leans heavily on drawString. It's at least 20 times slower in Windows 10. Are there ways to speed up drawing text in Windows? The following code illustrates the difference.

import javax.swing.*;
import java.awt.*;

public class hello{

// hello takes roughly 1 second in Ubuntu 20.04 SDK 11.
// hello takes roughly 2 seconds in Windows 7 Java SDK 1.7.
// hello takes roughly 40 seconds in Windows 10 Java SDK 16.

 public static void main(String[] args) {
        JPanel panel= new JPanel();
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setSize(100,100);
        frame.setVisible(true);
        Graphics g=panel.getGraphics();
        g.setFont(new Font("Arial", Font.PLAIN,12));

        long start_time=System.currentTimeMillis();
        for (int times=0;times<150000;times++)
            g.drawString("hello",50,50);

       System.out.println("total drawString time was "+(System.currentTimeMillis()-start_time));
       System.exit(0);
    }
}

Solution

  • Only takes about 100ms when painting is done properly:

    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class SSCCE extends JPanel
    {
        public SSCCE()
        {
        }
    
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
    
            g.setFont(new Font("Arial", Font.PLAIN,12));
    
            long start_time=System.currentTimeMillis();
            for (int times=0;times<150000;times++)
                g.drawString("hello",50,50);
    
           System.out.println("total drawString time was "+(System.currentTimeMillis()-start_time));
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SSCCE());
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    //      frame.pack();
            frame.setSize(300, 100);
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args) throws Exception
        {
            java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
        }
    }
    

    I'm using JDK11 on Windows 10.