Swing maximale quadratische Größe

Dieses Thema Swing - maximale quadratische Größe im Forum "AWT, Swing, JavaFX & SWT" wurde erstellt von banshee, 16. Okt. 2009.

Status des Themas:
Es sind keine weiteren Antworten möglich.

Thema: maximale quadratische Größe Hallo, wenn ich eine Komponente in ein GridbagLayout eingeflechted habe, wie kann ich es erreichen, dass sie...

  1. Hallo,

    wenn ich eine Komponente in ein GridbagLayout eingeflechted habe, wie kann ich es erreichen, dass sie immer quadratisch, aber eben maximale Größe auf dem Anzeigebereich hat? Einfach mit setPreferredSize einen fixen Wert einzutragen bringt da ja nichts, weil es auf Monitoren anderer Größe dann wieder komplett anders aussieht.
    Meine theoretische Lösung wäre ja folgende: Komponente erstellen, Defaultsize berechnen lassen, an der längeren Achse so verkleinern, dass sie quadratisch ist. Allerdings scheint das berechnen der Defaultsize ja einer der letzten Schritte vor dem Anzeigen zu sein (auch wenn ich mich mit den internen Mechanismen jetzt nicht 100%ig auskenne)
     
  2. Vielleicht hilft dir das Java-Tutorial weiter. Hier klicken --> (Klick)
  3. Hm ... ich hatte mal ein AspectLayout geschrieben, das eine einzelne Component mit einem bestimmten Seitenverhältnis (bei dir: 1.0) anzeigt - kann ich mal posten, wenn ich wieder am ensprechenden Rechner sitze...
     
  4. ja, das wäre prima. Ich hab mir die JGoodies Forms mal angeschaut und finde das auch für die Zukunft sehr interessant, aber das jetzt noch irgendwie in das Projekt zu quetschen, obwohl der Rest schon mit anderen Layout-Managern gemacht ist, sieht dann am Ende auch nicht schön aus.
    Außerdem hab ich es bis jetzt noch nicht raus, wie ich da eine Komponente quadratisch mache. Muss ich die columns dann in dlu so festlegen, dass sie quadratisch sind und die Komponente immer mitstauchen?

    Ich habe hier mal einen screenshot von dem Panel gemacht, wo ich das brauche:

    [​IMG]

    Hier sollten also das große Panel oben links und die 8 kleinen unten immer quadratisch sein. Ich sehe hier vor allen Dingen einen Konflikt mit dem rowspan aufkommen. Wenn ich nämlich einstelle, dass das obere Panel über den 7 kleinen liegt, wird es doch automatisch immer verlängert, auch wenn es schon nach 5 aufhören müsste, um quadratisch zu bleiben?!
     
  5. Aufgrund seiner Trivialität hiermit ins public domain entlassen:

    Code (Java):

    import java.awt.*;

    /**
     * An implementation of the LayoutManager interface, for containers
     * that contain a single component that should be as large as
     * possible under the constraint that a given aspect ratio
     * (width/height) is maintained.
     */

    public class AspectLayout implements LayoutManager
    {
        /**
         * The current aspect that should be maintained
         */

        private float aspect = 1.0f;
       
        /**
         * The alignment in horizontal or vertical direction.
         * If there is extra space in either direction, then
         * the component will aligned according to this value
         */

        private float alignment = 0.5f;
       
        /**
         * Creates a new AspectLayout for the given aspect
         *
         * @param aspect The aspect for the contained component
         */

        public AspectLayout(float aspect)
        {
            this.aspect = aspect;
        }

        /**
         * Creates a new AspectLayout for the given aspect and
         * alignment
         *
         * @param aspect The aspect for the contained component
         * @param alignment The alignment for the contained component
         */

        public AspectLayout(float aspect, float alignment)
        {
            this.aspect = aspect;
            this.alignment = alignment;
        }
       
        /**
         * {@inheritDoc}
         */

        public void addLayoutComponent(String name, Component comp)
        {
        }

        /**
         * {@inheritDoc}
         */

        public void layoutContainer(Container parent)
        {
            synchronized (parent.getTreeLock())
            {
                if (parent.getComponentCount() == 0)
                {
                    return;
                }
                Insets insets = parent.getInsets();
                int maxWidth = parent.getWidth() - (insets.left + insets.right);
                int maxHeight = parent.getHeight() - (insets.top + insets.bottom);
               
                int maxAspectW = (int)(maxHeight * aspect);
                int maxAspectH = (int)(maxWidth / aspect);
               
                //System.out.println("maxAspectW "+maxAspectW+" "+maxAspectH+" maxAspectH");
               
                Component component = parent.getComponent(0);
               
                if (maxAspectW > maxWidth)
                {
                    int w = maxWidth;
                    int h = maxAspectH;
                    int space = maxHeight - h;
                    int offset = (int)(alignment * space);
                    component.setBounds(insets.left, insets.top + offset, w, h);
                }
                else
                {
                    int w = maxAspectW;
                    int h = maxHeight;
                    int space = maxWidth - w;
                    int offset = (int)(alignment * space);
                    component.setBounds(insets.left+offset, insets.top, w, h);
                }
            }
        }

        /**
         * {@inheritDoc}
         */

        public Dimension minimumLayoutSize(Container parent)
        {
            if (parent.getComponentCount() == 0)
            {
                return new Dimension(0,0);
            }
            Component component = parent.getComponent(0);
            return component.getMinimumSize();
        }

        /**
         * {@inheritDoc}
         */

        public Dimension preferredLayoutSize(Container parent)
        {
            if (parent.getComponentCount() == 0)
            {
                return new Dimension(0,0);
            }
            Component component = parent.getComponent(0);
            return component.getPreferredSize();
        }

        /**
         * {@inheritDoc}
         */

        public void removeLayoutComponent(Component comp)
        {
        }

        /**
         * {@inheritDoc}
         */

        @Override
        public String toString()
        {
            return getClass().getName() + "[aspect=" + aspect + "]";
        }
       
        /*/
        public static void main(String args[])
        {
            javax.swing.JFrame f = new javax.swing.JFrame();
            f.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
            f.getContentPane().setLayout(new AspectLayout(2.0f));
            javax.swing.JPanel p = new javax.swing.JPanel()
            {
                public void paintComponent(Graphics g)
                {
                    super.paintComponent(g);
                    g.setColor(Color.BLACK);
                    g.drawString(""+getSize(), 10, 20);
                }
            };
            p.setPreferredSize(new Dimension(700,200));
            p.setBackground(Color.RED);
            f.getContentPane().add(p);
            f.pack();
            f.setVisible(true);
        }
        //*/

       
    }
     
     
  6. Noch als Nachtrag: Ich hatte das verwendet, um ein Spielfeld mit einem bestimmten Seitenverhältnis darzustellen. Bei dir wäre dann im oberen linken Panel das AspectLayout, und IN dem Panel dann der eigentliche Inhalt, der immer Quadratisch sein soll. Dass das bei der Anforderung, dass bestimmte Comonents immer Quadratisch sein sollen, zu Widersrpüchen kommen kann, ist klar, deswegen legt das AspectLayout immer nur EINE Component in ein (ansonsten leeres) Panel, und läßt ggf. links&rechts bzw. oben&unten ein bißchen Platz...
     
  7. Vielen Dank, funktioniert super. Ich habe allerdings das Gefühl, dass mir Swing einfach den nächst größeren Stein in die Bahn wirft, sobald ein Problem gelöst ist. Schaut euch zu folgendem unbedingt nochmal den Screenshot an.

    Ich zeichne also eine Matrix mit Java2D oben links. Wenn es gut läuft, passt sie genau ins Fenster und alle sind glücklich. Wenn es schlecht läuft, ist die Matrix allerdings so riesig, dass nur ein Teil ins Bild passt und der Rest per Scrollbalken angezeigt wird.
    Das wird zum Problem, wenn ich danach eine Matrix lade, die normalerweise wieder ins Bild passen würde. Ich schaue mir nämlich zuerst die Initialwerte des Panels an, versuche die Matrix dann erst so zu zeichnen, dass sie genau reinpasst und schalte eben die Scrollbalken ein, falls die Größe einer Zeller kleiner als x Pixel ist. Wenn ich die Größe dann durch eine Riesenmatrix aber verändert habe, zeichnet er auch z.B. eine 3x3 Matrix in dieses Riesenpanel mit den Scrollbalken. Ich bräuchte also einen Befehl, der das JPanel in seinen Ursprungszustand zurückversetzt, damit ich die wirklichen Initialwerte (= als das Panel noch komplett leer war) bekomme. Gibt es sowas?
     
  8. ???:L Häh? Man kann z.B. bei einer Scollbar die "policy" setzen, wann Scrollbalken angezeugt werden... ?! Poste notfalls mal ein Stück code...
     
  9. Ja ich benutze einfach das Std-Dingens mit VERT/HORZ_AS_NEEDED. Aber folgendermaßen:

    Code (Java):
    private void initPaint() {
            double minLen = (getWidth() < getHeight()) ? getWidth() : getHeight();
            rectSize = (float)minLen / colCount;

            if(rectSize < 10.0f)
                rectSize = 10.0f;

            Font font = new Font("Dialog", Font.PLAIN, 10);
            setFont(font);
        }
    Das ist der Code, der immer dann ausgeführt wird, wenn man eine neue Matrix zeichnet. Zeichne ich also eine Riesenmatrix, wird die Größe des JPanels verändert und wenn ich die Funktion oben das nächste mal aufrufe, rechnet sie eben mit der veränderten Größe weiter und er zeichnet auch kleine Matrizen in das Riesenpanel, was zur Folge hat, dass die Zellen riesig sind und trotzdem nur ein Teil sichtbar ist, obwohl die Matrix ganz in das Panel passen würde. Ich könnte natürlich einfach die Größe der ScrollPane abfragen, nur von der weiß das Panel, in dem die obere Funktion ist, nichts.

    Was ich übrigens auch festgestellt hab: Wenn die Matrix zu groß ist, verändere ich die Panelgröße einfach mit setPreferredSize(). Er zeigt dann auch Scrollbalken an, verschiebt aber trotzdem jedesmal das gesamte Layout.

    Erstellt wird das ganze einfach so:

    Code (Java):
    JScrollPane scrollPane = new JScrollPane(bigPanel);
                   
            layout.setConstraints(scrollPane, new GridBagConstraints(0, 0, 7, 1, 1, 4,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
    Und wenn ich das große Panel einfach direkt mal auf 600x600 setze, schiebt er die restlichen Komponenten einfach weg, obwohl die ScrollPane einfach Balken anzeigen sollte, anstatt ihre Größe zu ändern. Wie verhindere ich das?

    [​IMG]
     
  10. Zusammengefasst würde das jetzt etwa lauten: Wenn ich etwas mache und dann noch etwas ist das Layout nicht so, wie ich es will.

    Ein KSKB würde evtl. wirklich helfen...
     
  11. Das hätte ich auch schon längst gemacht. Das Problem ist zum einen nur, dass es in dem KSKB komischerweise so funktioniert, wie ich das will und für das andere Beispiel lässt sich das nicht so einfach machen, weil die Klasse sehr viele andere Komponenten benutzt.
    Mal sehen, ob ich nachher noch was basteln kann...
     
  12. Für das erste Problem ging es eigentlich doch recht einfach

    Code (Java):
    package test;

    import javax.swing.*;

    import java.awt.*;

    public class Test extends JPanel {
        private static final long   serialVersionUID    = 1L;
        private static final int    PANEL_COUNT         = 8;
        private JPanel              bigPanel            = new JPanel();
        private final JPanel[]      previewPanels       = new JPanel[PANEL_COUNT];

        public Test() {
            for(int i = 0; i < PANEL_COUNT; i++)
                previewPanels[i] = new JPanel();

            setLayout(new BorderLayout());

            JPanel left = createLeftSection();
            add(left, BorderLayout.CENTER);
        }

        private JPanel createLeftSection() {
            JPanel leftSec = new JPanel();
            GridBagLayout layout = new GridBagLayout();
            leftSec.setLayout(layout);

            JScrollPane scrollPane = new JScrollPane(bigPanel);

            layout.setConstraints(scrollPane, new GridBagConstraints(0, 0, 7, 1, 1, 4,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
            JPanel referenceBar = new JPanel();
            layout.setConstraints(referenceBar, new GridBagConstraints(7, 0, 1, 1, 1, 4,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
            leftSec.add(scrollPane);
            leftSec.add(referenceBar);

            for(int i = 0; i < PANEL_COUNT; i++) {
                layout.setConstraints(previewPanels[i], new GridBagConstraints(i, 1, 1, 1, 1, 1,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 0), 0, 0));
                leftSec.add(previewPanels[i]);
                previewPanels[i].setBorder(BorderFactory.createLineBorder(Color.black));
            }

            //bigPanel.setPreferredSize(new Dimension(600, 600));

            return leftSec;
        }

        public static void main(String[] args) {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setExtendedState(Frame.MAXIMIZED_BOTH);
            frame.add(new Test());
            frame.setVisible(true);
        }
    }
     
    Wenn man den Code, so wie er ist, startet, sieht man das Fenster also, wie es eigentlich immer aussehen soll. Wenn man dann die auskommentierte Zeile reinmacht, quetscht er die unteren Panels, obwohl das bigPanel in eine JScrollPane eingebettet ist, die für den Fall - das bigPanel wird größer als sein Anzeigebereich - mit Scrollbalken einspringen sollte. Es scheint also, also ob die ScrollPane ihre Größe aus irgendwelchen Gründen mitändert. Sie soll aber immer die Initialgröße beibehalten.
     
  13. Hm sorry - vielleicht hat jemand anderes Lust, sich durch GridBagConstraints zu wühlen und dir dein Wunschlayout zusammenzustellen.
     
  14. Höre ich da etwa Kritik an meinem Codestil oder kannst du den Manager nicht leiden? :D

    Ich dachte, das ist immernoch der beste der Std-Manager. Ich kann mir auch nicht wirklich vorstellen, dass es am layout liegt. Das ist ja zumindest initial so, wie ich es haben will. Die ScrollPane macht eben nur, was sie will.

    Oder hätte ich das kommentieren sollen? Ich dachte mit Ergebnisscreenshot und Javadoc ist das recht leicht zu lesen. Ich weiß nämlich nicht, was ich da noch aufschreiben soll, was man nicht sowieso schon mit einem Blick auf den Code erkennt (zumindest wenn man den Manager schonmal benutzt hat)
     
  15. Einerseits das Totally Gridbag – madbean andererseits ist mir immernocht nicht klar, was du eigentlich willst. Da unten sind ein paar Panels, in der Mitte ist ein Panel - BorderLayout.SOUTH und CENTER und was willst du weiter?
     
  16. okay, nochmal von vorne. Dass ich Matrizen zeichnen will, ist mittlerweile hoffentlich klar :D
    Die Hauptmatrix wird in dem großen Panel gezeichnet und kleinere Vorschaumatrizen in den kleinen Panels unten. Die Hauptmatrix versucht dabei immer zuerst sich in den zur Verfügung stehenden Platz zu zeichnen. Jetzt kann es aber vorkommen, dass eine Matrix zu groß ist (z.B. wenn man eine 1000x1000 Matrix in das 600x600 Panel zu zeichnen versucht). Dann soll sich aber trotzdem nichts am Layout ändern, sondern man soll die Matrix scrollen können.

    In dem Codestück habe ich also einfach mal simuliert, dass eine große Matrix angezeigt wird, indem ich das Panel, dass die ScrollPane "betrachtet" vergrößert habe und anstatt darauf mit Scrollbalken zu reagieren, wird das Layout gequetscht.

    Wahrscheinlich liegt das am GridBagLayout. Ich hab aber keine Ahnung, wie ich so ein Layout ohne Manager hinbekommen soll, vor allem wenn es sich auf verschiedene Monitorgrößen anpassen soll, etc.
     
  17. Da Dein Layout nach relativ komplexen Regeln aufgebaut ist, die mir noch nicht ganz klar sind (z.B. die acht quadratischen Panels: ist der relative/absolute Anteil an der Höhe begrenzt?) wurde ich empfehlen einen eigenen LayoutManager zu schreiben.

    Sowohl für den eigenen als auch fertige LayoutManager gilt aber:
    Die Regeln wie die Komponenten auf der Fläche verteilt werden sollen müssen eindeutig sein.
     
  18. Was spricht dagegen, die Vorschaupanels in ein Panel mit GridLayout(1,8) zu legen, dieses Panel dann ins Hauptpanel in BorderLayout.SOUTH, und die eigentliche Matrix dann ins Hauptpanel mit BorderLayout.CENTER?
     
  19. Gleiches Problem.

    Ich versteh das gar nicht, dass diese ganzen Constraints so schwer zu verstehen sind. Ich sehe mittlerweile schon ein Layout vor mir, wenn ich den Code sehe und ich dachte, ich bin hier die Gurke :D

    Im Prinzip sind ja nur die ersten 6 Zahlen in den Constraints interessant. Die ersten beiden geben die x/y-Koordinaten an, d.h. das große Panel logischerweise (0, 0), die referenceBar (da das große Panel horizontal 7 Vorschau-Panels überspannt) erst wieder bei (7, 0) und die Vorschau-Panels eben bei (i, 1), i = 1..8.
    Die nächsten beiden Zahlen geben den span an. Der ist überall 1 außer, wie schon beschrieben, beim großen Panel.
    Hinten dann die Gewichtung, wie freier Platz aufgeteilt wird. Die oberen Komponenten (großes Panel und referenceBar) sollen vertikal ein 4:1 Verhältnis zu den Vorschaupanels haben und auf der x-Achse gilt für alle der Standard.

    Das BorderLayout aus dem Konstruktor kann man eigentlich getrost ignorieren. Das hab ich nur eingefügt, damit die leftSection über den gesamten JFrame geht.
     
  20. Nochmal eine etwas andere Sache:

    Designtechnisch ist es ja garantiert besser, wenn man die Berechnungen und das eigentliche Zeichnen der Matrix trennt. Nur, um den Platz zu bestimmen, den die Beschriftung braucht, muss man ja über ein Graphics-Objekt auf die FontMetrics zugreifen. Ich kann mich allerdings erinnern, wie ich vor einiger Zeit irgendwo mal gelesen habe, dass man das Graphics-Objekt auf keinen Fall außerhalb der paintComponent mit getGraphics() abfragen sollte (die Begründung dazu weiß ich nicht mehr bzw. die gab es auch gar nicht). Es macht ja auch irgendwo Sinn, denn woher soll ein Panel wissen, auf welchem Graphics-Context es mal gezeichnet wird.

    Was macht man da?
     
  21. Wenn mich nicht alles täuscht bekommt das Graphics den Font, der auf der Component gesetzt ist, die gezeichnet werden soll (also mal panel.getFont und panel.setFont anschauen)... kann mich aber auch irren. Hat sich das mit dem Layout erledigt?
     
  22. Das Problem mit dem Layout hat sich nur teilweise erledigt. Ein revalidate() nach setPreferredSize() schaltet zumindest die Scrollbalken ein, wann ich will, aber jede Aktion, die irgendwie die View updated, zerschießt wieder alles.
     
    Zuletzt bearbeitet: 26. Okt. 2009
  23. Updates: Das mit getFont() hat sehr gut geklappt, vielen Dank schonmal dafür :)

    Mit dem Layout bin ich auch nen Schritt weiter. Das Problem, dass sich das Layout beim Neuladen eines anderen Files zerschossen hat, lag an einem validate(), was ich anscheinend gar nicht brauchte.
    Nur beim resizen macht er eben noch alles kaputt. Die Frage ist jetzt, was ich mache. Ich kann natürlich irgendwie das OnResize-Event so überschreiben, dass er darin kein validate aufruft, das sieht mir aber irgendwie nur nach Verlagerung des Problems aus...
    Die Frage ist auch, ob ich damit alle Fälle abdecke. Gehört da denn auch sowas dazu wie einen SplitPaneSeparator zu verschieben?
     
  24. Wie gesagt, ich weiß nicht, was gegen sowas spricht
    Code (Text):

    import javax.swing.*;

    import java.awt.*;

    public class PanelLayoutTest extends JPanel {
        private static final long   serialVersionUID    = 1L;
        private static final int    PANEL_COUNT         = 8;
        private JPanel              bigPanel            = new JPanel();
        private final JPanel[]      previewPanels       = new JPanel[PANEL_COUNT];

        public PanelLayoutTest() {
            for(int i = 0; i < PANEL_COUNT; i++)
                previewPanels[i] = new JPanel();

            setLayout(new BorderLayout());

            JPanel left = createLeftSection();
            add(left, BorderLayout.CENTER);
        }

        private JPanel createLeftSection() {
            JPanel leftSec = new JPanel();
            leftSec.setLayout(new BorderLayout());

            JScrollPane scrollPane = new JScrollPane(bigPanel);
            JPanel previews = new JPanel(new GridLayout(1,PANEL_COUNT));
            JPanel thisOtherOne = new JPanel();
            thisOtherOne.setPreferredSize(new Dimension(300,300));

            leftSec.add(scrollPane, BorderLayout.CENTER);
            leftSec.add(previews, BorderLayout.SOUTH);
            leftSec.add(thisOtherOne, BorderLayout.EAST);

            for(int i = 0; i < PANEL_COUNT; i++) {
                previews.add(previewPanels[i]);
                previewPanels[i].setBorder(BorderFactory.createLineBorder(Color.black));
                previewPanels[i].setPreferredSize(new Dimension(300,300));
            }

            bigPanel.setPreferredSize(new Dimension(600, 600));

            return leftSec;
        }

        public static void main(String[] args) {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setExtendedState(Frame.MAXIMIZED_BOTH);
            frame.add(new PanelLayoutTest());
            frame.setVisible(true);
        }
    }
    Aber wenn du das andere besser findest, und/oder weder klar sagst, wie groß die einzelnen Panels sein sollen oder welche Größenverhältnisse sie haben sollen, oder was wann passieren soll, wenn man es vergrößert oder verkleinert, kann ich dir nicht weiterhelfen.

    Kannst ja von allen Components, die du erstellst, die "validate"-Methode überschreiben
    Code (Text):

    panel = new JPanel()
    {
        public void validate()
        {
            System.out.println("Nee, das mach' ich lieber selbst");
        }
    };
     
    (hier müßte jetzt irgendein Smiley hin)
     
  25. Sorry konnte mich länger nicht darum kümmern, weil die Deadlines anderer Fächer näher waren ;)

    Also um es mal kurz zu machen: Deinen Ansatz habe ich auch schon probiert und das Problem ist das gleiche. Mir geht es auch gar nicht um ein ganz besonderes Verhältnis des Layouts oder ähnliches, sondern um das hier:

    Code (Java):
    package org.fvscale.ui.main;

    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;

    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;

    public class Test2 extends JPanel {
        private JFrame frame;
       
        Test2() {
            GridBagLayout layout = new GridBagLayout();
            setLayout(layout);
           
            JPanel a = new JPanel();
            JPanel b = new JPanel();
            JPanel c = new JPanel();
            JPanel d = new JPanel();
            JScrollPane sc = new JScrollPane(a);
           
            layout.setConstraints(sc, new GridBagConstraints(0, 0, 1, 1, 1, 1,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
            layout.setConstraints(b, new GridBagConstraints(1, 0, 1, 1, 1, 1,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
            layout.setConstraints(c, new GridBagConstraints(0, 1, 1, 1, 1, 1,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
            layout.setConstraints(d, new GridBagConstraints(1, 1, 1, 1, 1, 1,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
                    0));
           
            add(sc);
            add(b);
            add(c);
            add(d);
           
            a.setPreferredSize(new Dimension(800, 800));
            a.revalidate();
        }
        /**
         * Create the GUI and show it.  For thread safety,
         * this method should be invoked from the
         * event-dispatching thread.
         */

        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("ScrollDemo2");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            //Create and set up the content pane.
            JComponent newContentPane = new Test2();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane);

            //Display the window.
            frame.pack();
            frame.setVisible(true);
        }

        public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
     
    Ich erstelle hier einen Frame mit GridBagLayout, das 4 gleich große JPanels beinhalten soll. Das JPanel oben links ist zusätzlich noch in eine JScrollPane eingebettet. Was jetzt passiert, wenn ich die preferredSize des eingebetteten Panels erhöhe (und zusätzlich validate() aufrufe, was laut Dokumentation für eine Neuberechnung der ScrollPane reichen sollte), sprengt er mir das Layout. D.h. die Komponenten sind nicht mehr gleich groß, sondern die nun vergrößerte JScrollPane(!!!) drückt die anderen 3 Panels an den Rand.

    Was ich will: Die größe der JScrollPane soll sich niemals durch eine Zeichenoperation auf dem darin liegenden Panel ändern, sondern sie soll ihre Größe beibehalten und Scrollbalken anzeigen, sobald das Panel zu größ wird. Oder kurz: Der JFrame soll jederzeit in 4 gleich große Bereiche unterteilt sein. Man kann ja z.B. mal die preferredSize eines der anderen 3 JPanels vergrößern. Darauf reagiert der JFrame mit einer gleichmäßigen Verteilung für alle 4 Komponenten. Warum?
     
  26. Beim GridBagLayout :autsch: werden Gewichte angegeben. Die PreferredSize vom einen Panel ist 800,800, und die von den anderen ist 0,0. Was soll er machen?

    Zwei Alternativen: GridLayout(2,2) verwenden, oder allen 4 Panels eine PreferredSize von 800,800 geben.

    EDIT: Und eine dritte, ziemlich Hackig:
    sc.setPreferredSize(new Dimension(0,0));

    Und noch eine potentielle vierte: Das JPanel a könnte von einer Klasse sein, die Scrollable geeignet implementiert.
     
  27. Ja, genau die hab ich gestern auch gefunden und war ziemlich glücklich :)

    Eine (hoffentlich) letzte Frage noch: Kann man irgendwie die Initialgrößenberechnung von Swing vorziehen? Also z.B:

    Code (Java):
    JFrame frame = new JFrame("foo");
            frame.getContentPane().setLayout(new BorderLayout());
            JScrollPane scrollPane = new JScrollPane(panel);
            frame.setSize(new Dimension(800, 800));
            frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
            panel.getVisibleRect() // = [0, 0]
    Ich will also erneut die Zeichnerei perfekt auf die Anzeigegröße auslegen und müsste dazu wissen, wie groß das Panel später ist. Ich kann es natürlich mit 800x800 harcoden, aber das ist wohl ziemlich unelegant...
     
  28. Was soll worauf angepasst werden? Mit getPreferredSize() geht sowas i.a....
     
  29. Schau dir jetzt hier den Kurs an und lernen Java zu programmieren: --> Hier klicken, um mehr zu erfahren (Klick)
Status des Themas:
Es sind keine weiteren Antworten möglich.