Swing paintComponent();

tuedel

Aktives Mitglied
Hallo an alle !!

Ich habe eine kleine Verständnisfrage, mit der ich sicher gehen will, dass ich effizient mit der Zeichenfunktionalität von Swing umgehe.

Ich habe unzählige Swing Componenten, bei denen ich ein eigenes Aussehen in der paintComponent(); method vorgenommen habe. Was mich allerdings wundert ist, wie oft die Methode doch ausgeführt wird, obwohl laut einer Aussage diese nur dann gerufen wird wenn:

Die Komponente wird zum erstenmal sichtbar auf dem Bildschirm abgebildet.
Die Komponente wird in der Größe verändert.
Die Komponente wurde beschädigt und muß repariert werden (zum Beispiel wurde etwas verschoben, das vorher die Komponente verdeckte, und ein vorher verdeckter Teil der Komponente wird sichtbar).

Was aber zum Beispiel bei einem JPanel, dass ich als JButton fake (Mousevents die nen Enum State ändern und dann jeweils ein anderes Bild in der paintComponent() method zeichnen) passiert, ist das obwohl keine Interaktion mit dem Panel über die Maus erfolgt, die paintComponent permanent ausgeführt wird. Ich würde jetzt schlichtweg gern sicherstellen, ob dann nur geprüft wird, ob ein repaint notwendig ist, oder ob tatsächlich trotz keiner Veränderung die Component neu gezeichnet wird.

Falls der Aufruf öfter erfolgt als notwendig, könnte das daran liegen, dass alle meine Komponenten von dem vorherigen Entwickler in einem JPanel gelegt worden sind?! In diesem wird eine Animation ausgeführt die permanent einen repaint auslöst. Falls das bedeutet, dass auch alle child componenten neu gezeichnet werden, wüsste ich die Ursache und einen hohen Performanzverlust.

Ich hätte letztlich nur gern Gewissheit, wie die pipeline exakt aussieht und ob ich in meinem Programm Handlungsbedarf habe ?!

Herzlichen Dank!!
LG
tuedel
 

Michael...

Top Contributor
Falls der Aufruf öfter erfolgt als notwendig, könnte das daran liegen, dass alle meine Komponenten von dem vorherigen Entwickler in einem JPanel gelegt worden sind?! In diesem wird eine Animation ausgeführt die permanent einen repaint auslöst. Falls das bedeutet, dass auch alle child componenten neu gezeichnet werden, wüsste ich die Ursache und einen hohen Performanzverlust.
Lass doch einfach mal die Animation und das permanente repaint() in dem Container Panel weg, dann wirst Du feststellen, dass die anderen Komponenten ebenfalls nicht mehr so oft neu gezeichnet werden.
Grundsätzlich scheint mir ein animiertes/animierendes JPanel, welches weitere Komponenten enthält etwas fragwürdig.
 

Marco13

Top Contributor
Falls der Aufruf öfter erfolgt als notwendig, könnte das daran liegen, dass alle meine Komponenten von dem vorherigen Entwickler in einem JPanel gelegt worden sind?! In diesem wird eine Animation ausgeführt die permanent einen repaint auslöst. Falls das bedeutet, dass auch alle child componenten neu gezeichnet werden, wüsste ich die Ursache und einen hohen Performanzverlust.

Das bedeutet es. Wenn man repaint() aufruft, woher soll das Panel wissen, dass es bestimmte Teile DOCH nicht repainten muss? Das repaint() sollte in diesem Sinne möglichst "lokal" sein, also NUR auf der Component aufgerufen werden, die wirklich neu gezeichnet werden muss...
 

tuedel

Aktives Mitglied
Hallo und danke für die schnellen Antworten.

Ich habe mir den paint Prozess in meinem Programm nochmal genau angesehen. An sich hat wohl mein Vorgänger das Problem gehabt, dass wenn man die Komponenten, die nicht im eigentlichen Sinne Teil des animierenden Panels sind, als separierte Componenten im Contentpane durch das animierende Panel einfach "übermalt" werden. Es handelt sich dabei um eine Kartendarstellung die aufgrund der animation permanent geupdated werden muss.

Abgesehen davon, dass er viel zu viel neu zeichnet wäre das bei einem panning prozess jedoch auf jeden Fall notwendig. Nun ist es allerdings so, dass bspw. verschiedene Menüs mit Metadaten sagen wir mal fixed über der Karte liegen. Da die aber bei Separation nicht nachgezeichnet werden, "übermalt" das animierende Panel die anderen Componenten.

Vielleicht brauch ich nur einen Denkanstoß, aber wie könnte ich eine Componente "über" die animierende legen, ohne sie neu zeichnen zu müssen, oder permanent ein clipping durchzuführen. (Zumal sich beim pannen die Menüs ja nicht ändern und ich sie deswegen auch nicht neu zeichnen wollen würde).

Herzlichen Dank!!

LG
Lou
 

Marco13

Top Contributor
Ich würde mir eher die Frage stellen, ob es schlimm ist, wenn irgendein Menü neu gezeichnet wird, wenn im Hintergrund eine Landkarte mit Animation usw. sowieso komplett neu gezeichnet wird. Es gibt zwar prinzipiell Dinge wie JLayeredPane, oder repaint(x,y,w,h), mit dem man genau den Bereich neuzeichnen lassen könnte, in dem NICHT das Menü zu sehen ist, aber ... wozu der Aufwand ...? :bahnhof:
 

tuedel

Aktives Mitglied
Hallo Marco,

der Aufwand ist insofern gerechtfertigt, dass bspw. Teile des Menüs aus JTable/ JLists bestehen, die unter anderem auch Stringoperationen mit jedem update ausführen müssen. Wenn ich jetzt 25 fps für die animation erreiche, erscheint mir ein 25faches repaint von Tabellen und ähnliches überflüssig und könnte die hohe CPU Last erklären (z.T. 50% +).

Wenn ich bspw. eine der umfangreicheren Tabellen ausblende, sinkt die cpu last auf 20 %.

Daher würde ich es schon begrüßen, den Zeichenprozess intelligenter zu gestalten.
 

tuedel

Aktives Mitglied
Hm ich habe das JLayeredPane ausprobiert und folgendermaßen implementiert:

Java:
JLayeredPane content = new JLayeredPane();
        content.setLayout(null);

content.add(map, JLayeredPane.DEFAULT_LAYER);
        content.add(options, JLayeredPane.PALETTE_LAYER);
                
        setContentPane(content); // Applet container

Das Menü wird zwar nicht übermalt, der repaint wird jedoch immernoch permanent ausgeführt.
Irgendwas falsch gemacht?
 

Marco13

Top Contributor
Vielleicht hätte ich die JLayeredPane nicht so unreflektiert erwähnen sollen :oops: ich weiß nicht, welche Auswirkungen ein "repaint" auf eine der Components im JLayeredPane hat (nebenbei: Sowas wie JLayeredPane, aber auch schon die ganz normalen painting-Mechanismen von Swing, mit RepaintManager, dirty rectangle detection & Co, sind VIEL(!) komplizierter, als sie aussehen ... ;) )

Es war nur ein Gedanke, dass man damit vielleicht das Neuzeichnen auf die Landkarten-Component beschränken kann. Ansonsten wäre eine Möglichkeit, zu versuchen, mit repaint(x,y,w,h) den zu Zeichnenden Bereich zu bestimmen. Inwieweit das optimizedDrawingEnabled-Flag bei solchen Sachen noch relevant ist, müßte man sich genauer überlegen.
 

tuedel

Aktives Mitglied
Was hälst du von einem separatem container wie einen internalframe oder ein jwindow. Die sollten ja dann gänzlich unabhängig vom contentpane des applets sein.
 

Marco13

Top Contributor
Vielleicht, vielleicht auch nicht. Da hilft nur ausprobieren. :bahnhof:

Ich wollte gerade mal schauen, ob das mit repaint(x,y,w,h) gehen könnte: Wenn man keinen RepaintManager setzt, wird trotzdem immer die GANZE component neu gezeichnet - offenbar bildet er einfach das Bounding Rectangle der Dirty-Bereiche (wenn man nicht versucht, um das Menü herum neu zu zeichnen, wird auch nur der entsprechende Bereich neu gezeichnet!). Wenn man aber, wie ich eben, NUR zum Debuggen (!) einen eigenen RepaintManager anfügt, der einfach die Aufrufe weiterreicht, zeichnet er auch nur die als dirty markierten Bereiche. Warum das so ist, weiß ich spontan nicht, aber das könnte man sich im RepaintManager sicher mal genauer ansehen

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;

class MapPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        System.out.println("Painting in map  "+g.getClip());
        g.setColor(Color.BLUE);
        g.fillRect(0,0,getWidth(),getHeight());
    }
}

class MenuPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        System.out.println("Painting in menu "+g.getClip());
        g.setColor(Color.GREEN);
        g.fillRect(0,0,getWidth(),getHeight());
    }
}

