Heim > Java > javaLernprogramm > Hauptteil

Wie kann ich Java-Code für das Zeichnen sich ständig ändernder Grafiken basierend auf der Mausposition optimieren, um die Leistung zu verbessern?

Barbara Streisand
Freigeben: 2024-11-23 09:14:21
Original
762 Leute haben es durchsucht

How can I optimize Java code for drawing continuously changing graphics based on mouse position to improve performance?

Java: Zeichnen sich ständig ändernder Grafiken

In diesem Programm versuchen Sie, ein sich ständig änderndes Bild basierend auf der Mausposition des Benutzers zu zeichnen. Sie sind auf Leistungsprobleme gestoßen und suchen Rat zur Optimierung. Lassen Sie uns in Ihren Code eintauchen und die Herausforderungen angehen:

Der Originalcode

Die anfängliche Implementierung weist aufgrund mehrerer Faktoren Leistungseinbußen auf:

  1. Ineffizient Pixelabruf: Sie verwenden robot.getPixelColor(...), um einzelne Pixel abzurufen, was deutlich langsamer ist als der Abruf mehrerer Pixel auf einmal.
  2. Redundantes Neuzeichnen:Der Code zeichnet das gesamte Bild neu, auch wenn sich nur ein kleiner Teil geändert hat, was zu unnötigen Neuzeichnungsvorgängen führt.
  3. Falsches Threading : Aktualisierungen des Modells und der Ansicht werden nicht mit dem Event Dispatch Thread (EDT) synchronisiert, was zu grafischen Problemen führen kann Inkonsistenzen.

Leistungsverbesserungen

Um diese Probleme zu lindern, ziehen Sie die folgenden Optimierungen in Betracht:

  1. Verwenden Sie createScreenCapture für einen schnelleren Pixelabruf: Anstatt einzelne Pixel abzurufen, verwenden Sie robot.createScreenCapture(...), um alle abzurufen 64 Pixel auf einmal, was die Leistung steigert.
  2. Implementieren Sie Smart Clipping für effizientes Neuzeichnen: Bestimmen Sie den genauen Bereich des Bildes, der neu gezeichnet werden muss, und zeichnen Sie nur diesen Teil neu, um unnötige Neuzeichnungsvorgänge zu minimieren.
  3. Stellen Sie die EDT-Synchronisierung sicher: Aktualisieren Sie das Modell und die Ansicht im Ereignis Dispatch Thread (EDT) mit SwingUtilities.invokeLater(...), um Thread-Sicherheit zu gewährleisten und grafische Artefakte zu verhindern.

Optimierter Code

Hier ist ein Beispiel für eine optimierte Version des Codes das geht auf die Leistungsbedenken ein:

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

public class ZoomPanel extends JPanel {

    private static final int STEP = 40;
    private int iter = 0;
    private long cumulativeTimeTaken = 0;

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Image zoom");

        final ZoomPanel zoomPanel = new ZoomPanel();
        frame.getContentPane().add(zoomPanel);
        final Ticker t = new Ticker(zoomPanel);

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                t.done();
                frame.dispose();
            }
        });
        t.start();

        frame.setLocation(new Point(640, 0));
        frame.pack();
        frame.setVisible(true);
    }

    private final Color[][] model = new Color[8][8];

    public ZoomPanel() {
        setSize(new Dimension(400, 400));
        setMinimumSize(new Dimension(400, 400));
        setPreferredSize(new Dimension(400, 400));
        setOpaque(true);
    }

    private void setColorAt(int x, int y, Color pixelColor) {
        model[x][y] = pixelColor;
        repaint(40 + x * STEP, 45 + y * STEP, 40 + (x * STEP) - 3, 45 + (y * STEP) - 3);
    }

    private Color getColorAt(int x, int y) {
        return model[x][y];
    }

    public void paintComponent(Graphics g) {
        long start = System.currentTimeMillis();
        if (!SwingUtilities.isEventDispatchThread()) {
            throw new RuntimeException("Repaint attempt is not on event dispatch thread");
        }
        final Graphics2D g2 = (Graphics2D) g;
        g2.setColor(getBackground());
        try {

            for (int x = 0; x < 8; x++) {
                for (int y = 0; y < 8; y++) {
                    g2.setColor(model[x][y]);
                    Ellipse2D e = new Ellipse2D.Double(40 + x * STEP, 45 + y * STEP, STEP - 3, STEP - 3);
                    g2.fill(e);
                    g2.setColor(Color.GRAY);
                    g2.draw(e);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        iter++;
        g2.setColor(Color.black);
        long stop = System.currentTimeMillis();
        cumulativeTimeTaken += stop - start;
        StringBuilder sb = new StringBuilder();
        sb.append(iter)
                .append(" frames in ")
                .append((double) (cumulativeTimeTaken) / 1000)
                .append("s.");

        System.out.println(sb);
    }

    private static class Ticker extends Thread {

        private final Robot robot;

        public boolean update = true;
        private final ZoomPanel view;

        public Ticker(ZoomPanel zoomPanel) {
            view = zoomPanel;
            try {
                robot = new Robot();
            } catch (AWTException e) {
                throw new RuntimeException(e);
            }
        }

        public void done() {
            update = false;
        }

        public void run() {
            int runCount = 0;
            while (update) {
                runCount++;
                if (runCount % 100 == 0) {
                    System.out.println("Ran ticker " + runCount + " times");
                }
                final Point p = MouseInfo.getPointerInfo().getLocation();

                Rectangle rect = new Rectangle(p.x - 4, p.y - 4, 8, 8);
                final BufferedImage capture = robot.createScreenCapture(rect);

                for (int x = 0; x < 8; x++) {
                    for (int y = 0; y < 8; y++) {
                        final Color pixelColor = new Color(capture.getRGB(x, y));

                        if (!pixelColor.equals(view.getColorAt(x, y))) {
                            final int finalX = x;
                            final int finalY = y;
                           SwingUtilities.invokeLater(new Runnable() {
                                public void run() {
                                    view.setColorAt(finalX, finalY, pixelColor);
                                }
                            });
                        }
                    }
                }

            }
        }

    }

}
Nach dem Login kopieren

Dieser optimierte Code verwendet createScreenCapture für eine effiziente Pixelabfrage und implementiert Smart Clipping für selektives Neuzeichnen und gewährleistet die EDT-Synchronisierung für Thread-Sicherheit. Durch die Behebung dieser Leistungsengpässe wird eine flüssigere und reaktionsschnellere grafische Ausgabe ermöglicht.

Das obige ist der detaillierte Inhalt vonWie kann ich Java-Code für das Zeichnen sich ständig ändernder Grafiken basierend auf der Mausposition optimieren, um die Leistung zu verbessern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage