2017-10-05 1 views
2

Nun, ich folge diesem tutorial, um meine eigene Animation zu erstellen, und wenn ich es laufen alles funktioniert gut unter Windows, aber in Ubuntu 17.04 ist die Animation nur glatt, wenn die Maus über die App bewegt Fenster. Wenn es nicht funktioniert wie "in Ansätzen" (ich denke, es ist eine gute Übersetzung). hier ist mein Code:Machen Sie meine Java-Swing-Animation reibungsloser in Linux

import javax.swing.Box; 
import javax.swing.BoxLayout; 
import java.awt.Color; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Window extends JFrame { 

private Panel pan = new Panel(); 
private JButton play = new JButton("play"); 
private JButton pause = new JButton("pause"); 

public Window(String titre) { 

    this.setTitle(titre); 
    this.setSize(900, 600); 
    this.setLocationRelativeTo(null); 
    this.setAlwaysOnTop(true); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Box b1 = Box.createHorizontalBox(); 
    b1.add(play); 
    b1.add(pause); 

    Box b2 = Box.createVerticalBox(); 
    b2.add(b1); 
    this.setContentPane(pan); 
    this.getContentPane().add(b2); 
    this.setVisible(true); 
    this.go(); 

} 

private void go() { 
    // Les coordonnées de départ de notre rond 
    int x = pan.getPosX(), y = pan.getPosY(); 
    // Le booléen pour savoir si l'on recule ou non sur l'axe x 
    boolean backX = false; 
    // Le booléen pour savoir si l'on recule ou non sur l'axe y 
    boolean backY = false; 

    // Dans cet exemple, j'utilise une boucle while 
    // Vous verrez qu'elle fonctionne très bien 
    while (true) { 
     // Si la coordonnée x est inférieure à 1, on avance 
     if (x < 1) 
      backX = false; 

     // Si la coordonnée x est supérieure à la taille du Panneau moins la taille du 
     // rond, on recule 
     if (x > pan.getWidth() - 50) 
      backX = true; 

     // Idem pour l'axe y 
     if (y < 1) 
      backY = false; 
     if (y > pan.getHeight() - 50) 
      backY = true; 

     // Si on avance, on incrémente la coordonnée 
     // backX est un booléen, donc !backX revient à écrire 
     // if (backX == false) 
     if (!backX) 
      pan.setPosX(++x); 

     // Sinon, on décrémente 
     else 
      pan.setPosX(--x); 

     // Idem pour l'axe Y 
     if (!backY) 
      pan.setPosY(++y); 
     else 
      pan.setPosY(--y); 

     // On redessine notre Panneau 
     pan.repaint(); 

     // Comme on dit : la pause s'impose ! Ici, trois millièmes de seconde 
     try { 
      Thread.sleep(2); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

} 

seconde Klasse:

import javax.swing.JPanel; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 

public class Panel extends JPanel { 

private int posX = -50; 
private int posY = -50; 

public void paintComponent(Graphics g) { 
    g.setColor(Color.WHITE); 
    g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
    g.setColor(Color.red); 
    g.fillOval(posX, posY, 50, 50); 
} 

public int getPosX() { 
    return posX; 
} 

public void setPosX(int posX) { 
    this.posX = posX; 
} 

public int getPosY() { 
    return posY; 
} 

public void setPosY(int posY) { 
    this.posY = posY; 
} 
} 

und die Haupt:

import javax.swing.JFrame; 
public class test { 
public static void main(String [] args) { 
    Window window = new Window("Animation"); 

} 

} 

Sie einen im Voraus Viele in der Lage sein kann mir einige Ideen zu geben, :)

+0

Es ist wahrscheinlich einige Ressourcenschoner Linux hat, wenn das Fenster nicht aktiv ist, warum verschwenden Ressourcen ziehen es? – Dinh

+0

Nun, ich setze hohe Ressource mit dem Monitor-System und es tut das gleiche. Außerdem, wenn ich minecraft spiele, funktioniert es gut, auch wenn meine Maus nicht über dem Fenster ist haha ​​ –

+0

Ich würde vorsichtig sein, dass Sie "paintComponent" -Methode auf Eigenschaften beruht, die von einem anderen Thread geändert werden können - wenn Sie eine bessere Kontrolle über die Malprozess, sollten Sie eine 'BufferStrategy' statt – MadProgrammer

Antwort

2

Versuchen Sie anzurufen

Toolkit.getDefaultToolkit(). Sync();

Nachdem Sie das tun

pan.repaint();

+0

danke es klappt jetzt super !! aber warum? –

+0

@DaniSanz Das ist eine sehr weit gefasste Frage, beginnen Sie mit einem Blick auf die "[JavaDocs] (https://docs.oracle.com/javase/8/docs/api/java/awt/Toolkit.html#sync-) - * "Diese Methode stellt sicher, dass das Display auf dem neuesten Stand ist. Es ist nützlich für die Animation. "*, Ich würde auch empfehlen, einen Blick auf [Painting in Swing] (http://www.oracle.com/technetwork/java/painting-140037.html) zu werfen, um weitere Einzelheiten darüber zu erfahren, wie Der Malprozess funktioniert tatsächlich – MadProgrammer

+0

Es gibt ein Problem mit der grafischen Planung von Linux, was bedeutet, dass es aus irgendeinem Grund langsamer wird Der Aufruf benötigt wertvolle CPU-Zyklen (ziemlich viele von ihnen), also benutze System.getProperty ("os.name ") um festzustellen, ob Sie es brauchen. – Dinh

Verwandte Themen