public class RegionPaintTest
{
    public static void main(String[] args)
    {
        initRepaintManager();
        SwingUtilities.invokeLater(new Runnable()
        {
            
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final JPanel mapPanel = new MapPanel();
        mapPanel.setLayout(null);
        mapPanel.setPreferredSize(new Dimension(600,600));
        
        JPanel menuPanel = new MenuPanel();
        mapPanel.add(menuPanel);
        menuPanel.setBounds(0,0,200,200);
        
        f.getContentPane().add(mapPanel);
        f.pack();
        f.setVisible(true);
        
        Thread t = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    for (int i=0; i<3; i++)
                    {
                        Thread.sleep(2000);
                        System.out.println("Trigger full repaint");
                        mapPanel.repaint();
                    }
                    for (int i=0; i<3; i++)
                    {
                        Thread.sleep(2000);
                        System.out.println("Trigger partial repaint");
                        mapPanel.repaint(201,0,400,600);
                        mapPanel.repaint(0,201,200,400);
                    }
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                
            }
        });
        t.start();
    }
    
    
    private static void initRepaintManager()
    {
        RepaintManager.setCurrentManager(new RepaintManager()
        {
            @Override
            public void addDirtyRegion(
                JComponent c, int x, int y, int w, int h)
            {
                super.addDirtyRegion(c, x, y, w, h);
                System.out.println("addDirtyRegion " + x + " " + y + " " + w + " " + h + " on " + c);
            }
            @Override
            public void paintDirtyRegions()
            {
                super.paintDirtyRegions();
            }
            
        });
    }
    
}


Wie auch immer, das bringt ja alles nichts:
- Ändere das Layout, so dass das Menü außerhalb der Karte ist ODER
- Sorg' dafür, dass das Menü schnell gezeichnet werden kann (sollte nicht so schwer sein) ODER
- Find dich damit ab, dass es etwas langsamer ist (nur der Vollständigkeit halber ;) ) ODER
- Versuch' irgendwas zu frickeln, in der Hoffnung, dass es "was bringt", auch wenn es dadurch unwartbar wird...
 

tuedel

Aktives Mitglied
Hallo und danke Marco für deine Hilfe!!

Ich habe mich jetzt mit dem Clipping versucht, um dem Ganzen Herr zu werden. Ich habe eine Area von der Map erzeugt und die Bounds des Menüs ausgeschnitten.

Java:
     mapBounds = new Area(map.getBounds());
        mapBounds.subtract(new Area(options.getBounds()));

Das dann in der paintComponent der Karte als clipping eingesetzt, sodass ich nicht über das Menü zeichne.

Java:
g2.setClip(JMain.getInstance().getMapBounds());

Jetzt wird der Bereich, bei dem sich das Menü befindet, nicht mehr neu gezeichnet. Allerdings wird jetzt stattdessen eine graue Fläche angezeigt. Wenn ich die Karte nicht anzeige, ist das Menü an der entsprechenden Position sichtbar. Ich habe zuerst die map und dann das menü zum contentpane des Applets hinzugefügt. Demnach sollte eigentlich der gewünschte Effekt zu sehen sein..?

LG
 

Michael...

Top Contributor
Jetzt wird der Bereich, bei dem sich das Menü befindet, nicht mehr neu gezeichnet. Allerdings wird jetzt stattdessen eine graue Fläche angezeigt.
Kannst Du dazu mal kompilierbaren Bsp Code posten?
Vermutlich wird man dazu aber mit angemessenem Aufwand nicht eine zufriedenstellende Lösung finden, solange das Menü sich über der Karte befindet. Kann man die Karte evtl. aufteilen und z.B. auf drei JPanels darstellen, die um das Menü herumliegen?

Normalerweise sollte aber die Darstellung das Menüs im Verhältnis zum Neuzeichnen der Karte nicht sonderlich mehr Rechenaufwand bedeuten? Wie sieht es mit der Last aus wenn hier Standardkomponenten statt eigene verwendet werden? Wie schaut so eine paintComponent Deines Menüs aus?
 

Marco13

Top Contributor
Wann wird das clip gesetzt? Falls die Map ein JPanel ist, wird ggf. schon in
super.paintComponent(g);
der Hintergrund gelöscht. Evtl. könnte man da mit
mapPanel.setOpaque(false);
was machen, aber ... das ist alles ein bißchen hakelig...
 

tuedel

Aktives Mitglied
Hallo Michael,

an sich ist das von der Mechanik kein großes Ding.

Ein Applet/irgendein Heavyweight container, in dem sich die Karte (ein JPanel) befindet, in der die Tiles (oder bpsw. irgendeine Image) liegt. Dann muss ein Thread bestehen, der den repaint kontinuierlich ausführt.

In das Contentpane dann ein zweites Panel, in dem dann alternative Informationen angezeigt werden.

Was das Aufteilen der Karte angeht - das habe ich auch überlegt, würde aber den Korrektionsaufwand nicht für das korrekte Zeichnen der Tiles rechtfertigen. Wenn man saubere Bounds festlegt, sodass die Karte in jedem Falle bspw. rechteckig wäre, wäre die saubere Trennung kein Problem. Da ich aber nicht ausschließen kann, dass die Menüs in Zukunft auch draggable sind - keine Lösung.

Was den Rechenaufwand angeht - hätte ich auch behauptet, dass das nicht unglaublich ins Gewicht fallen sollte. Die Metadaten Tabelle zeigt aber was anderes. Sind halt ca. 15-20 Zeilen, dessen repaint aber unzählige String Operationen enthält - sagen wir 15-20 x 10. Zumindest kann ich mir anders nicht die hohe CPU Last erklären, die auftritt, wenn diese Table sichtbar ist.

Mein Vorgänger hat versucht den Prozess des neu Zeichnens auszubremsen in dem er die paintComponent des scrollpanes angepasst hat, in dem sich die Tabelle befindet:

Java:
@Override
			public void paint(Graphics g) {

				long actTime = System.currentTimeMillis();
				long dif = actTime - lastTime;
				if (!isFocused() && dif < 250) {

					if (isBufferChanged()) {
						reDraw(g);
					}
				} else {
					isBufferChanged();
					reDraw(g);
					lastTime = actTime;
				}
				g.drawImage(store, 0, 0, null);
			}

Allerdings habe ich dann wieder den Fall, dass die gesamte Table neu gezeichnet wurde, obwohl sich bspw. von 1000 Datensätzen, nur 10% verändert haben. Ich nehme also die Gewalt über den redraw aus der Table und dem Tablemodel und lege sie in die Karte, die ich nicht in gleichem Maße unter Kontrolle habe.

Da ich das Problem gern lösen würde, wäre ich auch geneigt, die elegantere Methode auch auf "weniger" Rechenaufwändige Menüs anzuwenden. Wenn man effizienter arbeiten kann, will ich wegen Schwierigkeiten nicht den einfachen Weg gehen und "damit leben".

@ marco

Die map ist ein JXPanel dessen paintComponent wie folgt aussieht:

Java:
@Override
    protected void paintComponent(Graphics g) {
        if(backgroundPainter != null) {
            if (isOpaque()) {
                super.paintComponent(g);
            }
            
            Graphics2D g2 = (Graphics2D)g.create();            
            g2.setClip((Shape) JMain.getInstance().getMapBounds());
            
            
            try {
                SwingXUtilities.paintBackground(this, g2);
            } finally {
                g2.dispose();
            }
        } else {
            super.paintComponent(g);
        }
    }

Das Setzen von opague auf false habe ich versucht.
 

tuedel

Aktives Mitglied
Die beste mögliche Lösung könnte der Gedanke von einem Kollegen sein, ein JWindow zu verwenden. Durch die getrennte Container Instanz, beeinflussen sich die Heavyweight components nicht.

Wenn ich dann zur Laufzeit die Größen anpasse, muss ich für die JWindows die Größen ändern, da ich ja kein opague setzen kann. Ich frag mich allerdings, ob das elegant ist, für die Menüs jeweils einen heavyweight container einzusetzen ?!

Was meint ihr?

Herzlichen Dank.
LG
 

Marco13

Top Contributor
Mein Vorgänger hat versucht den Prozess des neu Zeichnens auszubremsen in dem er die paintComponent des scrollpanes angepasst hat, in dem sich die Tabelle befindet:

Oh jeh... Was ist das denn alles? Der JScrollPane so ins Zeichnen reinzupfuschen ist heikel, wenn man bedenkt dass da ja auch noch ein Viewport und irgendwelche Blitting-Strategien dahinterliegen ... was "isBufferChanged" und "reDraw" genau machen würde ich ... bestenfalls aus Neugier wissen wollen... ;)

Die map ist ein JXPanel dessen paintComponent wie folgt aussieht:

Und der BackgroundPainter ist der, der das eigentliche Zeichnen des Bildes/Tiles durchführt?

Ich würde erstmal versuchen, das Problem einzugrenzen. Irgendwas zu ändern hat meistens zur Folge, dass ... .... irgendwas geändert wurde (sowas wie dieses "ausbremsen", da kommt man ja nur drauf, wenn man SEHR verzweifelt ist) und nachher traut sich niemand mehr, das rückgängig zu machen, weil man nicht weiß, ob es "wichtig" ist.
Also... wenn du die spezielle Tabelle und das SEHR spzezielle Scrollpane mal ersetzt durch
Java:
private JComponent createDummy()
{
    int rows = 100;
    int cols = 10;
    Object[][] rowData = new Object[rows][cols];
    Object[] columnNames = new Object[cols];
    for (int i=0; i<cols; i++)
    {
        columnNames = "Col"+i;
        for (int j=0; j<rows; j++) rowData[j][i] = "Cell"+i+","+j;
    }
    JTable table = new JTable(rowData, columnNames);
    return new JScrollPane(table);
}
ist es dann immernoch langsam? Hat die Tabelle, die da eigentlich angezeigt wird, einen eigenen CellRenderer? Wenn ja, wie sieht der aus? Wird da drin vielleicht eine Datenbankabfrage gemacht oder so? ;)
 

