507 Stimmen

Sollte ich die Verwendung von set(Preferred|Maximum|Minimum)Size Methoden in Java Swing vermeiden?

Ich bin mehrfach dafür kritisiert worden, dass ich die Anwendung der folgenden Methoden vorgeschlagen habe:

  1. setPreferredSize
  2. setMinimumSize
  3. setMaximumSize

auf Swing Komponenten. Ich sehe keine Alternative zu ihrer Verwendung, wenn ich Proportionen zwischen angezeigten Komponenten festlegen möchte. Dies wurde mir gesagt:

Bei Layouts ist die Antwort immer die gleiche: Verwenden Sie einen geeigneten LayoutManager

Ich habe das Internet ein wenig durchsucht, aber ich habe keine umfassende Analyse zu diesem Thema gefunden. Daher habe ich die folgenden Fragen:

  1. Sollte ich die Anwendung dieser Methoden völlig vermeiden?
  2. Die Methoden sind nicht ohne Grund festgelegt worden. Wann sollte ich sie also verwenden? In welchem Zusammenhang? Für welche Zwecke?
  3. Was genau sind die negativen Folgen der Anwendung dieser Methoden? (Ich kann mir nur vorstellen, dass die Übertragbarkeit zwischen Systemen mit unterschiedlicher Bildschirmauflösung hinzukommt).
  4. Ich glaube nicht, dass irgendein LayoutManager alle gewünschten Layoutanforderungen erfüllen kann. Muss ich wirklich für jede kleine Variation in meinem Layout einen neuen LayoutManager implementieren?
  5. Wenn die Antwort auf Frage 4 "ja" lautet, führt dies dann nicht zu einer Vervielfachung der LayoutManager-Klassen, die nur noch schwer zu pflegen sind?
  6. In einer Situation, in der ich Proportionen zwischen Kindern einer Komponente definieren muss (z. B. Kind1 sollte 10 % des Platzes verwenden, Kind2 40 %, Kind3 50 %), ist es möglich, das zu erreichen, ohne einen benutzerdefinierten LayoutManager zu implementieren?

18voto

Michael Punkte 2598

Diese Methoden werden von den meisten Menschen nur unzureichend verstanden. Sie sollten diese Methoden auf keinen Fall ignorieren. Es liegt im Ermessen des Layouters, ob er diese Methoden anerkennt. Auf dieser Seite finden Sie eine Tabelle, die zeigt, welche Layout-Manager welche dieser Methoden anerkennen:

http://thebadprogrammer.com/swing-layout-manager-sizing/

Ich schreibe seit mehr als 8 Jahren Swing-Code, und die im JDK enthaltenen Layout-Manager haben mir immer gute Dienste geleistet. Ich habe nie einen Layout-Manager eines Drittanbieters benötigt, um meine Layouts zu erreichen.

Ich möchte darauf hinweisen, dass Sie nicht versuchen sollten, dem Layout-Manager mit diesen Methoden Hinweise zu geben, solange Sie nicht sicher sind, dass Sie diese benötigen. Machen Sie Ihr Layout, ohne Hinweise zur Größe zu geben (d. h. lassen Sie den Layout-Manager seine Arbeit machen), und dann können Sie kleinere Korrekturen vornehmen, wenn Sie sie brauchen.

17voto

Thomas Punkte 84982

In einer Situation, in der ich Proportionen zwischen Kindern einer Komponente definieren muss (Kind 1 sollte 10 % des Platzes verwenden, Kind2 40 %, Kind3 50 %), ist es möglich, das zu erreichen, ohne einen benutzerdefinierten Layout-Manager zu implementieren?

Vielleicht GridBagLayout würde Ihre Bedürfnisse befriedigen. Außerdem gibt es eine Menge Layout-Manager im Internet, und ich wette, es gibt einen, der Ihren Anforderungen entspricht.

7voto

Gee Bee Punkte 1754

Ich sehe das anders als die übliche Antwort.

1) Sollte ich die Anwendung dieser Methoden vollständig vermeiden?

Niemals vermeiden! Sie sind dazu da, dem Layout-Manager die Größenbeschränkungen Ihrer Komponenten mitzuteilen. Sie können sie vermeiden, wenn Sie keinen Layout-Manager verwenden und versuchen, das visuelle Layout selbst zu verwalten.

Leider ist Swing nicht mit vernünftigen Standardabmessungen ausgestattet. Anstatt die Abmessungen einer Komponente festzulegen, ist es jedoch besser, Ihre eigene Komponente mit vernünftigen Standardwerten abzustufen. (In diesem Fall rufen Sie setXXX in Ihrer Nachfolgeklasse auf.) Alternativ können Sie die getXXX-Methoden überschreiben, um denselben Effekt zu erzielen.

2) Die Methoden wurden aus einem bestimmten Grund festgelegt. Wann sollte ich sie also verwenden? In welchem Zusammenhang? Für welche Zwecke?

Immer. Wenn Sie eine Komponente erstellen, legen Sie deren realistische Mindest-, Vorzugs- und Höchstgröße entsprechend der Verwendung dieser Komponente fest. Wenn Sie z. B. ein JTextField für die Eingabe von Ländersymbolen wie UK haben, sollte seine bevorzugte Größe so breit sein, dass zwei Zeichen hineinpassen (mit der aktuellen Schriftart usw.), aber wahrscheinlich ist es sinnlos, es noch größer werden zu lassen. Schließlich bestehen Ländersymbole aus zwei Zeichen. Wenn Sie dagegen ein JTextField für die Eingabe z.B. eines Kundennamens haben, kann es eine bevorzugte Größe haben, wie z.B. die Pixelgröße für 20 Zeichen, aber es kann größer werden, wenn die Größe des Layouts geändert wird, also setzen Sie die maximale Größe auf mehr. Gleichzeitig ist ein 0px breites JTextField sinnlos, also setzen Sie eine realistische Mindestgröße (ich würde sagen, die Pixelgröße von 2 Zeichen).

3) Was genau sind die negativen Folgen der Anwendung dieser Methoden?

(Ich kann nur daran denken, die Portabilität zwischen Systemen mit unterschiedlicher Bildschirmauflösung hinzuzufügen).

Keine negativen Folgen. Dies sind Hinweise für den Layout-Manager.

4) Ich glaube nicht, dass ein LayoutManager alle gewünschten Layoutanforderungen erfüllen kann.

Muss ich wirklich für jede kleine Variation in meinem Layout einen neuen LayoutManager implementieren?

Nein, definitiv nicht. Der übliche Ansatz besteht darin, verschiedene grundlegende Layout-Manager wie horizontales und vertikales Layout zu kaskadieren.

Zum Beispiel das folgende Layout:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

besteht aus zwei Teilen. Der linke und der rechte Teil sind ein horizontales Layout. Der rechte Teil ist ein JPanel, das dem horizontalen Layout hinzugefügt wurde, und dieses JPanel hat ein vertikales Layout, das die Schaltflächen vertikal anordnet.

Natürlich kann dies bei einem realen Layout schwierig werden. Deshalb sind rasterbasierte Layout-Manager wie MigLayout viel besser, wenn Sie etwas Ernsthaftes entwickeln wollen.

5) Wenn die Antwort auf Frage 4 "ja" lautet, führt dies nicht zu einer Vermehrung von LayoutManager-Klassen, die schwer zu pflegen sein werden?

Nein, Sie sollen auf keinen Fall Layout-Manager entwickeln, es sei denn, Sie brauchen etwas ganz Besonderes.

6) In einer Situation, in der ich Proportionen definieren muss...

zwischen den Kindern einer Komponente (z. B. Kind1 soll 10 % des Platzes einnehmen, Kind2 40 %, Kind3 50 %), ist es möglich, dies zu erreichen, ohne einen eigenen LayoutManager zu implementieren?

Wenn die bevorzugten Größen einmal richtig eingestellt sind, sollten Sie keine prozentualen Änderungen mehr vornehmen. Ganz einfach, weil Prozentsätze sinnlos sind (z.B. ist es sinnlos, ein JTextField 10% der Fenstergröße zu haben - da man das Fenster schrumpfen kann, so dass das JTextField 0px breit wird, oder man kann das Fenster erweitern, so dass das JTextField über zwei Displays in einem Multi-Display-Setup ist).

Aber manchmal kann man die Prozentsätze verwenden, um die Größe größerer Bausteine der Benutzeroberfläche (z. B. Panels) zu steuern.

Sie können JSplitPane verwenden, wo Sie das Verhältnis der beiden Seiten voreinstellen können. Oder Sie können MigLayout verwenden, mit dem Sie solche Beschränkungen in Prozent, Pixeln und anderen Einheiten festlegen können.

1voto

MiguelMunoz Punkte 4172

Sollte ich die Anwendung dieser Methoden völlig vermeiden? Ich würde nicht sagen "meiden". Ich würde sagen, wenn Sie glauben, dass Sie sie brauchen, machen Sie wahrscheinlich etwas falsch. Die Größe der Komponenten hängt vom jeweiligen Kontext ab. Die Größe einer Textkomponente wird beispielsweise durch die Anzahl der Zeilen und Spalten bestimmt, die Sie angeben, in Kombination mit der Schriftart, die Sie ausgewählt haben. Die Größe von Schaltflächen und Beschriftungen richtet sich nach der Größe der Grafik, falls Sie eine eingestellt haben, oder nach dem Platz, der für die Anzeige des von Ihnen eingestellten Textes benötigt wird. Jede Komponente hat eine natürliche Größe, und die Layout-Manager verwenden diese, um alles anzuordnen, ohne dass Sie Größen angeben müssen. Die wichtigste Ausnahme ist das JScrollPane, das eine Größe hat, die unabhängig von dem ist, was es enthält. Für diese rufe ich manchmal setSize() und lassen Sie diese Größe die anfängliche Fenstergröße bestimmen, indem Sie JFrame.pack() . Normalerweise lasse ich die Fenstergröße die JScrollPane-Größe bestimmen. Die Größe des Fensters wird vom Benutzer bestimmt. Viele Layout-Manager ignorieren die von Ihnen festgelegten Größen sowieso, so dass sie oft nicht viel nützen.

Die Methoden sind nicht ohne Grund festgelegt worden. Wann sollte ich sie also verwenden? In welchem Zusammenhang? Für welche Zwecke? Ich glaube, sie wurden hinzugefügt, um den Layout-Managern Hinweise zu geben. Sie könnten aus historischen Gründen geschrieben worden sein, weil die Layout-Manager neu waren und man ihnen nicht ganz traute. Ich kenne einige Entwickler, die Layout-Manager vermieden und alles manuell platziert haben, nur weil sie sich nicht die Mühe machen wollten, ein neues Paradigma zu lernen. Das ist eine schreckliche Idee.

Was genau sind die negativen Folgen der Anwendung dieser Methoden? (Ich kann mir nur vorstellen, dass die Übertragbarkeit zwischen Systemen mit unterschiedlicher Bildschirmauflösung hinzukommt). Sie sind ineffektiv und erzeugen schlechte Layouts, bei denen Objekte gequetscht oder auf unnatürliche Größen gestreckt werden. Und die Layouts werden brüchig. Änderungen an der Fenstergröße führen manchmal dazu, dass das Layout zerbricht und Dinge an die falschen Stellen gesetzt werden.

Ich glaube nicht, dass ein LayoutManager alle gewünschten Layoutanforderungen erfüllen kann. Muss ich wirklich für jede kleine Variation in meinem Layout einen neuen LayoutManager implementieren? Sie sollten einen neuen LayoutManager nicht "implementieren". Sie sollten vorhandene instanziieren. Ich verwende oft mehrere Layout-Manager in einem einzigen Fenster. Jedes JPanel hat dann seinen eigenen LayoutManager. Manche Leute schrecken vor verschachtelten Layouts zurück, weil sie schwer zu pflegen sind. Wenn ich sie verwende, gebe ich jedem seine eigene Erstellungsmethode, damit es einfacher ist, zu sehen, was jeder einzelne tut. Aber ich "implementiere" niemals einen Layout-Manager. Ich instanziiere sie nur.

Wenn die Antwort auf Frage 4 "ja" lautet, führt dies dann nicht zu einer Vervielfachung der LayoutManager-Klassen, die nur noch schwer zu pflegen sind? Wenn Sie neue Layout-Manager-Klassen für leichte Variationen im Layout implementieren, verwenden Sie sie falsch. Wenn Sie nur neue Layout-Manager implementieren, machen Sie wahrscheinlich etwas falsch. Das einzige Mal, dass ich eine LayoutManager-Klasse erweitert habe, war, um einen Zoom-Schieberegler zu einem JScrollPane hinzuzufügen.

In einer Situation, in der ich Proportionen zwischen Kindern einer Komponente definieren muss (z. B. Kind1 sollte 10 % des Platzes verwenden, Kind2 40 %, Kind3 50 %), ist es möglich, das zu erreichen, ohne einen benutzerdefinierten LayoutManager zu implementieren? Das JSplitPane bietet eine Möglichkeit, den Prozentsatz anzugeben, den jede Komponente erhalten soll. Der Teiler ist standardmäßig beweglich, aber Sie können das ausschalten, wenn Sie wollen. Ich benutze diese Funktion nicht oft. Normalerweise habe ich einige Komponenten, die eine bestimmte Größe einnehmen, und der Rest des Platzes wird von einem Bildlaufbereich eingenommen. Die Größe des Bildlauffensters passt sich an die Fenstergröße an. Wenn Sie zwei Bildlaufleisten nebeneinander haben, können Sie sie in eine JSplitPane packen und den Prozentsatz des neuen Platzes angeben, der jeder einzelnen zugewiesen wird, wenn der Benutzer das Fenster vergrößert oder verkleinert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X