Graphics Objekte scalen mit Veränderung des Bildschirms

Das hier ist eine Funktion der Klasse Char, die ich nutze:
Java:
public void draw(Graphics2D g2d, int x, int y, int yOffset) {
        indentSize = g2d.getFontMetrics().charWidth(' ')*5*indent;
        this.x = x + indentSize;
        this.y = y;
        g2d.setFont(font);
        this.height = g2d.getFontMetrics().getHeight();
        g2d.setColor(color);
        g2d.drawString("" + c, this.x, y + yOffset);
        offset = g2d.getFontMetrics().charWidth(c);
      
    }
 
Sonst könnte ich mir nichts vorstellen, dass die Verzerrung verursacht. Ich dachte, dass Graphics2Ds drawString mit dem Scalen des Bildschirms mitscaled. Wenn ich den Bildschirm sehr dünn mache, wird die Schrift auch zusammengedrückt (mit setResizable(true)).
 
Mal eine Frage wiso gibst du deiner Methode nur den offset in y Richtung mit und nicht auch X Richtung.
Die wird sich beim zoomen wohl auch verändert haben.
 
Kannst Du etwas genauer beschreiben, was Du genau machst? Du hast eine Swing Anwendung mit einem JFrame.
Dann hast Du irgend eine Loop Methode, die etwas malt? Auf was malst Du wann / wie?

Der generelle Ablauf sollte eigentlich so sein:
  • Das JFrame malt sich, wenn es von außen aufgefordert wird. (Event Loop bekommt ein WM_PAINT). Dazu wird dann die ganze paint / paintComponent Chain aufgerufen für alle Childs und so.
  • Das Graphics Objekt einer solchen Methode sollte nicht irgendwo außerhalb der Methode bzw, direkt aufgerufener Methoden verwendet werden. Also nicht irgendwo speichern um dann außerhalb des UI-Threads darauf zugreifen.

Natürlich kann es sein, dass man direkt etwas malen möchte. Gameloop eines Spieles ist da ein gutes Beispiel. Da wird dann aber in der Regel der Inhalt erstellt und dann dem UI Thread zur Verfügung gestellt (Mit ggf. Aufruf repaint() was dann ein WM_PAINT Event in die Eventloop packt).

Evtl. kommt es zu Verzerrungen, weil Du mit Instanzen arbeitest, die dafür nicht mehr wirklich gedacht sind?
 
Java:
public void draw(Graphics2D g2d) {
        if(dbi == null) {
            dbi = createImage(getWidth(), getHeight());
            dbg = dbi.getGraphics();
        }
        Graphics2D dbg2d = (Graphics2D) dbg;
        dbg2d.setRenderingHints(renderhints);
        renderOffScreen(dbg2d);
        
        g2d.drawImage(dbi, 0, 0, getWidth(), getHeight(), null);
        
    }


Durch
Code:
draw((Graphics2D) this.getGraphics());
In public void update(double dt) {}
Mit this. als extends JFrame
 
Verstehe ich das richtig, du willst direkt auf ein JFrame malen? Das ist nicht der richtige Weg. Du solltest dem JFrame eine JComponent z.B. JPanel hinzufügen und dieses zum zeichnen verwenden.
 
Also paar Unterschiede kann man direkt feststellen: Wenn Du etwas gemalt hast und dann das Fenster neu gemalt werden muss (z.B bei einem maximieren), dann ist das Gemalte weg.

Also ein minimaler Test (Code aus main Methode):
Java:
        JFrame frame = new JFrame();
        frame.setSize(600, 400);
        frame.setVisible(true);
        Graphics2D graphics2D = (Graphics2D) frame.getGraphics();
        SwingUtilities.invokeLater(() -> graphics2D.drawLine(0, 0, 600, 400));

Wenn Du das Fenster angezeigt bekommen hast und es dann maximierst, dann ist der Strich weg.

Es macht halt Sinn, Verantwortlichkeiten zu trennen. Dann hast Du die Daten in irgendwelchen Model Klassen. Und die Daten zeigst Du dann an. Und bei den Swing Klassen ist es üblich paint bzw. paintComponent zu nutzen um die Darstellung zu machen.

Kaum packst Du das Malen der Linie in die entsprechende Methode (und das Graphics Objekt musst Du Dir nicht holen - das bekommst Du direkt als Parameter!) dann wird es immer wieder erneut aufgerufen, wenn notwendig. Also auch z.B. nach dem Maximieren des Fensters.
 

Zurück
Oben