tuedel

Aktives Mitglied
Also was im Moment schon ugly ist, dass das noch gar keine JTable ist, sondern eine JList - Zugleich ohne eigenes ListModel, um repaints auf updates auszuführen. Das heißt, dass er die Metadaten eines Objektes für jede Zeile neu auslesen und für die Darstellung anpassen muss (ja eigener cellrenderer).

Der Renderer macht halt die ganzen Stringoperationen. Kleines Beispiel:

Java:
@Override
	public Component updateComponent(C value, int index, boolean mouseOver) {

	      
		if (mouseOver) {
			setBackground(MouseOverColor);
		} else if (index % 2 == 0) {
			setBackground(zero);
		} else {
			setBackground(one);
		}
		for (LineEntry<C, ?> l : this.list) {
		      if(value!=null){
			l.update(value, index);
		      }
		}

		return linePanel;
	}

Das ist eine methode die von einem abstrakten Cellrenderer überschrieben wird und bei jedem getListCellRendererComponent(...) Aufruf ausgeführt wird. Da werden alle Einzeleinträge (JComponents) durchlaufen und geupdated - dabei ist der value das Object das die Meta Daten enthält. Die werden dann ausgelesen - angepasst wie bspw.:

Java:
@Override
            protected void update(Competitor source, JTextPane component, int index) {
                CompetitorKeyframeData inter = source.getInterpolationInfo().getKeyFrameData();
                if (inter != null && source.getInterpolationInfo().getStatus()) {
                    Integer d = inter.getDistToLeader();
                    if (d != null && d > 0) {
                        component.setText(parseDistance(d));
                    } else {
                        component.setText("-");
                    }
                } else if (!source.getInterpolationInfo().isSailMasterStatus()) {
                    component.setText("no data");
                } else if (inter != null && inter.getDistToLeader() != null) {
                    component.setText(parseDistance(inter.getDistToLeader()));
                }
                if (Config.isMatchRace() == true) {
                    setRscBasedBgColor(source.getRsc(), component);
                }
                if (followColor) {
                    toggleColor(source, component);
                }
            }

Also eine recht lange Kette, die ich anfangs auch nicht durchblickt habe und inzwischen als äußerst ineffizient ansehe. Ich möchte in Zukunft eine JTable einsetzen, mit eigenem TableModel um zellengenau updaten zu können. Das bringt nur nix, wenn die ohnehin 25x pro sek gezeichnet wird.

Ich bin gerade vom Mittag zurück und werd mal deinen Code einfügen.
brb.

Danke!!
 

Marco13

Top Contributor
Was das alles macht und wo das aufgerufen wird, sieht man da jetzt halt nicht... aber irgendwelche Berechnungen (inter.getDistToLeader(), parseDistance(d) usw. ) um den Text in einer JTextPane (!? :autsch: ) zu setzen kann halt aufwändig sein. Es könnte sich lohnen, da mal genauer nachzusehen...
 

tuedel

Aktives Mitglied
Das ist es, deswegen soll statt der JList auch eine JTable rein, dessen TableModel mit den anzuzeigenden Daten geupdated werden soll, statt das im Renderer zu machen.

Ich habe deine Beispiel tabelle eingefügt. Diese ist erwartungsgemäß schneller, auch wenn ich mit dem Krüppel von Rechner keine genauen Angaben machen kann. Allerdings hat die zZ gar keinen eigenen Renderer. Der käme auch bei der neuen JTable zum Einsatz, um die Inhalte gemäß des Datentyps anzupassen (bspw. Images usw.).

Ich denke du würdest vermuten, dass nicht der Zeichenprozess so langsam ist, sondern die JList, nicht wahr :oops:?

An sich ist das richtig, könnte aber dennoch nicht den gewünschten Effekt haben. Updates erfolgen ohnehin oft, aber die müssen sich nicht noch mit den Zeichenprozessen überschneiden, dass wäre lediglich - das größere Übel (falls es das ist = ) ) auszumerzen. Das bedeutet aber nicht, dass das andere nicht genügend Einfluss ausübt.

An sich könnte ich auch mit der Tabelle beginnen und dann prüfen, wieviel sich dadurch bessert. Allerdings halte ich es für semi gut die UI weiterzuführen, wenn ich die hierarchy doch noch ändern muss. Ich will den Code quasi nicht mehrfach umschreiben müssen.

Ansonsten gibt es aber kein wirklich großes Loch im Renderer. Quasi keine aufwendigen Berechnungen. Lediglich eine Menge Stringarbeit und setText Aufrufe halt.

