Beim Testen eines Echtzeit-Simulationscodes, der einen Swingworker verwendet, bemerkte ich, dass meine GUI immer mit 30 fps läuft, nicht mehr und nicht weniger. Ich aktualisiere die GUI jedes Mal, wenn der Benutzer mit der Anwendung interagiert (wie eine Mausbewegung) oder wenn die Methode process() des Swingworker aufgerufen wird. Der Swingworker macht gerade nichts, er greift nur die Mausposition von der GUI und sendet sie als Klon durch die Methoden publish() und process() zurück (ich mache das nur, um zu sehen, was ich kann und kann) t tun, wenn zwischen Threads kommunizieren, weil Multithreading noch ziemlich neu für mich ist). Ich habe keine Timer, die process() - Methode des Swingworker ruft repaint() auf der GUI auf, also frage ich mich, was die GUI dazu bringt, mit 30 fps zu aktualisieren? Gibt es vielleicht einen vsync, der standardmäßig in der GUI aktiv ist oder ist es ein Verhalten der process() Methode im Swingworker? Und schließlich: Gibt es eine Möglichkeit, höhere Frameraten zu erzielen?GUI läuft mit 30 fps?
Hier ist ein sscce, die dieses Verhalten zeigt:
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 eine andere Version erstellt, wo ich die Anzahl der Male, zählen nur die GUI neu gestrichen wurde und die Zählung auf dem Bildschirm zeigen, und es scheint ein zu steigen Rate von 30 pro Sekunde, also denke ich, die FPS-Berechnung ist nicht das Problem.
Bearbeiten Sie Ihre Frage so, dass sie eine [sscce] (http://sscce.org/) enthält, die die von Ihnen beschriebene Rate aufweist. – trashgod
Wie erhalten Sie die Bildrate? –
Sorry, hinzugefügt eine sscce – FinalArt2005