Eine theoretische Frage zur Praxis - JPanel oder Canvas

Jeykay

Mitglied
Hallo zusammen.

Ich möchte eine App erstellen in der ich Schichten planen möchte (PEP). Hierfür habe ich nun (sehr) vereinfacht folgende Class:

Java:
public class ClassSchicht extends JPanel/Canvas {
    String Name;
    int Start;
    int Ende;

   public void paint(Graphics g){
      g.drawString(Name, xPos, yPos);
     g.drawRect(0, 0, 40, 40)
   }
}

Die Schichten zeichnen sich also praktisch selber einen "Rahmen" und einen String, mit dem Namen der Schicht auf einem JPanel welches ich wiederum in einem JFrame platziert habe. Grafiken werden zur Zeit nicht benutzt. Ich hoffe das ist bis hier verständlich.

Nun aber meine eigentliche Frage. Nutze ich für die Ausgabe der Schicht für sich selber einen JFrame oder ein Canvas? Ich habe es mit beidem probiert und es geht in meiner App mit beidem. Aber was ist besser?

Gruß
Jan
 
JFrame und JPanel sind Klassen aus Swing, Frame und Canvas wären Klassen aus AWT. Swing basiert auf AWT, verwendet aber leichtgewichtige Komponenten. AWT verwendet man selbst in der Regel schon lange nicht mehr.
 
Sowohl JPanel als auch Canvas erben von java.awt.Component insofern verwendet JPanel AWT.
Ja, darum hatte ich geschrieben, dass Swing auf AWT basiert. Meine letzte Aussage ist allerdings sehr salopp und damit nicht korrekt, denn Graphics, Fonts etc. verwendet man natürlich weiterhin. Die Aussgae sollte man auf Komponenten bezogen sehen: so gut wie niemand baut heute noch ein GUI mit AWT-Komponenten.
 
Nun aber meine eigentliche Frage. Nutze ich für die Ausgabe der Schicht für sich selber einen JFrame oder ein Canvas? Ich habe es mit beidem probiert und es geht in meiner App mit beidem. Aber was ist besser?
Zuerst einmal die beiden Varianten sollten in etwa so aussehen.
Java:
public class ClassSchicht extends Canvas {

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        // ...
    }
}
Java:
public class ClassSchicht extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // ...
    }
}
In Swing sollte man niemals paint() überschreiben. Und weder paint noch paintComponent selbst aufrufen. Dazu gibt es repaint, revalidate ..
Was besser ist ? Falls deine Anwendung mit beiden gut funktioniert, spielt das nicht wirklich eine Rolle.
JPanel hat vieles dabei was Du eventuell gar nicht benötigst. awt.Container -> JComponent .
Bei vielen Layers kann man da mit Canvas etwas sparen.
Ich selbst verwende Canvas für aktives Rendern bei kleinen 2D Games.
Aber wie gesagt ist das in Deinem Fall eventuell nicht wirklich relevant.
 
Canvas ist grundsätzlich am schnellsten, aber hier hast du eben das Problem, dass es sehr Low Level ist, du musst dir also erst mal was ausrenken, um Swing-Kontextmenüs ordentlich darauf anzeigen zu können. Bei denen muss dann erst mal Lightweight ausgeschaltet werden. Buffering ist dann auch noch so ein Thema.
In einer UI sollte - sofern es nicht um Rendering geht - Gewschwindigkeit aber eh nur eine untergeordnete Rolle spielen. In fast allen Fällen ist ein JPanel mit überschriebener drawComponent Methode die beste Lösung.
Selbst für meine ISO-Gittermodellrenderer verwende ich ein JPanel. Canvas hatte ich auch probiert, aber das hat mehr Probleme bereitet, als es nützlich war. Das Panel beinhaltet nämlich zusätzlich noch Buttons und das Canvas hatte sich mit denen nicht wirklich gut vertragen.
 

Zurück
Oben