GUI läuft mit 30 fps?

Beim Testen eines Echtzeit-Simulationscodes, der einen Swingworker verwendet, ist mir aufgefallen, dass meine GUI immer mit 30 fps zu laufen scheint, nicht mehr und nicht weniger. Ich aktualisiere die GUI jedes Mal, wenn der Benutzer mit der Anwendung interagiert (wie bei einer Mausbewegung) oder wenn die process () -Methode von Swingworker aufgerufen wird. Der Swingworker macht im Moment nichts, er holt sich lediglich die Mausposition von der GUI und sendet sie als Klon über die Methoden publish () und process () zurück (ich mache das nur, um zu sehen, was ich kann und kann Dies ist bei der Kommunikation zwischen Threads nicht der Fall, da Multithreading für mich noch recht neu ist. Ich habe nirgendwo Zeitgeber, die process () -Methode der Swingworker-Aufrufe repaint () auf der GUI, also habe ich mich gefragt, warum die GUI mit 30 fps aktualisiert wird. Ist in der GUI möglicherweise standardmäßig ein vsync aktiv, oder handelt es sich um ein Verhalten der process () -Methode in Swingworker? Und schließlich: Gibt es eine Möglichkeit, höhere Frameraten zu erzielen?

Hier ist eine sscce, die dieses Verhalten aufweist:

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();
            }
        }
    }
}

Ich habe eine andere Version erstellt, in der ich nur zähle, wie oft die GUI neu gestrichen wurde und wie oft sie auf dem Bildschirm angezeigt wird. Die Geschwindigkeit steigt anscheinend mit 30 pro Sekunde, daher ist die FPS-Berechnung wohl nicht das Problem.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage