Swing Animationen - Drehung aller Komponenten auf Knopfdruck

Weiti

Mitglied
Hallo, ich würde gerne wissen wie ich es am klügsten anstelle das ich meine gezeichneten Sachen um 90° Drehe.

Mein Programm ist so aufgebaut:
Ein Frame läuft.
Wenn ein Button im Frame angeklickt wird wird eine Liste von Shapes an eine Klasse übergeben die von JComponent erbt und in der paintComponent überschrieben wird. Dort wird alles gezeichnet.

Nun soll ein weiterer Button das GESAMTE Bild um 90° Drehen, aber nicht jede Komponente einzeln, sondern alle als ein gemeinsames Bild.

Da ich die Komponenten nach dem Drehen wieder neu berechne und erzeuge brachen sie bei der Drehung eigentlich nicht mehr einzeln existieren.
Daher ist meine Idee ein Bild (Quasi ein Java interner Screenshot) zu machen und dieses zu drehen, aber als Animation, nicht auf einen Rutsch.

Meine Frage ist nun wie ich das mache? ich hab ein paar Sachen gelesen darüber das Animationen SwingTimer brauchen, aber ich weiß nicht wie ich das bei mir einbinden soll, insbesondere soll die Animation nur bedingt laufen und nicht immer wenn ich neu zeichne Außerdem muss ich ja aus den Shapes ein Bild machen, wie das geht weiß ich auch nicht.
Nutzt mir die Methode rotate() von Graphics2D etwas?

Könnt ihr mir da helfen?
 

Runtime

Top Contributor
Paint Methode des JFrames überschreiben, Graphics-Object zu Graphics2D-Object casten, und rotate(wert) aufrufen. Dann super.paint(g);
 

Weiti

Mitglied
hallo, das funktioniert nicht,

Java:
@Override
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D)g;
        g2d.rotate(90);
        super.paint(g);
    }

führt zu einem leeren jFrame.

Außerdem würde das die buttons doch mitdrehen? Ich will eigentlich nur den Teil drehen den das JComponent zeichnet.
 

Runtime

Top Contributor
Aha. Ok, beim paintComponent der JComponent-Abgeleiteten Klasse g2d.rotate(winkel, getWidth() / 2, getHeight() / 2) aufrufen, bevor du zeichnest.
 

Weiti

Mitglied
Edit: klappt leider nicht ganz, das drehen ist super, aber noch ohne Animation:

Java:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        for(int i=0;i<=90;i++)
        {
            paintingComponent.turn = true;
            paintingComponent.winkel=i;
            paintingComponent.repaint();
            try {
            Thread.sleep(50);
            } catch (InterruptedException e) {}

        }
    }

Java:
package viergewinnt3;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.LinkedList;
import javax.swing.JComponent;

class PaintingComponent extends JComponent
{
   LinkedList<ColoredShape> shapes;
   boolean turn=false;
   int winkel=0;

    @Override
    protected void paintComponent(Graphics g) {
        //dient dazu den Hintergrund zu säubern wie wir es vorher bereits mit
        //clearRect getan haben.
        super.paintComponent(g);
        //AWT/Swing bestimmt wann paintComponent aufgerufen wird, wir müssen
        //nun also überprüfen ob shape und color noch gar nicht gesetzt wurden
        if(shapes!=null)
        {
            Graphics2D g2d = (Graphics2D)g;

            if(turn)
            {
                g2d.rotate(winkel, 300, 300);
                System.out.println("winkel: "+winkel);
            }

            for(ColoredShape cs : shapes)
            {

                g2d.setColor(cs.color);
                g2d.fill(cs.shape);
                g2d.draw(cs.shape);

                if(cs.shape.getClass()==Line2D.Float.class)
                {
                   double y = 25 + cs.shape.getBounds2D().getMaxY();
                   double x = 25 + cs.shape.getBounds2D().getMaxX();

                   g2d.drawString(cs.text, (float)x, (float)y);
                }
               
            }

            if(turn)
            {
                g2d.rotate(winkel, getWidth() / 2, getHeight() / 2);
                System.out.println("winkel: "+winkel);
            }
        }

    }

    //

   
}
 
Zuletzt bearbeitet:

Weiti

Mitglied
Java:
if(cs.shape instanceof Line2D.Float)
{
//
}

Ok, gemacht, wie mache ich nun eine Animation?
 

Weiti

Mitglied
Oh, hatte noch zwei Drehungen drinnen, nun ist es richtig.

Java:
package viergewinnt3;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.LinkedList;
import javax.swing.JComponent;

class PaintingComponent extends JComponent
{
   LinkedList<ColoredShape> shapes;
   boolean turn=false;
   int winkel=0;

    @Override
    protected void paintComponent(Graphics g) {
        //dient dazu den Hintergrund zu säubern wie wir es vorher bereits mit
        //clearRect getan haben.
        super.paintComponent(g);
        //AWT/Swing bestimmt wann paintComponent aufgerufen wird, wir müssen
        //nun also überprüfen ob shape und color noch gar nicht gesetzt wurden
        if(shapes!=null)
        {
            Graphics2D g2d = (Graphics2D)g;

            if(turn)
            {
                g2d.rotate(winkel, 300, 300);
                System.out.println("winkel: "+winkel);
            }

            for(ColoredShape cs : shapes)
            {

                g2d.setColor(cs.color);
                g2d.fill(cs.shape);
                g2d.draw(cs.shape);

                if(cs.shape instanceof Line2D.Float)
                {
                   double y = 25 + cs.shape.getBounds2D().getMaxY();
                   double x = 25 + cs.shape.getBounds2D().getMaxX();

                   g2d.drawString(cs.text, (float)x, (float)y);
                }
               
            }

            
        }

    }

}
 

Runtime

Top Contributor
Java:
Timer t = new Timer(10, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                winkel += 0.05;
            }
        });
        t.start();

der Winkel sollte ein double sein.
 
Zuletzt bearbeitet:

Weiti

Mitglied
Super, danke, das anhalten klappt auch, nur läuft während der Drehung das Programm weiter und ruft eine erneutes repaint() auf. Kann man etwas tun damit das Programm erst später weiter läuft?
Klappt:

Java:
     private Timer t = new Timer(30, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer();
            }
            });

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            paintingComponent.turn = true;            
            t.start();                                         
        
    }                                        

    public void timer()
    {
        paintingComponent.winkel += 0.03;
        paintingComponent.repaint();
         if(paintingComponent.winkel>(Math.PI/2))
            {
                t.stop();
                paintingComponent.turn = false;
                paintingComponent.winkel=0;
                paintingComponent.repaint();
            }
    }

klappt nicht:

Java:
   private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         

       t.start();
           try{
               Thread.sleep(1000);
           }
           catch(Exception e)
           {
               
           }

       board.turnBoardCW();
       jButton2.setVisible(false);
       jButton4.setVisible(false);
       jButton7.setVisible(false);
       jButton1.setVisible(true);
       jTextField1.setVisible(true);
       paint();
       jTextArea1.setText(board.toString());
       
    }
 

Illuvatar

Top Contributor
In diesem Fall hier sieht es aus als wäre es egal, aber falls mal jemand anders auf den Thread stößt eine Bemerkung:
Wenn man einen Swing-Container dreht und mit den gedrehten Komponenten noch vernünftig interagieren willst, sollte man lieber JXTransformer verwenden, als da selbst rumzufrickeln.
 

Weiti

Mitglied
Dann tu alles, was nach derr Drehung ausgeführt werden soll in eine Methode und führe die aus wenn der Winkel > Math.PI/2 ist.

Klar, da hätte ich auch drauf kommen können.

und mit den gedrehten Komponenten noch vernünftig interagieren willst

Guter Hinweis, ich will es nicht, da ich mein Spielbrett (int[][]) eh neu berechnen muss und daraus dann die Shapes neu erzeuge, aber für andere Zwecke wird es bestimmt die bessere Lösung sein.

Danke für die Hilfe.
Gruß, Weiti
 

Ähnliche Java Themen

Neue Themen


Oben