Podczas testowania kodu symulacyjnego w czasie rzeczywistym, który wykorzystuje Swingworker zauważyłem, że mój GUI zawsze działa z prędkością 30 klatek na sekundę, nie więcej, nie mniej. Aktualizuję GUI za każdym razem, gdy użytkownik wchodzi w interakcję z aplikacją (jak ruch myszy) lub gdy wywoływana jest metoda process() Swingworker. Swingworker nic teraz nie robi, po prostu chwyta lokalizację myszy z GUI i wysyła ją z powrotem jako klon za pomocą metod publish() i process() (robię to po to, aby zobaczyć, co mogę i mogę kiedy komunikujesz się między wątkami, ponieważ wielowątkowość jest dla mnie całkiem nowa). Nie mam żadnych timerów w dowolnym miejscu, metoda process() wywołań Swingworker repaint() na GUI, więc zastanawiałem się, co powoduje, że GUI aktualizuje się z prędkością 30 fps? Czy w GUI jest prawdopodobnie aktywny kontrakcjonariusz, czy jest to pewne zachowanie metody process() w Swingworker? I wreszcie: czy istnieje sposób na zwiększenie liczby klatek na sekundę?GUI z 30 fps?
Oto sscce który wykazuje takie zachowanie:
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();
}
}
}
}
stworzyłem inną wersję, gdzie po prostu policzyć ile razy GUI został przemalowany i pokazać liczyć na ekranie, a wydaje się, że rośnie w stawka 30 na sekundę, więc domyślam się, że obliczenie fps nie jest problemem.
Edytuj swoje pytanie, dołączając [sscce] (http://sscce.org/), które pokazuje stawkę, którą opisujesz. – trashgod
W jaki sposób uzyskujesz liczbę klatek na sekundę? –
Przepraszam, dodałem sscce – FinalArt2005