Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Java und Swing-Problem
#1
Servus,

ich dachte, ich poste hier mal mein Problem, in der Hoffnung, dass sich hier jemand mit Java auskennt. Ich hab letztens angefangen einen generischen Editor für Spielstände zu schreiben. Mein Problem ist nun, dass der LayoutManager sich nicht so verhält, wie ich es erwarten würde. Im Anhang befindet sich eine ZIP-Datei, die meine Sourcen enthält, vielleicht hat ja jemand Lust, sich damit auseinander zu setzen.
Unter test befindet sich eine LayoutTest.java. Das ist ein einfaches Frame mit zehn JButtons. Wenn man die Fenstergröße verändert, werden die Buttons neu angewordnet, so dass sie im Fenster verbleiben.
Unter src/gui gibt es ein GamePanel.java. Wenn man das startet, sollte man die savegame.xml laden und über Import eine DSA1-Char-Datei auswählen. Und dann ist das Problem ersichtlich (siehe auch Screenshot im Anhang): Alle generierten JComponents sind in einer Reihe angeordnet, so dass sie das Fenster auf beiden Seiten verlassen. Wenn jemand weiß, wie ich erzwingen kann, dass es wie das vorige Beispiel funktioniert, sagt mir bitte Bescheid.
Denn das ganze könnten Bimberbude und ich ganz gut als Basis für einen Monster-Editor benutzen.


Angehängte Dateien Thumbnail(s)
   

.zip   GameHexStuff.zip (Größe: 142,99 KB / Downloads: 5)
Zitieren
#2
Verstehe ich das richtig, Du hast keine fertige Maske, sondern willst der Reihe nach dynamisch JComponents hinzufügen? Interessante Idee. Dann ist wohl GridLayout oder FlowLayout richtig. So ganz steige ich auf Anhieb nicht durch die Sourcen. Wie wäre es mit Kommentaren?

Am sinnvollsten fände ich ein GridBagLayout mit vordefinierten Feldern und Abständen zu einander. Bedenke, dass Du immer ein JPanel mit weiteren JPanels füllen kannst, die jeweils über andere LayoutManager verfügen.

Meine erste Anlaufstelle für derartige Probleme ist http://www.exampledepot.com/
Zitieren
#3
Jupp, wie schon von Rabenaas vorgeschlagen, musst du ein Layout für das lowerPanel festlegen. Ich schätze, du möchtest eine tabellenartige Anordnung, da ist GridLayout(Zeilen, Spalten) mit gerader Spaltenzahl (2 oder 4) wohl angebracht, ist halt nur fraglich, was bei Überschreiten der gewählten Anzahl Felder passiert. GridBagLayout ist sicher das flexibelste (nach manueller Andordnung), aber komplizierter zu handhaben als Flow-, Grid- oder BorderLayout.

P.S.: Wenn du willst, dass das Programm auch bei Anderen funktioniert, wähle in den XML-Dateien einen relativen Pfad für die DTD.
Hallo, ich bin's - der Bart von Fidel Castro. Und mir ist total langweilich nie geschnitten wurde.
I'm a roleplayer. My dice are like my relationships: platonic and unlucky.
Zitieren
#4
Java, Swing, LayoutManager?

*schüttel*

Das Ding ist der Teufel, der Teufel ich sag' es euch!

* Borbaradwurm konnte sich diesen Kommentar nicht verkneifen.
Zitieren
#5
Servus,

sorry, für die Fehler und fehlende Kommentare, die kommen noch bei Gelegenheit.

Zitat:Verstehe ich das richtig, Du hast keine fertige Maske, sondern willst der Reihe nach dynamisch JComponents hinzufügen? Interessante Idee. Dann ist wohl GridLayout oder FlowLayout richtig.
Ganz richtig, deshalb wollte ich erstmal FlowLayout verwenden, was auch standardmäßig von jeder JComponent benutzt wird. Das Problem besteht, egal ob ich FlowLayout oder GridBagLayout verwende. Und ein GridBagLayout mit vordefinierten Felder würde ich nur ungern benutzne, da ich ja nicht weiß, was an Inhalten vorhanden sein wird und welche Dimension das JFrame hat. Ich werde es aber mal ausprobieren. Ich werde auch mal probieren, das Layout explizit auf FlowLayout zu stellen.
Wenn generell Interesse an dem Programm besteht, kann ich mir vielleicht auch mal die Zeit nehmen und Kommentare schreiben.


EDIT: Ich hab mal wieder nicht gesehen, dass einmal von GridLayout und einmal von GridBagLayout die Rede ist. GridLayout halte ich für keine praktikable Idee, da ich weder weiß, wieviele Koponenten enthalten, noch wie große diese sein werden.
Zitieren
#6
:wall::wall::wall:

Also sowas, da hab ich mir in den letzten Wochen doch schon öfter den Kopf über dieses Problem zerbrochen und dann ist die Lösung so einfach. Falls es jemanden interessiert hier die Lösung (alle anderen können diesen Paragraphen jetzt getrost überspringen):
In der Klasse GamePanel werden in dem ActionListener zu dem importSaveGameButton alle Komponenten erstellt und zusammengesetzt. Das ganze wird dann in ein Panel (saveGamePanel) gesteckt, das selbst im Zentrum eines BorderLayouts sitzt. Wenn ich mein generiertes Panel (addMe) stattdessen direkt in das Zentrum des BorderLayouts setze, dann funktioniert es.

Das finde ich äußerst erfreulich, dass dieses Problem behoben ist. Dann kann ich gleich mit meiner nächsten Frage kommen: Kennt sich jemand mit JScrollPane aus? Denn da ich nicht weiß, wie viele Elemente so ein Panel enthalten wird, wäre es praktisch, wenn es einen vertikalen Scrollbalken gäbe. Das blöde ist nur, sobald ich ein JScrollPane benutze, werden die Elemente, wie vorher, nur in der Horizontalen aufgereiht und ich kann horizontal scrollen. Es wäre mir aber lieber, wenn sich das Ding an die Breite des Fensters halten würde und, wenn nötig, vertikales Scrollen erlauben würde.
Ich würde mich freuen, wenn ihr mir dabei auch helfen könntet. Ich habe hier zwar schon irgendwo von einem Charakter-Editor gelesen, aber ich glaube der lief nur unter Windows. Außerdem wäre das Ding auch eine gute Basis für einen Monster-/Kampf-Editor (hab ich glaub ich oben schon erwähnt).
Zitieren
#7
Ok, das Problem ist auch geschafft. Ich hab von http://java.freehep.org das FlowScrollLayout benutzt.
Zitieren
#8
Die Idee, einen JScrollPane in nur in einer Dimension automatisch umbrechen zu lassen, funktioniert nicht. Theoretisch gibt es Flags, die genau das steuern sollen. Praktisch haut es aber nicht hin. Ich habe irgendwann einfach aufgegeben. Versuchen kannst Du es ja mal. :evil:

Ansonsten hat Borbaradwurm absolut recht. Deswegen steigen ja auch so viele Leute auf SWT um.

EDIT: WAAAAAAAAA!?! Naja, ich durfte nur Bordmittel verwenden. ;)
Zitieren
#9
Pssst,.... HÄ????? (;))
--------
Warnung! Geschichte kann zu Einsichten führen und verursacht Bewusstsein!
Avatar by: Keven Law (CC BY-SA 2.0)
Zitieren
#10
(01.04.2009, 20:08)Rabenaas schrieb: EDIT: WAAAAAAAAA!?! Naja, ich durfte nur Bordmittel verwenden. ;)
Und ich kann dich noch weiter beruhigen: Dein Editor kann DSA spezifische Dinge, der generische von mir kann nur stumpf Werte eintragen.
Zitieren
#11
Da verwechselst Du mich gerade mit Scheí¯jian, glaube ich. ;)
Zitieren
#12
Ahso, dann hab ich deinen Post falsch interpretiert.
Zitieren
#13
Swing treibt mich mal wieder in den Wahnsinn... :angry:

Weiß hier jemand (wo ich nachgucken kann), wie ein LayoutManager die "preferred size" eines Containers berechnet? Ich ärger mich damit ja nicht zum ersten Mal rum, aber mir ist immer noch schleierhaft, wie dabei die "Unter-Komponenten" berücksichtigt werden... preferred, minimum, maximum oder nur size?
Wie kann denn bitte ein Panel, das Komponenten mit einer Breite von 198 Pixeln enthält, selber nur ne bevorzugte Breite von 28 haben!? :wall:

Und kann ich diese Berechnung irgendwie beeinflussen bzw. dafür sorgen, dass sie richtig funktioniert? Was müsste ich wo überschreiben, wenn ich die Berechnung selber von Hand machen will?

Ich bin kurz davor, getPreferredSize() zu überschreiben, so dass die Methode einfach konstante Werte zurückgibt... :silly:

Ich hasse Swing und Swing hasst mich... :cry:
Great people care.
Zitieren
#14
Welche Komponente in welcher? Oft hilft es, Zwischencontainer mit anderem Layoutmanager zwischenzuschalten. Eine allgemeine Antwort gibt es aufgrund der Polymorphie gar nicht.

EDIT: Das Problem hatte ich auch schon das eine oder andere mal. :pfeif:
Zitieren
#15
Ich verwende einen (wie ich vermute) etwas exotischeren LayoutManager, nämlich das SpringLayout, weil ich dabei noch die größte Kontrolle über das Layout habe und es recht schnell so aussah, wie ich es haben wollte. Das Layout benutzt "Federn" (Spring), um die Abstände zwischen den Komponenten zu definieren. Ich benutze konstante Federn (min = max = pref), damit sich da nix verschiebt.

Das Panel, um das es geht, soll ein Menü werden - bzw. ist es das schon, aber man sieht es halt noch nicht, wenn man es nicht manuell vergrößert. ;) In diesem Menü (MenuPanel) gibt es mehrere Einträge zum Anklicken (MenuItem), ebenfalls Panels, die (bis jetzt) jeweils ein Label mit nem Icon enthalten. Alle Komponenten werden mit diesem SpringLayout ausgerichtet. Das funktioniert auch wunderbar. Das einzige Problem ist, wie gesagt, die Größe.

Das ganze Problem im Detail zu schildern, ist wohl etwas zu aufwändig. Hatte nur gehofft, dass du oder jemand anderes vielleicht schon den Dreh raus hat, was Swing angeht, und eine ganz einfache Lösung weiß. Ich vermute nämlich, dass das ein Standardfehler ist, den ich da mache; vielleicht weil ich irgendwo irgendwas verändere (über setPreferredSize() oder so), was ich nicht sollte, weil der LayoutManager dann nicht mehr klar kommt, oder sonstwas. ;) Gerade bei diesen LayoutManagern und den (bevorzugten) Größen von Komponenten verliert man sich ja recht leicht im Swing-Dschungel.

So sieht das Ganze übrigens aus, wenn ich es manuell vergrößere:
   
Und so, wenn ich es ganz ohne LayoutManager einfach in ein Frame klatsche:
   
Dass es überhaupt sichtbar ist, liegt daran, dass ich die Texturgrößen der Ecken manuell reingerechnet hab (das wär schon mal eine Stelle, wo ich die Finger drin hab ;)).
Great people care.
Zitieren
#16
Aber pack() ruft das Panel am Ende der Initialisrungsroutine auf, oder?

EDIT: Hört sich für mich nach einem klassischen Fall für das GridBagLayout an. Vielleicht sogar AbsoluteLayout.
Zitieren
#17
pack() kann das Panel nicht. Das kann nur das Frame (das dann aber auch mit Minimalgröße startet). Das GridBagLayout hab ich probiert, allerdings hab ich's nicht geschafft, die Komponenten vernünftig auszurichten. Ich blick auch mit diesen Constraints überhaupt nicht durch. Vielleicht sollt ich einfach mal ein paar hundert Seiten Javadoc & Co wälzen... :confused:
Great people care.
Zitieren
#18
In einer von JFrame abgeleiteten Klasse habe ich z.B. mal folgendes gemacht:
Code:
        // Fenster anordnen
        frame.pack();
        frame.setSize(800, 600);
und zwar nachdem alle Kindkomponenten eingefügt wurden, und bevor das Fenster dargestellt wird.

Nein, die JavaDoc ist nur für Referenzzwecke. hilfreicher sind die Insel, das Almanach und die Trails.

Layout mit Swing ist aber auch ein wirklich kompliziertes und verbuggtes Feld. Oft muss man sich mit üblen Tricks helfen. Versuche lieber erst mal, einen vernünftigen LayoutManager einzusetzen.
Und die Technik mit den Containern in Containern ist wirklich mächtig.
Zitieren
#19
(11.09.2009, 21:27)Rabenaas schrieb: Versuche lieber erst mal, einen vernünftigen LayoutManager einzusetzen.
Heißt das, du findest das SpringLayout doof? :D
Mein Problem bei diesen LayoutManagern ist, dass ich so wenig Kontrolle habe. Am Schluss gefällt mir meistens irgendwas nicht. Dann würde es schon reichen, den Button X noch zwei Pixel nach links zu verschieben, aber genau das geht natürlich nicht... Naja, ich hab wohl zu hohe Ansprüche an die swingsche grafische Oberfläche. Liegt vielleicht daran, dass ich mit Delphi angefangen hab... :D
(Ein WYSIWYG-Editor wär super. Da gibt's ja einige. Hab auch schon viele probiert, aber die sind leider alle sehr mau. Vor allem zerschießen sie dir den ganzen Code... :()

Die Insel ist zwar sehr gut, leider aber oft nicht ausführlich genug. Hilft nur, wenn man bereits ein Gefühl dafür hat, wie's nach dem Ansatz weitergeht. Und sonst gibt es ja hundert Quellen im Internet zur Java-Programmierung. Nur hilft vieles davon auch nicht wirklich weiter. Da wird dann zwar z.B. etwas über diese LayoutManager erklärt, aber eine Lösung für das Problem, dass man gerade hat, sucht man vergeblich. Naja, ich guck mal. Danke für die Links. :)
Great people care.
Zitieren
#20
(11.09.2009, 21:55)Boneman schrieb: Heißt das, du findest das SpringLayout doof? :D
:pfeif:

(11.09.2009, 21:55)Boneman schrieb: Dann würde es schon reichen, den Button X noch zwei Pixel nach links zu verschieben, aber genau das geht natürlich nicht...
Wenn es das ist, was Du willst :evil::
Code:
pane.setLayout(null);

JButton b1 = new JButton("one");
JButton b2 = new JButton("two");
JButton b3 = new JButton("three");

pane.add(b1);
pane.add(b2);
pane.add(b3);

Insets insets = pane.getInsets();
Dimension size = b1.getPreferredSize();
b1.setBounds(25 + insets.left, 5 + insets.top,
             size.width, size.height);
size = b2.getPreferredSize();
b2.setBounds(55 + insets.left, 40 + insets.top,
             size.width, size.height);
size = b3.getPreferredSize();
b3.setBounds(150 + insets.left, 15 + insets.top,
             size.width + 50, size.height + 20);

...//In the main method:
Insets insets = frame.getInsets();
frame.setSize(300 + insets.left + insets.right,
              125 + insets.top + insets.bottom);
hier
Ich kenne die Editoren von Eclipse und NetBeans. Beide ok, aber ich bevorzuge auch "händisch".
Zitieren




Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste