GUI in esecuzione a 30 fps?

Durante il test di alcuni codici di simulazione in tempo reale che utilizzano uno Swingworker, ho notato che la mia interfaccia grafica sembra sempre funzionare a 30 fps, né più né meno. Aggiorno la GUI ogni volta che l’utente interagisce con l’applicazione (come una mossa del mouse) o quando viene chiamato il metodo process () di Swingworker. Il Swingworker non fa nulla al momento, semplicemente prende la posizione del mouse dalla GUI e la rimanda come un clone attraverso i metodi publish () e process () (sto solo facendo questo per vedere cosa posso e posso Lo faccio quando comunico tra thread perché il multithreading è ancora abbastanza nuovo per me). Non ho timer da nessuna parte, il metodo process () di Swingworker chiama repaint () sulla GUI, quindi mi chiedevo cosa causava l’aggiornamento della GUI a 30 fps? C’è forse come un vsync attivo nella GUI di default o è un comportamento del metodo process () in Swingworker? E infine: c’è un modo per ottenere framerate più alti?

Ecco uno sscce che presenta questo comportamento:

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

Ho creato un’altra versione in cui conto il numero di volte in cui la GUI è stata ridipinta e mostra il conteggio sullo schermo, e sembra aumentare a una velocità di 30 al secondo, quindi suppongo che il calcolo dell’FPS non sia il problema.