Danke.
LG
 

tuedel

Aktives Mitglied
Achja was hälst du jetz eigentlich von dem JWindow. Das scheint bisher den Anforderungen zu genügen. Liegt definitiv vorn. Beeinflusst sich nicht gegenseitig und unterstützend könnte ich trotzdem die Clipping Area setzen, um noch ein wenig in der Karte zu sparen.

Hier wird jedenfalls nicht permanent die UI mitgezeichnet (habe ein Auswahlmenü mit Comoboxes und eigenem Renderer und Tablemodel zum üben geschrieben). Der Renderer wird exakt nur zum einblenden aufgerufen.
 

Michael...

Top Contributor
Das ganze schaut mir nach einem fehlerhaften Konzept aus. Unter dem Aspekt, dass ein Renderer im Paint Prozess einer solchen Komponente (egal ob JList oder JTable) eine wichtige Rolle spielt, sollte man irgendwelche Berechnungs/Bestimmungsprozesse die für ein Graphikupdate nicht relevant sind aus diesem Prozess raushalten. Solche relevanten Informationen wie der Text der dargestellt werde soll, müssen m.M. schon "vor" dem Zeichenprozess vorliegen und im Renderer nur abgeholt werden. Es macht ja keinen Sinn einen Wert der sich nicht geändert hat bei jedem Neuzeichnen neu zu bestimmen. Der Trigger zur Neubestimmung muss aus einer anderen Ecke kommen.
Von daher sollte man das Konzept vor allem unter dem Aspekt möglicher Weiterentwicklungen überarbeiten. Alles andere ist nur ein Workaround und geht früher oder später wieder nach hinten los.
 

tuedel

Aktives Mitglied
Jo Michael, so seh ich das auch. Deswegen will ich auch in Zukunft zu einem eigenen TableModel, bei dem das Update von woanders kommt und dann lediglich der Renderer die Anzeige übernimmt. Ansonsten was das JWindow angeht - keine zusätzliche UI (Border, Header usw.). Dazu liegt es definitiv vor des ContentPane und ich muss deswegen dessen Inhalt nicht neu zeichnen, auch wenn "dahinter gezeichnet" wird.

Es sieht für mich so aus, als wäre das eine der wenigen Möglichkeiten um bei dem UI Aufbau dem repaint zu entkommen.

Danke für eure Hilfe!!
 

tuedel

Aktives Mitglied
Hallo !!

Ich melde mich mal wieder, weil ich doch noch einen anderen Gedanken hatte, wie man die Problematik lösen könnte. Mein Gedanke ging in die Richtung die Karteninhalte zu trennen. In diesem Zuge müsste ich den Hintergrund, der ja ohne drag/zoom nur 1x gezeichnet werden muss in einem layeredPane mit der niedrigsten Order versehen. Sämtliche Inhalte, die sich auf der Karte befinden, könnten in einem separatem durchsichtigem Panel gezeichnet werden, sodass ich abhängig der darzustellenden Elemente den repaint steuern könnte.

Ich habe mir als Möglichkeit vorgestellt, die UI elemente in einer Map mit entsprechenden Enums und deren relativen Position zum Applet zu mappen. Während des Zeichenprozesses dann zu prüfen, ob sich das zu zeichnende Objekt innerhalb der boundaries befindet. Dadurch könnte der objekt repaint und toplayer repaint umgangen werden. Wenn das Objekt nur z.T. innerhalb der Boundaries liegt, könnte man den entsprechenden Teil im repaint des Toplayers festlegen, um nicht die gesamte UI neu zu zeichnen.

Das einzige was mich daran stört ist, dass ich eigentlich keinen Plan habe, ob ich mit solchen permanenten Vergleichen nicht genauso schnell/langsam bin, wie wenn ich die Toplayer neu zeichnen würde. - wobei das widerum vom Inhalt des Toplayers abhängt.

Vielleicht schafft dieser Gedanke Anreize für weitere Diskussionen, wie sich Animationen in Swing aus Sicht der Konzeption gut umsetzen lassen oder ob jemand eine Aussage dazu treffen kann, wie stark sich Vergleichsoperationen im Gegensatz zu repaints auswirken können.

Herzlichen Dank!!

LG
tuedel
 

Marco13

Top Contributor
Ich glaube das steht und fällt mit der Frage, die noch über allem schwebt: Warum muss das Zeichnen eines Menüs so aufwängig sein?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L 2D-Grafik Swing paint|paintComponent AWT, Swing, JavaFX & SWT 2
M Swing Swing-Widgets und paintComponent() AWT, Swing, JavaFX & SWT 2
D Fragen zu Swing, paintComponent() und repaint AWT, Swing, JavaFX & SWT 6
A paintComponent in Swing AWT, Swing, JavaFX & SWT 5
Juelin javax.swing in javafx AWT, Swing, JavaFX & SWT 1
A Eclipse 2023 und Swing AWT, Swing, JavaFX & SWT 4
W 2 JTables in einem Swing-Fenster? AWT, Swing, JavaFX & SWT 5
H Swing Componente zur Läufzeit ändern AWT, Swing, JavaFX & SWT 3
B Actionlistener mit Java Swing AWT, Swing, JavaFX & SWT 2
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
H Swing Buttons erst nach Klick sichtbar AWT, Swing, JavaFX & SWT 13
ExceptionOfExpectation Anpassung von JKomponentengrößen (Swing) AWT, Swing, JavaFX & SWT 3
thor_norsk AWT SWING Aufgabe AWT, Swing, JavaFX & SWT 7
U Zwei Fragen zu eienr Swing Aufgabe AWT, Swing, JavaFX & SWT 2
M Swing Bilder in Swing anzeigen AWT, Swing, JavaFX & SWT 9
H Swing , GridLayout, Größenbestimmung der Komponenten im Layout AWT, Swing, JavaFX & SWT 8
H Simple Animation mit Swing AWT, Swing, JavaFX & SWT 2
Guybrush Threepwood Einfachste Möglichkeit zum Abspielen eines Videos in Swing AWT, Swing, JavaFX & SWT 4
A Swing ProgressBar über 2 parallel laufende Threads AWT, Swing, JavaFX & SWT 2
M Swing GridLayout AWT, Swing, JavaFX & SWT 2
O return-Statement mit Swing AWT, Swing, JavaFX & SWT 6
O Ein Java-Programm mit Swing steuern AWT, Swing, JavaFX & SWT 1
Monokuma Swing zu JavaFX AWT, Swing, JavaFX & SWT 5
J Swing Slider AWT, Swing, JavaFX & SWT 11
G Thread starten Swing AWT, Swing, JavaFX & SWT 5
G Swing JPasswordField AWT, Swing, JavaFX & SWT 12
L Swing Button Farbe ändern/wechseln AWT, Swing, JavaFX & SWT 2
C Swing AWT GUI Anfänger Aufgabe AWT, Swing, JavaFX & SWT 7
W Inject bei einem Swing Frontend AWT, Swing, JavaFX & SWT 8
L Kommunikation zwischen Klassen / Konstruktoren bei Swing AWT, Swing, JavaFX & SWT 9
M Feldvalidierung swing AWT, Swing, JavaFX & SWT 4
E Swing Componenten werden nach Änderung des display modes verzerrt dargestellt AWT, Swing, JavaFX & SWT 8
D [Swing] Anordnung von Komponenten mit GridLayout Manager AWT, Swing, JavaFX & SWT 13
O Zukunft von Swing und JavaFX ? AWT, Swing, JavaFX & SWT 3
S Swing Fenster State Machine AWT, Swing, JavaFX & SWT 1
T Swing Swing an Bildschirm anpassen AWT, Swing, JavaFX & SWT 3
S Swing Panel wird nicht neu gezeichnet AWT, Swing, JavaFX & SWT 3
M Swing Java Swing/AWT Combobox Bug AWT, Swing, JavaFX & SWT 3
M Swing GUI mittels erben sowie variabler Dateninhalt AWT, Swing, JavaFX & SWT 1
W Swing Multitouch mit Swing AWT, Swing, JavaFX & SWT 6
S Swing-Applikation die ein Numpad nachbildet samt Keybindings..? AWT, Swing, JavaFX & SWT 5
S Swing Java Swing AWT, Swing, JavaFX & SWT 6
Blender3D Problem mit € Symbol Font Gotham Windows 10 Swing AWT, Swing, JavaFX & SWT 11
J Swing oder JavaFX AWT, Swing, JavaFX & SWT 21
D Swing Anwendung ohne JPanel erstellen AWT, Swing, JavaFX & SWT 1
D SQL Statements mit Java Swing benutzen AWT, Swing, JavaFX & SWT 4
Damtonix BufferStrategy flackert (Swing) AWT, Swing, JavaFX & SWT 9
D DatePicker für Java Swing AWT, Swing, JavaFX & SWT 2
B JavaFX oder swing AWT, Swing, JavaFX & SWT 3
T Java Swing - kleines Rechteck unter dem cursor AWT, Swing, JavaFX & SWT 5
L Swing Größe automatisch anpassen AWT, Swing, JavaFX & SWT 14
G Swing Swing Binding JList funktioniert nicht AWT, Swing, JavaFX & SWT 5
Blender3D Meine Swing Anwendung läuft unter Windows 10 und Ubuntu aber nicht auf Windows 7 AWT, Swing, JavaFX & SWT 16
B Bar Plot in Swing JPanel AWT, Swing, JavaFX & SWT 0
D Swing in Kombination mit JGraphX und JGraphT AWT, Swing, JavaFX & SWT 0
F main-Funktion bei Swing AWT, Swing, JavaFX & SWT 4
S Java Swing Print() method AWT, Swing, JavaFX & SWT 4
S Java Swing auf Windows Phone AWT, Swing, JavaFX & SWT 6
I JAVAFX - Übergabe der Inhalte an eine Scene - Wo ist der Vorteil gegenüber Swing? AWT, Swing, JavaFX & SWT 2
S Manuelles Menu in Swing AWT, Swing, JavaFX & SWT 3
T Custom Window ohne Swing / AWT / FX..?! AWT, Swing, JavaFX & SWT 1
MaxG. Swing Swing Komponenten zur Laufzeit hinzufügen AWT, Swing, JavaFX & SWT 2
Java_RY Bin Ratlos bzgl Malen in Swing AWT, Swing, JavaFX & SWT 5
offi Swing Shuttle List AWT, Swing, JavaFX & SWT 9
I Graph mit Swing zeichnen AWT, Swing, JavaFX & SWT 8
D Swing Swing Objekte sehen im Entwurf anders aus als beim Ausführen AWT, Swing, JavaFX & SWT 3
S Swing & Clean und build Problem AWT, Swing, JavaFX & SWT 12
javampir Swing repaint in JavaFX Anwendung AWT, Swing, JavaFX & SWT 3
K Mit JavaFX angefangen. Lohnt sich Swing? AWT, Swing, JavaFX & SWT 28
B Swing Update Swing Komponente bevor Methode startet. AWT, Swing, JavaFX & SWT 4
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
B Swing WindowBuilde: Menu -> anderes Panel wechseln AWT, Swing, JavaFX & SWT 1
K eigener button in swing AWT, Swing, JavaFX & SWT 3
A JavaFX DatePicker in Swing beim Start nicht sichtbar AWT, Swing, JavaFX & SWT 2
windl Bufferstrategy in Swing nachstellen AWT, Swing, JavaFX & SWT 0
M Kamera in Java Swing einbinden AWT, Swing, JavaFX & SWT 4
Z Swing Swing und die Progressbar AWT, Swing, JavaFX & SWT 1
J Frage zur objektorentierten Swing Programmierung AWT, Swing, JavaFX & SWT 10
Xanny 2D-Grafik Beginner! Probleme mit Swing, Gprahics class und paint AWT, Swing, JavaFX & SWT 13
F Java Swing Rechteck in JPanel zeichnen AWT, Swing, JavaFX & SWT 7
N Swing Benötige Hilfe um ein Swing Canvas zu speichern AWT, Swing, JavaFX & SWT 4
stylegangsta JButton Fehelr javax.swing.ImageIcon.<init>(Unknown Source) AWT, Swing, JavaFX & SWT 24
RalleYTN Swing JavaFX VideoPlayer in Swing einbetten. Ich komm nicht an die Dimension des Videos! AWT, Swing, JavaFX & SWT 0
T swing läuft nur beding flüssig AWT, Swing, JavaFX & SWT 1
A Sonderzeichen bei Swing AWT, Swing, JavaFX & SWT 3
L DoubleBuffering unter Swing AWT, Swing, JavaFX & SWT 0
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
D Java Swing, Label lässt sich nicht mit Checkboxen/Knopf verändern AWT, Swing, JavaFX & SWT 2
J Swing Basics - JButton funktioniert nicht. AWT, Swing, JavaFX & SWT 1
J Swing/AWT | Dynamisch erzeugte Objekte ansprechen AWT, Swing, JavaFX & SWT 1
N JavaFX Umstieg von Swing auf Java FX AWT, Swing, JavaFX & SWT 6
J GUI Anfänger einfaches Program AWT, Swing, JavaFX & SWT AWT, Swing, JavaFX & SWT 3
M Swing Grundlegende Frage zu SWING mit WindowBuilder AWT, Swing, JavaFX & SWT 11
M Plugin oder eigenes Tool mit zB SWING AWT, Swing, JavaFX & SWT 2
Z Java-Swing : JComponent AWT, Swing, JavaFX & SWT 2
Z Swing Swing: Elemente werden doppel/verschoben gezeichnet, sind teils unsichtbar etc... AWT, Swing, JavaFX & SWT 10
S JComboBox aus anderer Klasse füllen (Java-Swing) AWT, Swing, JavaFX & SWT 0
N JComboBox in JTable [Swing] -> totaler UI-Einsteiger AWT, Swing, JavaFX & SWT 3
T Swing Kompatibilitätsproblem zwischen Swing und JavaFX AWT, Swing, JavaFX & SWT 4
M Layout-Probleme unter Swing AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben