DesktopPane mit GridLayout ohne, dass Fenster springen

tamtam

Mitglied
Hallo,

ich baue gerade eine Oberfläche mit einem "scrollable" Desktop und mehreren Fenstern. Diese werden mit Hilfe von dem GridLayout angeordnet. Das funktioniert auch alles sehr gut. Die Fenster werden dank eines CustomDesktopmanager alle gleichzeitig vergrößert usw. Jedoch, wenn ich in ein Fenster klicke und dieses den Fokus bekommt, dann springt es immer nach oben links. Das will ich vermeiden. Im Moment hab ich dies versucht in dem ich beim klick das Layout auf null setzte. Damit verliere ich aber die Möglichkeit zu scrollen.

Hat jemand einen Rat?


Hier ein KSKB:

Java:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.DefaultDesktopManager;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;


public class GridDesktop {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       JFrame frame = new JFrame("");
       frame.setSize(new Dimension(800, 600));
       BorderLayout bl= new BorderLayout();
       JDesktopPane jd= new JDesktopPane();
       JScrollPane jsp= new JScrollPane(jd);
        CustomDesktopManager cdm = new CustomDesktopManager();
      
       jd.setDesktopManager(cdm);
       
       frame.add(jsp, bl.CENTER);
       JInternalFrame jif = null;
       for(int i=0; i<20; i++){
           jif = new JInternalFrame("jif"+i, true, false, true, true);
           jif.setSize(new Dimension(50,30));
           jd.add(jif);
           jif.show();
       }
       cdm.setGrid(jif);
       frame.setVisible(true);
       
    }
}



import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import javax.swing.DefaultDesktopManager;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;


public class CustomDesktopManager extends DefaultDesktopManager {

    Dimension oldSize, olderSize;
    Point oldPoint;
    Component help;
    Point beforeDrag;

    @Override
    public void iconifyFrame(JInternalFrame f) {
        super.iconifyFrame(f);
        f.setVisible(false);
    }

    @Override
    public void deiconifyFrame(JInternalFrame f) {
        super.deiconifyFrame(f);
        f.setVisible(true);
    }

    @Override
    public void beginResizingFrame(JComponent f, int direction) {

        Container parent = f.getParent();
        parent.setLayout(null);
        oldSize = f.getSize();
        olderSize = f.getSize();
    }

    @Override
    public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
        //super.resizeFrame(f, newX, newY, newWidth, newHeight);
        Dimension desktopSize = f.getParent().getSize();

        int i = 0;
        for (Component c : f.getParent().getComponents()) {
            c.setSize(newWidth, newHeight);
            Point location = c.getLocation();
            // c.setLocation(c.getLocation().x+(newWidth-oldSize.width), c.getLocation().y+(newHeight-oldSize.height));
            i++;

            //oldSize=c.getSize();


            if (c.getLocation().x >= oldSize.width || c.getLocation().y >= oldSize.height /*&& c!=f*/) {

                //System.out.println("oldsize "+oldSize+" location "+c.getLocation());
                if (c.getLocation().y >= oldSize.height) {

                    double help_y = c.getY() / oldSize.height;
                    int faktor_y = (int) Math.ceil(help_y);
                    System.out.println("faltor y" + faktor_y);

                    c.setLocation(c.getLocation().x, c.getLocation().y + faktor_y * (c.getHeight() - oldSize.height));

                }
                if (c.getLocation().x >= oldSize.width) {
                    double help_x = c.getX() / oldSize.width;
                    int faktor_x = (int) Math.ceil(help_x);
                    System.out.println("faltor y" + faktor_x);
                    c.setLocation(c.getLocation().x + faktor_x * (c.getWidth() - oldSize.width), c.getLocation().y);


                }

            }

        }

        oldSize = f.getSize();
    }

    @Override
    public void endResizingFrame(JComponent f) {


        setGrid(f);


        //f.getParent().setSize(f.getParent().getLayout().minimumLayoutSize(f.getParent()));

    }

    @Override
    public void beginDraggingFrame(JComponent f) {
        f.getParent().setLayout(null);
        System.out.println("Parent SIze  " + f.getParent().getParent().getSize());
        f.getParent().setSize(new Dimension(f.getParent().getWidth(), f.getHeight() * 50));
        beforeDrag = f.getLocation();


    }

    @Override
    public void endDraggingFrame(JComponent f) {
        if (!beforeDrag.equals(f.getLocation(oldPoint))) {
            setGrid(f);
        }
        System.out.println("end dragging");
        super.endDraggingFrame(f);


    }

    @Override
    public void maximizeFrame(JInternalFrame f) {
        super.maximizeFrame(f);
        f.getParent().setLayout(null);
    }

    public void setGrid(JComponent f) {
        Dimension size = f.getParent().getParent().getParent().getParent().getParent().getSize();

        int x_count = size.width / f.getWidth();
        if (x_count == 0) {
            x_count = 1;
        }
        int y_count = f.getParent().getComponents().length / x_count;

        System.out.println("x " + x_count + " y " + y_count + " from parant widht" + size.width + " f widht " + f.getWidth());

        f.setPreferredSize(oldSize);
        Component[] components = f.getParent().getComponents();

        f.getParent().setLayout(new GridLayout(y_count, x_count));
        for (Component c : components) {
            c.setPreferredSize(new Dimension(50, f.getHeight()));
        }


    }
}

Danke schonmal!
 
Zuletzt bearbeitet:

bERt0r

Top Contributor
Nimm das MigLayout:
Java:
import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

import net.miginfocom.swing.MigLayout;


public class GridDesktop extends JFrame
{
	
	private JPanel contentPane;
	private JScrollPane scrollPane;
	private JDesktopPane desktopPane;
	private JInternalFrame internalFrame;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					try
					{
						GridDesktop frame = new GridDesktop();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public GridDesktop()
	{
		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);
		
		scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);
		
		desktopPane = new JDesktopPane();
		scrollPane.setViewportView(desktopPane);
		desktopPane.setLayout(new MigLayout("", "[grow,fill][grow,fill][grow,fill][grow,fill][grow,fill]", "[grow,fill][grow,fill][grow,fill][grow,fill]"));
		
		for(int i=0;i<5;i++)
		{
			for(int j=0;j<4;j++)
			{
				JInternalFrame iFrame=new JInternalFrame();
				iFrame.getContentPane().add(new JLabel(String.valueOf(5*j+i)));
				desktopPane.add(iFrame,"cell "+i+" "+j);
				iFrame.setVisible(true);
			}
		}
	}
	
}
 

tamtam

Mitglied
danke, ich schau es mir mal an. Muss mal gucken, ob ich die anderen Funktionen, wie z.B. das Vergrößern und das eigenständige Layouten damit hinbekomme.
 

tamtam

Mitglied
es könnte funktionieren, jedoch versteh ich folgendes nicht:

die Funktion endResizing wird zum Teil sehr häufig aufgerufen, wodurch dann das Programm in die knie geht. woran liegt das? das war vorher mit dem GridLayout nicht so.

Hier zum ausprobieren:


Java:
package griddesktop;

import java.awt.BorderLayout;
import java.awt.EventQueue;
 
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
 
import net.miginfocom.swing.MigLayout;
 
public class GridDesktop1 extends JFrame
{
    
    private JPanel contentPane;
    private JScrollPane scrollPane;
    private JDesktopPane desktopPane;
    private JInternalFrame internalFrame;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    try
                    {
                        GridDesktop1 frame = new GridDesktop1();
                        
                        frame.setVisible(true);
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            });
    }
    
    /**
     * Create the frame.
     */
    public GridDesktop1()
    {
        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);
        
        scrollPane = new JScrollPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);
        
        desktopPane = new JDesktopPane();
        scrollPane.setViewportView(desktopPane);
         MigLayout mL= new MigLayout();
        mL.setColumnConstraints("[grow,fill][grow,fill][grow,fill][grow,fill][grow,fill]");
        mL.setRowConstraints("[grow,fill][grow,fill][grow,fill][grow,fill]");
         desktopPane.setLayout(mL);
        desktopPane.setDesktopManager(new CustomDesktopManager());
        
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<4;j++)
            {
                JInternalFrame iFrame=new JInternalFrame();
                iFrame.getContentPane().add(new JLabel(String.valueOf(5*j+i)));
                iFrame.setResizable(true);
                desktopPane.add(iFrame,"cell "+i+" "+j);
                iFrame.setVisible(true);
            }
        }
    }
    
}


import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.DefaultDesktopManager;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import net.miginfocom.swing.MigLayout;


public class CustomDesktopManager extends DefaultDesktopManager {

    Dimension oldSize, olderSize;
    Point oldPoint;
    Component help;
    Point beforeDrag;
    int count=0;

    @Override
    public void iconifyFrame(JInternalFrame f) {
        super.iconifyFrame(f);
        f.setVisible(false);
    }

    @Override
    public void deiconifyFrame(JInternalFrame f) {
        super.deiconifyFrame(f);
        f.setVisible(true);
    }

    @Override
    public void beginResizingFrame(JComponent f, int direction) {

        Container parent = f.getParent();
        parent.setLayout(null);
        oldSize = f.getSize();
        olderSize = f.getSize();
    }

    @Override
    public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
        //super.resizeFrame(f, newX, newY, newWidth, newHeight);
        Dimension desktopSize = f.getParent().getSize();

        int i = 0;
        for (Component c : f.getParent().getComponents()) {
            c.setSize(newWidth, newHeight);
            Point location = c.getLocation();
            // c.setLocation(c.getLocation().x+(newWidth-oldSize.width), c.getLocation().y+(newHeight-oldSize.height));
            i++;

            //oldSize=c.getSize();


            if (c.getLocation().x >= oldSize.width || c.getLocation().y >= oldSize.height /*&& c!=f*/) {

                //System.out.println("oldsize "+oldSize+" location "+c.getLocation());
                if (c.getLocation().y >= oldSize.height) {

                    double help_y = c.getY() / oldSize.height;
                    int faktor_y = (int) Math.ceil(help_y);
                    System.out.println("faltor y" + faktor_y);

                    c.setLocation(c.getLocation().x, c.getLocation().y + faktor_y * (c.getHeight() - oldSize.height));

                }
                if (c.getLocation().x >= oldSize.width) {
                    double help_x = c.getX() / oldSize.width;
                    int faktor_x = (int) Math.ceil(help_x);
                    System.out.println("faltor y" + faktor_x);
                    c.setLocation(c.getLocation().x + faktor_x * (c.getWidth() - oldSize.width), c.getLocation().y);


                }

            }

        }

        oldSize = f.getSize();
    }

    @Override
    public void endResizingFrame(JComponent f) {


        setGrid(f);


        //f.getParent().setSize(f.getParent().getLayout().minimumLayoutSize(f.getParent()));

    }

    @Override
    public void beginDraggingFrame(JComponent f) {
        //f.getParent().setLayout(null);
        System.out.println("Parent SIze  " + f.getParent().getParent().getSize());
        f.getParent().setSize(new Dimension(f.getParent().getWidth(), f.getHeight() * 50));
        beforeDrag = f.getLocation();


    }

    @Override
    public void endDraggingFrame(JComponent f) {
        if (!beforeDrag.equals(f.getLocation(oldPoint))) {
            setGrid(f);
        }
        System.out.println("end dragging");
        super.endDraggingFrame(f);


    }

    @Override
    public void maximizeFrame(JInternalFrame f) {
        super.maximizeFrame(f);
        f.getParent().setLayout(null);
    }

    public void setGrid(JComponent f) {
       
        
        Dimension size = f.getParent().getParent().getParent().getParent().getParent().getSize();
        System.out.println("----- "+count++);
        int x_count = size.width / f.getWidth();
        if (x_count == 0) {
            x_count = 1;
        }
        int y_count = f.getParent().getComponents().length / x_count;

        System.out.println("x " + x_count + " y " + y_count + " from parant widht" + size.width + " f widht " + f.getWidth());

        f.setPreferredSize(oldSize);
        Component[] components = f.getParent().getComponents();

        
        MigLayout mL= new MigLayout();
        f.getParent().setLayout(mL);
       
        StringBuilder csB= new StringBuilder();
        for(int i=0; i<x_count;i++){
            csB.append(" [grow,fill]");
            
        }
       // System.out.println("Colum: "+csB.toString());
        mL.setColumnConstraints(csB.toString());
        StringBuilder rsB= new StringBuilder();
        
         for(int i=0; i<y_count;i++){
            rsB.append(" [grow,fill]");
            
        }
       //  System.out.println("Row: "+rsB.toString());
        mL.setRowConstraints(rsB.toString());
         int k=0;
        for(int i=0;i<x_count;i++)
        {
            for(int j=0;j<y_count;j++)
            {
                
               
                f.getParent().add(components[k++],"cell "+i+" "+j);
               
            }
        }


    }
}
 

bERt0r

Top Contributor
Naja, die Methode sollte jedes mal aufgerufen werden, wenn ein JInternalFrame fertigresized ist. In dieser Methode ein neues Layout zu erstellen ist eventuell nicht optimal und löst wohl gleich den nächsten resize Vorgang aus. Vertragen sich Desktopmanager und Layoutmanager überhaupt?

DefaultDesktopManager (Java Platform SE 7 )
Die Javadoc sagt:
JInternalFrames that are not children of a JDesktop will use this component to handle their desktop-like actions

Bzgl. endResizingFrame
This method signals the end of the resize session. Any state maintained by the DesktopManager can be removed here. Normally f will be a JInternalFrame.

Und nochwas: nimm dein setLayout(null) raus.
 

tamtam

Mitglied
irgendwie muss das ja gehen... :-/
Ich hab schon gelesen null Layout is evil, aber ist das nicht standardmäßig bei jDesktopPanes?
 
Zuletzt bearbeitet:

bERt0r

Top Contributor
Ja, aber dazu benutzt du ja den DesktopManager... Wenn du aber beides haben willst solltest du nicht dauernd das Layout neu setzen.
Wenn du das mit null layout machen willst, dann kannst du dir auch gleich einen eigenen Layoutmanager schreiben, der dir wie das GridLayout die Frames ausrichtet. Du musst dabei darauf achten, die Componenten beim add in eine Collection zu packen und beim layout dann in der Reihenfolge der Collection,nicht in der wie container.getComponents sie dir gibt, zu layouten. Das GridLayout macht das nämlich so und anscheinend ändert sich die Reihenfolge da.
 
Zuletzt bearbeitet:

bERt0r

Top Contributor
Schwer zu sagen, du machst ja irgendwelche Layout/Größenberechnungen in deinem DesktopManager (da hab ich nicht ganz durchgeblickt). Hängt auch davon ab was du genau erreichen willst.
 

tamtam

Mitglied
:) ich möchte zu Anfang ein Grid haben, quasi als überblick(da ist ein Diagramm in jedem Fenster), und wenn man so ein Frame vergrößert udn verkleinert soll er das so anordnen, dass die Breite des Fensters so bleibt und der Rest dann nach unten angehängt wird. Also die Spaltenanzahl richtet sich danach wie viele Fenster reinpassen.
oha, ich hoffe das war verständlich. :p kann man aber in dem Prog im ersten Post von mir ausprobieren.



Ich habe eben gerade mal versucht das Gridlayout so zu ändern wie du sagtest, aber irgendwie wird nie, die bei denen schon leere Funktion, addComponent aufgerufen :-/
 

tamtam

Mitglied
oh sorry, hab mich verschrieben. Die meinte ich. Die wird nicht aufgerufen.
hab den gesamten quellcode mit copy / paste aus dem gridlayout geklaut.
 

bERt0r

Top Contributor
Du musst beim adden einen String mit übergeben. Statt copy/paste würde es ein extends GridLayout oder eine annonyme Klasse auch tun...
Java:
new GridLayout()
{
@Override
public void addLayoutComponent(...
}
 

tamtam

Mitglied
So funktioniert es auf jeden fall! Das Umschreiben des Gridlayouts mit eigener ComponentList hat zum Erfolg geführt.

Danke für die Hilfe!
 

Ähnliche Java Themen

Neue Themen


Oben