Al probar algún 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. El Swingworker no hace nada ahora, simplemente toma la ubicación del mouse desde la GUI y la envía de vuelta como un clon a través de los métodos publish() y process() (solo hago esto para ver lo que puedo y puedo No se puede hacer cuando se comunica entre subprocesos porque la multithreading todavía es bastante nueva para mí). No tengo temporizadores en ninguna parte, el método process() del Swingworker llama a repintado() en la GUI, así que me preguntaba ¿por qué la GUI se actualiza a 30 fps? ¿Hay quizás como un vsync activo en la GUI por defecto o es algún comportamiento del método process() en Swingworker? Y finalmente: ¿hay alguna manera de obtener mayores tasas de fotogramas?GUI funcionando a 30 fps?
He aquí un sscce que muestra 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 donde acabo de contar el número de veces que se repintó la interfaz gráfica de usuario y mostrar el recuento en la pantalla, y que parece ir en aumento a una tasa de 30 por segundo, así que supongo que el cálculo de fps no es el problema.
Por favor, edite su pregunta para incluir una [sscce] (http://sscce.org/) que muestre la tasa que describe. – trashgod
¿Cómo está obteniendo la velocidad de cuadros? –
lo siento, agregué un sscce – FinalArt2005