Swing JLayeredPane "Phänomen"?

S

Spacerat

Gast
Hallo Comunity
Es geht um Folgendes:
Für den Versuch, zwei JPanels (der obere davon ist grösstenteils transparent) übereinander zu legen verwende ich eine JLayeredPane (Versuche mit JRootPane scheiterten, weil ich es nicht hinbekomme, der GlassPane einen LayoutManager zu übergeben). Eine JLayeredPane lässt sich afaik am besten ohne LayoutManager verwenden, denn wenn man einen verwendet, ist' mit dem Überlagern von Komponenten vorbei. Null-Layout bedeutet, dass man die einzelnen Komponenten selbst platzieren und deren Grösse bestimmen darf (äh muss). Da sich die beiden JPanels 100%ig abdecken sollen hielt ich es für eine gute Idee, "reshape(x, y, w, h)" der JLayeredPane zu überschreiben. Okay, die ist @Deprecated, aber alles was Position und Ausdehnung einer Komponente angeht, kommt an dieser Methode nicht vorbei. Zumindest ist das für meine Zwecke (eigentlich) völlig ausreichend und viel bequemer, als einen ComponentListener (oder zwei) zu implementieren.
Java:
class MyPanel extends JLayeredPane {
  @Override
  @Deprecated
  public void reshape(int x, int y, int width, int height) {
    super.reshape(x, y, width, height);
    content.reshape(x, y, width, height);
    glass.reshape(x, y, width, height);
  }
}
Wider Erwarten, funktioniert das aber leider nicht (es wird nur eine graue Fläche angezeigt, weder Inhalt der Content- noch der GlassPane), wohingegen
Java:
class MyPanel extends JLayeredPane {
  @Override
  @Deprecated
  public void reshape(int x, int y, int width, int height) {
    super.reshape(x, y, width, height);
    content.reshape(x, y, width, height);
    glass.reshape(x + 1, y + 1, width - 2, height - 2);
  }
}
recht gut funktioniert, die GlassPane nur leider ein wenig zu klein ist. Woran kann das liegen?
BTW.: Google ist in Sachen LayeredPane zwar recht aufschlussreich, aber gerade über dieses "Phänomen" kann ich nichts finden. :(
 

bERt0r

Top Contributor
Ich versteh nicht ganz, ist deine glass Variable das GlassPane des Frames oder nur ein normales Panel das durchsichtig ist?
 
S

Spacerat

Gast
Das ist ein normales JPanel, das durchsichtig ist. Die Glasspane eines Frames oder sonstiger JRootPanes kann ich nicht verwenden, weil ich dort einen LayoutManager benötige, eine solche GlassPane jedoch nur eine simple Component ist.
 

bERt0r

Top Contributor
Also ich glaube das hat eher mit den layern zu tun (du musst beim adden ins LayeredPane immer den Layer angeben). Ich hab dir ein KSKB gemacht, da funktioniert das problemlos ohne komische +/- und sogar mit beliebig vielen Componenten! :D

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class LayeredPhenomaen  extends JFrame
{
	
	private JPanel contentPane;
	private JPanel content;
	private JPanel glassPanel;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					try
					{
						LayeredPhenomaen  frame = new LayeredPhenomaen();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public LayeredPhenomaen()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		content = new JPanel();
		JLabel label = new JLabel();
		try
		{
			label.setIcon(new ImageIcon(new URL("http://www.java-forum.org/avatars/spacerat.gif")));
		} catch (MalformedURLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		content.add(label);
		
		glassPanel = new JPanel();
		glassPanel.setOpaque(false);
		JLabel hallo = new JLabel("Hallo Welt");
		hallo.setForeground(Color.RED);
		glassPanel.add(hallo);
		
		JLayeredPane p = new JLayeredPane()
			{
				@SuppressWarnings("deprecation")
				@Override
				public void reshape(int x, int y, int width, int height)
				{
					super.reshape(x, y, width, height);
					for (Component c : getComponents())
					{
						c.reshape(x, y, width, height);
					}
				}
			};
		p.add(content, JLayeredPane.FRAME_CONTENT_LAYER);
		p.add(glassPanel, JLayeredPane.POPUP_LAYER);
		
		contentPane.add(p);
	}
}
 
Zuletzt bearbeitet:
S

Spacerat

Gast
Also ich glaube das hat eher mit den layern zu tun (du musst beim adden ins LayeredPane immer den Layer angeben). Ich hab dir ein KSKB gemacht, da funktioniert das problemlos ohne komische +/- und sogar mit beliebig vielen Componenten! :D

Java:
		p.add(content, JLayeredPane.FRAME_CONTENT_LAYER);
		p.add(glassPanel, JLayeredPane.POPUP_LAYER);
...okay, das habe ich auch schon gemacht, nur eben mit DEFAULT_LAYER und PALETTE_LAYER. Wenn ich mit diesen Konstanten ein wenig experimentiere, bekomm' ich es zumindest schon mal flakernd. Leider bekomm ich per Screenshot nur vollständige Bilder, so dass man dort nur sehen kann, wie's aussehen soll. Kann es sein, dass es an zu vielen Repaints innerhalb der Threads und gar nicht an der JLayeredPane liegt?
Mit 'nem KSKB hätt' ich ein Problem. Ich müsste dazu 3 mehr oder weniger umfangreiche grösstenteils undokumentierte Libs posten, glaube kaum, dass sich da jemand durchwühlen will.
Fakt ist, dass es mehrere unterschiedlich getimte Threads gibt. Der Erste, ein AudioStream, wirft ca. alle 500ms einen Event und es werden zwei Scopes (Source & Playback, 1 JPanel pro Kanal, 1 Thread pro Scope) mit Amplitudendaten gefüllt. Die beiden Scopes sind mit jeweils 40ms (25Hz) Wartezeit animiert, beide rufen innerhalb dieses Threads ihre Repaintmethode auf und geben eine UpdateInfo an ihre Levelmeter weiter. Diese Levelmeter widerum (keine eigenen Threads) rufen danach ihre eigene Repaintmethode auf. Das ganze sollte dann so aussehen, tut's aber leider nicht.
 

Anhänge

  • SwingAudioPlayer.png
    SwingAudioPlayer.png
    36,3 KB · Aufrufe: 37
S

Spacerat

Gast
Okaaay... es lag an den Threads... nun gibt es neben dem AudioStream-Thread nur noch einen Animator, "repaint()" wird demzufolge nur noch einmal aufgerufen und alles ist wie es sein soll.
 

Marco13

Top Contributor
BTW: Ich habe den Fall einer solchen "Pseudo-GlassPane" gerade auch, aber die Größenanpassung mit einem ComponentListener gemacht - funktioniert ganz gut.
[ot]
Das deprecation-Modell der meisten Swing-Methoden ist etwas unglücklich. Meistens sind die nach dem Muster
Java:
public void setBounds(int x, int y, int w, int h)
{
    reshape(x,y,w,h);
}

@Deprecated // use setBounds instead!
public void reshape(int x, int y, int w, int h) 
{ 
    /* The implementation */
}
Wenn man dieses Verhalten nun ändern will, was soll man dann tun? setBounds überschreiben funktioniert schlicht nicht. reshape überschreiben funktioniert zwar, aber ist deprecated - und niemand hindert Sunracle daran, in der nächsten Version zu schreiben
Java:
public void setBounds(int x, int y, int w, int h)
{
    /* The implementation */ 
}

@Deprecated // use setBounds instead!
public void reshape(int x, int y, int w, int h) 
{ 
    setBounds(x,y,w,h);
}
und "reshape" intern nicht mehr aufzurufen - schließlich war es ja lange genug deprecated...
[/ot]
 
S

Spacerat

Gast
[OT]Hatte mich auch schon gefragt, warum man das nicht ändert, aber da kann man lange drauf warten... Grund: Abwärtskompatibilität.
Was geht:
Java:
class MyPanel extends Component {
  @Override
  public void setBounds(int x, int y, int width, int height) {
    // my code
    /*super.*/reshape(x, y, width, height);
  }
}
Das ist zwar blöd so, aber man muss auf jeden Fall damit rechnen, dass jemand seine Klasse so gestaltet haben könnte. Würde Sunracle das Muster nun umdrehen (wie sie es von vorne herein hätten tun sollen ;)), gäbe es in MyPanel eine Endlosrekursion. Kurz gesagt: Sunracle kann das nicht mehr ändern, es sei denn sie vergessen das Thema Abwärtskompatibilität.[/OT]Das ein CL funktioniert hätte ist mir klar. Das bedeutet aber nicht nur mehr (möglicherweise auch unverständlichen) Code, denn einen solchen muss man auch irgendwann wieder deregistrieren, wenn man das Panel sauber verabschieden will. Wo soll das den stattfinden? Bei "removeNotify()" oder gar "finalize()"?
Aber Listener sind nun überhaupt das Thema... z.B. InputListener auf den Content... wie soll das jetzt gehen? Naja, wenn ich dafür keine Lösung finde, wirds Zeit für einen neuen Thread, das muss nicht hier diskutiert werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B viele JPanels auf JLayeredPane -> to SVG? AWT, Swing, JavaFX & SWT 15
S Swing JLayeredPane Anordnung funktioniert nicht AWT, Swing, JavaFX & SWT 2
E Swing JPanel in JLayeredPane animieren AWT, Swing, JavaFX & SWT 7
R Swing Animation mit JLayeredPane? AWT, Swing, JavaFX & SWT 8
T JLayeredPane in JScrollBox AWT, Swing, JavaFX & SWT 2
GUI-Programmer Swing Problem mit JLayeredPane AWT, Swing, JavaFX & SWT 2
M JLayeredPane mit JPanel im Vordergrund, Hintergrundelemente sperren AWT, Swing, JavaFX & SWT 7
G JPanel in JLayeredPane AWT, Swing, JavaFX & SWT 8
D Probleme mit MouseWheelListener und JLayeredPane in Applet AWT, Swing, JavaFX & SWT 2
G Swing JLayeredPane Schach AWT, Swing, JavaFX & SWT 7
K JLayeredPane Elemente auf gleicher Position AWT, Swing, JavaFX & SWT 7
R JLayeredPane - JPanel mit variabler Form AWT, Swing, JavaFX & SWT 4
J Layer von JLayeredPane unsichtbar durchsichtig in den Hintergrund AWT, Swing, JavaFX & SWT 5
R JLayeredPane - Drag&Drop - mouseDragged AWT, Swing, JavaFX & SWT 6
J SWING Fenster mit mehreren JPanels (dank JLayeredPane) AWT, Swing, JavaFX & SWT 19
R Swing JLayeredPane - Wie JScrollPane einbauen? AWT, Swing, JavaFX & SWT 17
R Swing JLayeredPane - Drag&Drop Positionen vertauschen AWT, Swing, JavaFX & SWT 3
H Button auf Bild/ JLayeredPane in Jpanel AWT, Swing, JavaFX & SWT 15
G JLayeredPane moveToFront funktioniert nicht AWT, Swing, JavaFX & SWT 15
D jLayeredPane Ebenen mit dynamischer Größe AWT, Swing, JavaFX & SWT 2
B Ärger mit JLayeredPane :-( AWT, Swing, JavaFX & SWT 5
S JLayeredPane AWT, Swing, JavaFX & SWT 16
M JLayeredPane : Applet - Application AWT, Swing, JavaFX & SWT 4
V JLayeredPane wird nur 1x bezeichnet AWT, Swing, JavaFX & SWT 12
shiny_hair JLayeredPane - Wie funktioniert das mit den Layern? AWT, Swing, JavaFX & SWT 2
T JLayeredPane Problem - AWT und SWING Komponente AWT, Swing, JavaFX & SWT 6
M Scrollbare JLayeredPane AWT, Swing, JavaFX & SWT 2
A Beim Füllen von JList entsteht ein komisches Phänomen AWT, Swing, JavaFX & SWT 3
G Seltsames Phänomen beim starten meiner Applikation AWT, Swing, JavaFX & SWT 8

Ähnliche Java Themen

Neue Themen


Oben