Ärger mit JLayeredPane :-(

Status
Nicht offen für weitere Antworten.
B

Bernie

Gast
Hallo,
ich hänge derzeit fest mit JlayeredPane, und das bringt mich langsam zum verweiflen :'-(

in einem JLayeredPane (null Layout) habe ich 4 verschiedene Panels, die frei platzierbar sind

die Panels werden in einer Schleife dem LayeredPane hinzugefügt, und zwar so:

Code:
  int i = 1;

  for (Iterator iter = panels.iterator(); iter.hasNext();) {
      
      CustomPanel cP = (CustomPanel) iter.next();

      layeredPane.add(cP, new Integer(i++));
      cP.setBounds(...);     
    }


Nun habe ich 4 Panels die mit index (1,2,3,4) in den layeredpane (richtig) eingefügt worden sind.

Diese Panels haben nun ein JPopupMenu, für jedes dieser Panels soll es nun die Möglichkeit geben,
das aktuell selektierte "eine Ebene nach vorne", oder "eine ebene nach hinten" zu bringen.
im entsprechenden ActionListener versuche ich dies:

Code:
public void actionPerformed(ActionEvent e) {
     
      String source = ((JMenuItem)e.getSource()).getActionCommand();

      if(source.equals("eine ebene nach vorne")) {  

         //cP.getLayerPosition() gibt den Layer-index des selektierten Panels zurück (1,2,3,4)
        //setLayer(cP, 1, cP.getLayerPosition()) zB. führt nur zu teilweise richtigem, und für
        // mich nicht nachvollziebarem Verhalten
       // außerdem scheint moveToFront immer ein rücken in die oberste Ebene zu machen
	//was muss ich hier tun, damit das selektierte Panel "eine ebene" nach oben rückt ?
        setLayer(cP, cP.getLayerPosition(),cP.getLayerPosition());
        moveToFront(cP);      
      }          
      
}

Ich habe auch anderes in der setLayer Methode probiert, nichts führt zum Erfolg. Bitte, was mache ich hier falsch ?


Vielen Dank schonmal.

Beste Grüße

Bernie

[Edit by Beni: Codetags repariert, / und nicht \ verwenden!]
 
B

Bernie

Gast
hallo nochmal,
hier nun mal ein ausführbares Beispiel, das mein Problem zeigen soll:

Wenn ich nun z.B. das PopupMenu über dem Label mit layer index 2 aufrufe, und den eintrag "eine ebene nach vorne" auswähle, tauschen das weiße und das schwarze Jlabel quasi den platz und das weiße rückt eben über das schwarze, bleibt aber hinter dem grauen...usw

ich kapier das nicht mit den layern. ja, das sun beispiel kenne ich , und kann mir trotz stundenlangem anguckens bis dato nichts übertragen :'-((

Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;


public class LayeredPaneTest extends JLayeredPane {

	DragableLabel layerLabel;
	Color [] background = {Color.GREEN, Color.BLUE, Color.WHITE, Color.BLACK, Color.GRAY};
	JPopupMenu popup;
	JMenuItem moveOneBehind, moveOneBefore;

	public LayeredPaneTest() {		
		
		
		initPopupMenu();

		for(int i = 0;i<5;i++) {
		  layerLabel = new DragableLabel();		
		  layerLabel.setText("Label mit Layer Index " + i);
		  layerLabel.setBorder(new LineBorder(Color.BLACK));
          layerLabel.setBackground(background[i]);
		  layerLabel.setBounds(i+(i*100),i+(i*100),180,180);
		  
		  
		  this.add(layerLabel, new Integer(i));	  
			
		}	
		
		//ActionListener für PopupMenu,Layer index soll verändert werden
		moveOneBefore.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e){
				
				//??? 
				 setLayer(layerLabel,0,1);			    
//			     moveToFront(layerLabel);			      
			}			
		});		
	}
	
	public void initPopupMenu(){
		
		moveOneBehind = new JMenuItem("Eine Ebene nach hinten");	     
	    moveOneBefore = new JMenuItem("eine ebene nach vorne");
	    popup = new JPopupMenu();    
	    popup.add(moveOneBefore);    
	    popup.add(moveOneBehind);		
	}

	public static void main(String args []){
		
		JFrame f = new JFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setContentPane(new LayeredPaneTest());
		f.setSize(new Dimension(700,700));
	    f.setLocationRelativeTo(null);
	    f.setTitle("Layer Test :-(");
		f.setVisible(true);
	}
	
	/**
	 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	 * Code stammt teilweise von 
	 * [url]http://www.dpunkt.de/java/Programmieren_mit_Java/Oberflaechenprogrammierung/18.html[/url]
	 *
	 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	 */
	class DragableLabel extends JLabel implements MouseListener, MouseMotionListener {		
	
		 int startPoint = 0;
		 int originalLayer;
		 Point offsetPoint = null;

		 DragableLabel() {
			 
		   setHorizontalAlignment(SwingConstants.CENTER);	
		   setOpaque(true);	
		   startPoint += 20;	
		   setBounds(startPoint, startPoint, 50, 50);
		   addMouseListener(this);
		   addMouseMotionListener(this);
		 }
		 
		 public void mouseReleased(MouseEvent e){

			 if(e.getButton() == MouseEvent.BUTTON3) {
			     popup.show(DragableLabel.this,e.getX(),e.getY());
			 }

		 }
		     
		 public void mousePressed(MouseEvent e) {	
			offsetPoint = new Point (e.getPoint ().x,e.getPoint ().y);			
		   
		 }
			   
		 public void mouseDragged(MouseEvent e){
		   if (offsetPoint != null)
			 setLocation (getX () + (e.getX () - offsetPoint.x),getY () + (e.getY () - offsetPoint.y));
			
		 }

			public void mouseClicked(MouseEvent arg0) {}

			public void mouseEntered(MouseEvent arg0) {}
			

			public void mouseExited(MouseEvent arg0) {}
			

			public void mouseMoved(MouseEvent arg0) {}
	 
	
		
	}
	
	
}
 

Marco13

Top Contributor
Du hast da bei der Zeile mit den Fragezeichen
setLayer(layerLabel,0,1);
aufgerufen. Das 'layerLabel' ist in dem Moment aber immer das LETZTE layerLabel, das in der Schleife erzeugt wurde. Eigentlich brauchst du dort aber das layerLabel, von dem das PopupMenu aufgerufen wurde. Das würde mit
setLayer(popup.getInvoker(),0,1);
gehen. Aber es bringt ja nichts, dort immer Layer '0' zu setzen. Spätestens nachdem alle Labels einmal nach oben bewegt wurden, liegen sie alle auf Layer 0, und dann geht (abgesehen von der 'position') garnichts mehr.

Ich habe mal den Code so verändert, dass die Labels anzeigen, auf welcher Layer (und Position) sie liegen. Du kannst dir ja mal ansehen, was bei deiner Ursprünglichen Lösung dort genau passiert ist. Aber auf so eine Idee solltest du auch kommen können: Irgendwelche Debug-Ausgaben einzubauen! Wenn du z.B. nur eine Zeile

System.out.println("Setze layer 0 für Label mit farbe "+layerLabel.getBackground());
setLayer(layerLabel,0,1);

eingebaut hättest, hättest du schon gesehen, dass das immer das gleiche (falsche) ist!

Aber ich muß zugeben, dass dieses Layer-Handling dann doch etwas ekliger war, als ich zuerst vermutet hatte. Darum habe ich mal zwei praktische, "semi-spohisticated"-Hilfs-Methoden gebastelt, mit denen man eine komplette Layer nach oben- bzw. unten bewegen kann. Das "vernünftig" zu machen (z.B. so, dass die Positionen immer stimmen, und man nicht die Layer beliebig erhöhen oder verringern kann) war ein bißchen fummelig, scheint aber jetzt so weit zu funktionieren...

Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.*;
import java.util.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;


public class LayeredPaneTest extends JLayeredPane {

   ArrayList<DragableLabel> labels = new ArrayList<DragableLabel>();
   DragableLabel layerLabel;
   Color [] background = {Color.GREEN, Color.BLUE, Color.WHITE, Color.BLACK, Color.GRAY};
   JPopupMenu popup;
   JMenuItem moveOneBehind, moveOneBefore;

   public LayeredPaneTest() {

      initPopupMenu();

      layerLabel = new DragableLabel();
      labels.add(layerLabel);
      layerLabel.setText("");
      layerLabel.setBorder(new LineBorder(Color.BLACK));
      layerLabel.setBackground(Color.MAGENTA);
      layerLabel.setBounds(2+(2*100),2+(2*100),210,210);
      add(layerLabel, new Integer(2));

      for(int i = 0;i<5;i++) {
        layerLabel = new DragableLabel();
        labels.add(layerLabel);
        layerLabel.setText("");
        layerLabel.setBorder(new LineBorder(Color.BLACK));
        layerLabel.setBackground(background[i]);
        layerLabel.setBounds(i+(i*100),i+(i*100),180,180);
        this.add(layerLabel, new Integer(i));
        updateLabels();
      }

      //ActionListener für PopupMenu,Layer index soll verändert werden
      moveOneBefore.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e){

            //setLayer(layerLabel,0,1);
            moveUp(popup.getInvoker());

            updateLabels();
         }
      });

      moveOneBehind.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e){
            moveDown(popup.getInvoker());
            updateLabels();
         }
      });
   }

   private void updateLabels()
   {
       for (int i=0; i<labels.size(); i++)
       {
           int layer = getLayer(labels.get(i));
           int pos = getPosition(labels.get(i));
           labels.get(i).setText("Layer: "+layer+" pos "+pos);
       }
   }




   //---------------------------------------------------------- Marco13 --->
   private void moveDown(Component component)
   {
       int currentLayer = getLayer(component);
       Component currentLayerComponents[] = getComponentsInLayer(currentLayer);
       int minLayer = lowestLayer();
       int nextLayer = currentLayer-1;
       while (nextLayer>=minLayer)
       {
           Component nextLayerComponents[] = getComponentsInLayer(nextLayer);
           if (nextLayerComponents.length != 0)
           {
               changeLayer(nextLayerComponents, currentLayer-nextLayer);
               break;
           }
           nextLayer--;
       }
       if (nextLayer >= minLayer)
       {
           changeLayer(currentLayerComponents, -1);
       }
   }

   private void moveUp(Component component)
   {
       int currentLayer = getLayer(component);
       Component currentLayerComponents[] = getComponentsInLayer(currentLayer);
       int maxLayer = highestLayer();
       int nextLayer = currentLayer+1;
       while (nextLayer<=maxLayer)
       {
           Component nextLayerComponents[] = getComponentsInLayer(nextLayer);
           if (nextLayerComponents.length != 0)
           {
               changeLayer(nextLayerComponents, currentLayer-nextLayer);
               break;
           }
           nextLayer++;
       }
       if (nextLayer <= maxLayer)
       {
           changeLayer(currentLayerComponents, 1);
       }
   }

    private void changeLayer(Component components[], int layerDelta)
    {
        int positions[] = new int[components.length];
        for (int i=0; i<components.length; i++)
        {
            positions[i] = getPosition(components[i]);
        }
        for (int i=0; i<components.length; i++)
        {
            setLayer(components[i], getLayer(components[i])+layerDelta);
        }
        for (int i=0; i<components.length; i++)
        {
            setPosition(components[i], positions[i]);
        }
    }
   //---------------------------------------------------------- Marco13 <---













   public void initPopupMenu(){

      moveOneBehind = new JMenuItem("Eine Ebene nach hinten");
       moveOneBefore = new JMenuItem("eine ebene nach vorne");
       popup = new JPopupMenu();
       popup.add(moveOneBefore);
       popup.add(moveOneBehind);
   }

   public static void main(String args []){

      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setContentPane(new LayeredPaneTest());
      f.setSize(new Dimension(700,700));
       f.setLocationRelativeTo(null);
       f.setTitle("Layer Test :-)");
      f.setVisible(true);
   }

   /**
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    * Code stammt teilweise von
    * [url]http://www.dpunkt.de/java/Programmieren_mit_Java/Oberflaechenprogrammierung/18.html[/url]
    *
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */
   class DragableLabel extends JLabel implements MouseListener, MouseMotionListener {

       int startPoint = 0;
       int originalLayer;
       Point offsetPoint = null;

       DragableLabel() {

         setHorizontalAlignment(SwingConstants.CENTER);
         setOpaque(true);
         startPoint += 20;
         setBounds(startPoint, startPoint, 50, 50);
         addMouseListener(this);
         addMouseMotionListener(this);
       }

       public void mouseReleased(MouseEvent e){

          if(e.getButton() == MouseEvent.BUTTON3) {
              popup.show(DragableLabel.this,e.getX(),e.getY());
          }

       }

       public void mousePressed(MouseEvent e) {
         offsetPoint = new Point (e.getPoint ().x,e.getPoint ().y);

       }

       public void mouseDragged(MouseEvent e){
         if (offsetPoint != null)
          setLocation (getX () + (e.getX () - offsetPoint.x),getY () + (e.getY () - offsetPoint.y));

       }

         public void mouseClicked(MouseEvent arg0) {}

         public void mouseEntered(MouseEvent arg0) {}


         public void mouseExited(MouseEvent arg0) {}


         public void mouseMoved(MouseEvent arg0) {}



   }


}
 
B

Bernie

Gast
Oh mann...

ich glaube so langsam aber sicher raff ich das. Dachte mir schon, dass man das etwas weiter "ausprogrammieren" muss, um dieses Verhalten zu erreichen. Diese Sache mit Layer Index und Layerposition hat mich auch total verwirrt. Konsolen Prints hab ich etliche gemacht, aber manchmal sollte man halt einfach aufhören, wenn man merkt es geht gar nichts mehr.
Dennoch, ich danke dir natürlich vielmals für deine Mühen.
Kleine Spende gefällig ?

Beste Grüße
 
B

Bernie

Gast
Oh mann...

ich glaube so langsam aber sicher raff ich das. Dachte mir schon, dass man das etwas weiter "ausprogrammieren" muss, um dieses Verhalten zu erreichen. Diese Sache mit Layer Index und Layerposition hat mich auch total verwirrt. Konsolen Prints hab ich etliche gemacht, aber manchmal sollte man halt einfach aufhören, wenn man merkt es geht gar nichts mehr.
Wie auch immer, ich danke dir natürlich vielmals für deine Mühen.
Kleine Spende gefällig ?

Beste Grüße
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Developer_X Swing Ärger mit der JCombobox AWT, Swing, JavaFX & SWT 2
E Ärger mit ScrollPane, JTable und der Resize-Einstellung AWT, Swing, JavaFX & SWT 2
B viele JPanels auf JLayeredPane -> to SVG? AWT, Swing, JavaFX & SWT 15
S Swing JLayeredPane Anordnung funktioniert nicht AWT, Swing, JavaFX & SWT 2
S Swing JLayeredPane "Phänomen"? AWT, Swing, JavaFX & SWT 7
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
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

Ähnliche Java Themen

Neue Themen


Oben