2011-01-13 5 views
7

JLayeredPane ermöglicht es, mehrere Komponenten übereinander zu stapeln JLayeredPane.add(Component, Integer). Komponenten in höheren "Schichten" werden über Komponenten in unteren "Schichten" angezeigt.JLayeredPane versus Container Schichtung

Container.add(Component, int) bietet einen ähnlichen Mechanismus, wobei Komponenten mit unteren Indizes auf Komponenten mit höheren Indizes angezeigt werden.

Bitte beachten Sie, dass der erste Mechanismus Integer und der zweite Mechanismus verwendet verwendet int. Auch macht man hohe Werte über niedrige, und das andere macht das Gegenteil. Mischen Sie nicht die beiden :)

Meine Frage ist: Was ist der Sinn der Verwendung von JLayeredPane, wenn Container bereits den gleichen Mechanismus bietet? Ist eine Schicht besser als die andere?

UPDATE: Es gibt auch Container.setComponentZOrder(Component, int) zu berücksichtigen.

Antwort

6

meine eigene Frage zu beantworten:

Container.add(Component, int) und Container.setComponentZOrder(Component, int) sind nahezu identisch. Das vorherige ruft removeNotify() auf, während das letztere (aus Leistungsgründen) nicht tut.

Container-Layering funktioniert nur, wenn JComponent.isOptimizedDrawingEnabled() false zurückgibt. Eine Implementierung, die genau so zufällig false zurückgibt, ist ... Sie haben es erraten: JLayeredPane

Verwenden von Container-Layering wird abgeraten, da es unexpected side-effects haben kann.

Schließlich ist es erwähnenswert, dass während Container add(Component, int) deklariert tatsächlich Schichtkomponenten nicht richtig lackiert. JComponent und seine Unterklassen tun.

Ein weiterer interessanter Fund: Rufen Sie nie repaint() auf einem Kind von JLayeredPane auf. Dies führt dazu, dass sich die Komponente unabhängig von ihrer Z-Reihenfolge selbst überlagert. Sie sollten repaint() nur für JLayeredPane selbst aufrufen.

+0

Re "nie repaint() auf ein Kind von JLayeredPane aufrufen": Ich bin gespannt auf welche Art von Kind-Komponente, die Sie mit diesem gefunden haben. Ich stieß auf [ein ähnliches Problem] (http://stackoverflow.com/questions/5668721/jmenuitems-painting-over-higher-components-in-jlayeredpane) und festgestellt, dass, zumindest in meinem Fall, war es ein Problem mit JMenuItems speziell. Sie verhalten sich so, als wären sie immer oben (es sei denn, sie sind transparent). –

+0

@Aaron, ich erinnere mich nicht, welche Komponente ich verwendet habe, aber wenn Sie darüber nachdenken, macht es Sinn, dass alle Komponenten verhalten werden, sie sind immer oben. paint() soll annehmen, dass Sie die Clip-Grenzen so einstellen, dass sie nicht außerhalb der gewünschten Grenzen zeichnen. Wenn Sie repaint() direkt auf eine untergeordnete Komponente (ohne Grenzen) aufrufen, fordern Sie im Wesentlichen, dass es die Eltern ignoriert. Mit anderen Worten, dies ist kein Fehler in der Swing-Implementierung. Es ist Benutzerfehler. – Gili

+0

Eigentlich stimmt das nicht. Siehe [Malen in AWT und Swing] (http://java.sun.com/products/jfc/tsc/articles/painting/), speziell die Paint Processing-Sektion.Wenn Repaint() 'für eine JComponent aufgerufen wird, verwendet der RepaintManager das Clip-Rechteck und die Eigenschaften 'opaque' und 'isOptimizedDrawingEnabled' der Komponente, um die 'root'-Komponente zu bestimmen, von der aus die Paint-Operation beginnen soll. Die meisten Komponenten verhalten sich nicht so, als ob sie immer oben wären (d. H. 'AlwaysOnTop()' gibt standardmäßig 'false' zurück). –

0

Meine Annahme ist, dass die Funktionen Container.add(Component,int) und JLayeredPane.add(Component,Integer) die Komponente festlegen, die zu einem bestimmten Index hinzugefügt wird. Dieser Index wird dann von Layout-Managern verwendet, um Position, Layout und Reihenfolge der Bemalung der Komponente zu verwalten. Ich denke, JLayeredPane.setLayer(Component c, int layer) ist mehr, was Sie suchen, soweit Schichten gehen. Es wurde speziell zum Schichten der Komponenten erstellt. Nur meine zwei Sinne.