¿GUI corriendo a 30 fps?

Al probar un código de simulación en tiempo real que utiliza un Swingworker, noté que mi GUI siempre parece funcionar a 30 fps, ni más ni menos. Actualizo la GUI cada vez que el usuario interactúa con la aplicación (como un movimiento del mouse) o cuando se llama al método process () del Swingworker. Swingworker no hace nada en este momento, solo toma la ubicación del mouse de la GUI y la envía como clon a través de los métodos publish () y process () (solo hago esto para ver lo que puedo y puedo hacer). No lo hagas cuando te comunicas entre hilos porque el subprocesamiento múltiple todavía es bastante nuevo para mí). No tengo temporizadores en ninguna parte, el método process () del Swingworker llama a repaint () en la GUI, así que me preguntaba qué hace que la GUI se actualice a 30 fps. ¿Hay tal vez como un vsync activo en la GUI por defecto o es algún comportamiento del método process () en el Swingworker? Y finalmente: ¿hay una manera de obtener cuadros de cuadros más altos?

Aquí hay un scsc que exhibe este comportamiento:

public class SimGameTest implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimGameTest());
    }

    @Override
    public void run() {
        MainWindow mainWindow = new MainWindow(new Game());

        mainWindow.setLocationRelativeTo(null);
        mainWindow.setVisible(true);
    }
}

public class MainWindow extends JFrame {
    private Game        game;
    private GamePanel   gamePanel;

    public MainWindow(Game game) {
        this.game = game;

        createAndShowGUI();

        startGame();
    }

    private void startGame() {
        GameSim gameSim = new GameSim(game, gamePanel);
        gameSim.execute();
    }

    private void createAndShowGUI() {
        setTitle("Sim game test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        JPanel contentPane = new JPanel(new GridBagLayout());

        gamePanel = new GamePanel(game);
        contentPane.add(gamePanel);

        add(contentPane);
        pack();
    }
}

public class Game {
    public Point            mouseLocation       = new Point();
    public Point            clonedMouseLocation = new Point();
}

public class GameSim extends SwingWorker<Point, Point> {
    private Game                game;
    private GamePanel           gamePanel;

    public GameSim(Game game, GamePanel gamePanel) {
        this.game = game;
        this.gamePanel = gamePanel;
    }

    @Override
    protected Point doInBackground() throws Exception {
        while (true) {
            publish((Point) game.mouseLocation.clone());
        }
    }

    @Override
    protected void process(List<Point> pointList) {
        game.clonedMouseLocation = pointList.get(pointList.size() - 1);
        gamePanel.repaint();
    }
}

public class GamePanel extends JPanel {
    private Game                game;
    private long                lastTime;

    public GamePanel(Game game) {
        this.game = game;
        setPreferredSize(new Dimension(512, 512));
    addMouseMotionListener(new GamePanelListener(););
    }

    @Override
    public void paintComponent(Graphics g) {
        // draw background
        g.setColor(new Color(0, 0, 32));
        g.fillRect(0, 0, getWidth(), getHeight());

        g.setColor(new Color(192, 192, 255));
        g.drawString(game.clonedMouseLocation.x + ", " + game.clonedMouseLocation.y, 10, 502);

        long now = System.nanoTime();
        long timePassed = now - lastTime;
        lastTime = now;
        double fps = ((double) 1000000000 / timePassed);
        g.drawString("fps: " + fps, 10, 482);
    }

    private class GamePanelListener extends MouseInputAdapter {
        @Override
        public void mouseMoved(MouseEvent e) {
            if (contains(e.getPoint())) {
                game.mouseLocation = e.getPoint();
            }
        }
    }
}

Creé otra versión en la que solo cuento la cantidad de veces que se repintó la interfaz gráfica de usuario y se muestra el conteo en pantalla, y parece que aumenta a una velocidad de 30 por segundo, así que supongo que el cálculo de fps no es el problema.

Respuestas a la pregunta(1)

Su respuesta a la pregunta