Ich wurde mehrmals dafür kritisiert, dass ich die Verwendung der folgenden Methoden vorgeschlagen habe:
- setPreferredSize
- setMinimumSize
- setMaximumSize
auf Swing
Komponenten. Ich sehe keine Alternative zu ihrer Verwendung, wenn ich Proportionen zwischen angezeigten Komponenten definieren möchte. Mir wurde folgendes gesagt:
Bei Layouts ist die Antwort immer dieselbe: Verwenden Sie einen geeigneten LayoutManager
Ich habe ein wenig im Internet gesucht, aber keine umfassende Analyse des Themas gefunden. Ich habe also folgende Fragen:
- Sollte ich die Verwendung dieser Methoden vollständig vermeiden?
- Die Methoden wurden aus einem bestimmten Grund definiert. Wann sollte ich sie verwenden? In welchem Kontext? Für welche Zwecke?
- Was genau sind die negativen Folgen dieser Methoden? (Ich kann mir nur vorstellen, Portabilität zwischen Systemen mit unterschiedlicher Bildschirmauflösung hinzuzufügen).
- Ich glaube nicht, dass ein LayoutManager alle gewünschten Layoutanforderungen genau erfüllen kann. Muss ich wirklich für jede kleine Variation meines Layouts einen neuen LayoutManager implementieren?
- Wenn die Antwort auf 4 "Ja" lautet, führt dies dann nicht zu einer Zunahme von LayoutManager-Klassen, deren Wartung schwierig wird?
- Ist es in einer Situation, in der ich Proportionen zwischen untergeordneten Elementen einer Komponente definieren muss (z. B. sollte child1 10% des Speicherplatzes verwenden, child2 40%, child3 50%), möglich, dies zu erreichen, ohne einen benutzerdefinierten LayoutManager zu implementieren?
quelle
JEditorPane
mit HTML, das selbst keine Breite vorschlägt. OTOH Ich bin mir nicht sicher, ob ich etwas verpasst habe. Ich werde die Antworten auf den Thread sorgfältig prüfen, war aber interessiert, wenn Sie Kommentare hatten, insbesondere zu letzterem Fall.Einige Heuristiken:
Verwenden Sie nicht ,
set[Preferred|Maximum|Minimum]Size()
wenn Sie wirklich außer Kraft zu setzen bedeutenget[Preferred|Maximum|Minimum]Size()
, wie es bei der Erstellung Ihre eigene Komponente erfolgen, gezeigt hier .Nicht verwenden,
set[Preferred|Maximum|Minimum]Size()
wenn Sie sich darauf verlassen können, dass eine Komponente sorgfältig überschrieben wirdgetPreferred|Maximum|Minimum]Size
, wie hier und unten gezeigt.Verwenden Sie
set[Preferred|Maximum|Minimum]Size()
diese Optionvalidate()
, um die Postgeometrie abzuleiten , wie unten und hier gezeigt .Wenn eine Komponente keine bevorzugte Größe hat
JDesktopPane
, müssen Sie möglicherweise den Container dimensionieren, aber eine solche Auswahl ist willkürlich. Ein Kommentar kann helfen, die Absicht zu verdeutlichen.Ziehen Sie alternative oder benutzerdefinierte Layouts in Betracht, wenn Sie feststellen, dass Sie viele Komponenten durchlaufen müssen, um abgeleitete Größen zu erhalten, wie in diesen Kommentaren erwähnt .
quelle
setPreferredSize()
immer die Berechnung der Komponente durch eine beliebige Auswahl.Nein, es gibt keine formalen Beweise dafür, dass das Aufrufen oder Überschreiben dieser Methoden nicht zulässig ist. Laut Oracle werden diese Methoden verwendet, um Größenhinweise zu geben: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment .
Sie können auch außer Kraft gesetzt werden (das ist die beste Praxis für Swing) , wenn Verlängerung eine Swing - Komponente (anstatt Aufruf der Methode auf dem benutzerdefinierten Komponenteninstanz)
Unabhängig davon, wie Sie die Größe Ihrer Komponente angeben, stellen Sie sicher, dass der Container Ihrer Komponente einen Layout-Manager verwendet, der die angeforderte Größe der Komponente berücksichtigt.
Wenn Sie dem Layout-Manager des Containers benutzerdefinierte Größenhinweise geben müssen, damit die Komponente gut angeordnet ist
Viele Layout-Manager achten nicht auf die angeforderte maximale Größe einer Komponente. Aber
BoxLayout
undSpringLayout
tun. Darüber hinausGroupLayout
bietet die Möglichkeit , die minimalen, bevorzugte oder maximale Größe explizit zu setzen, ohne die Komponente zu berühren.Stellen Sie sicher, dass Sie die genaue Größe der Komponente wirklich einstellen müssen. Jede Swing-Komponente hat eine andere bevorzugte Größe, abhängig von der verwendeten Schriftart und dem Erscheinungsbild. So hat eine festgelegte Größe variiert produzieren könnte Blicke auf verschiedene Systeme der UI
Manchmal können Probleme mit
GridBagLayout
und Textfeldern auftreten. Wenn die Größe des Containers kleiner als die bevorzugte Größe ist, wird die Mindestgröße verwendet, was dazu führen kann, dass Textfelder erheblich verkleinert werden.JFrame
erzwingt keine ÜberschreibunggetMinimumSize()
, indem nursetMinimumSize(..)
seine Werke aufgerufen werdenWenn mit Implementierung gemeint ist, dann ja. Nicht jeder
LayoutManger
kann mit allem umgehen, jederLayoutManager
hat seine Vor- und Nachteile, so dass jeder zusammen verwendet werden kann, um das endgültige Layout zu erstellen.Referenz:
quelle
setXxxSize
Methoden als rote Fahne zu sehen, dass ich hier landen könnte , selbst wenn die Dokumente es vorschlagen. Ich hätte fast immer überschreiben sollengetXxxSize
, wo man Zugriff auf die gewünschte Geometrie hat; und selbst kurze Beispiele werden mehr recycelt, als ich mir vorstellen möchte. +1 für die Erwähnung von Abweichungen zwischen Layout-Managern und das Zitieren des Tutorials.Hier gibt es viele gute Antworten, aber ich möchte etwas mehr über die Gründe hinzufügen, warum Sie diese normalerweise vermeiden sollten (die Frage wurde gerade in einem doppelten Thema erneut gestellt):
Mit wenigen Ausnahmen, wenn Sie diese Methoden verwenden, optimieren Sie wahrscheinlich Ihre GUI so, dass sie in einem bestimmten Erscheinungsbild gut aussieht (und mit Ihren systemspezifischen Einstellungen, z. B. Ihrer bevorzugten Desktop-Schriftart usw.). Die Methoden selbst sind nicht von Natur aus böse, aber die typischen Gründe für ihre Verwendung sind . Sobald Sie anfangen, Pixelpositionen und -größen in einem Layout zu optimieren, besteht die Gefahr, dass Ihre GUI auf anderen Plattformen beschädigt wird (oder zumindest schlecht aussieht).
Versuchen Sie beispielsweise, das Standard-Erscheinungsbild Ihrer Anwendung zu ändern. Selbst mit den auf Ihrer Plattform verfügbaren Optionen können Sie überrascht sein, wie schlecht die Ergebnisse wiedergegeben werden können.
Um Ihre GUI auf allen Plattformen funktionsfähig und ansprechend zu halten (denken Sie daran, einer der Hauptvorteile von Java ist die plattformübergreifende Funktionalität), sollten Sie sich auf Layout-Manager usw. verlassen, um die Größe von automatisch anzupassen Ihre Komponenten, damit sie außerhalb Ihrer spezifischen Entwicklungsumgebung korrekt gerendert werden.
Trotzdem können Sie sich durchaus Situationen vorstellen, in denen diese Methoden gerechtfertigt sind. Auch hier sind sie nicht von Natur aus böse, aber ihre Verwendung ist normalerweise eine große rote Fahne, die auf mögliche Probleme mit der Benutzeroberfläche hinweist. Stellen Sie einfach sicher, dass Sie sich des hohen Komplikationspotenzials bewusst sind, wenn / wenn Sie sie verwenden, und versuchen Sie immer zu überlegen, ob es eine andere Look-and-Feel-unabhängige Lösung für Ihre Probleme gibt - meistens werden Sie feststellen, dass diese auftreten Methoden sind nicht notwendig.
Übrigens, wenn Sie mit Standard-Layout-Managern frustriert sind, gibt es viele gute kostenlose Open-Source- Angebote von
FormLayout
Drittanbietern, zum Beispiel JGoodies oderMigLayout
. Einige GUI-Builder bieten sogar integrierte Unterstützung für Layout-Manager von Drittanbietern. Der WindowBuilder-GUI-Editor von Eclipse bietet beispielsweise Unterstützung fürFormLayout
undMigLayout
.quelle
JTextField.setColumns
die Spaltenanzahl festlegen, um die bevorzugte Größe entsprechend anzupassen. Wenn Sie dies tun,setPreferredSize
codieren Sie eine Größe fest, wodurch Ihre Layouts abhängig von der Schriftgröße der Plattform beschädigt werden. Hier sind einige Textfelder in einem Grid-Bag-Layout mitsetColumns
entsprechend aufgerufen . Verwenden Sie für Ihre Schaltflächen geeignete Layouts / Rastergewichte, um die Größen zu steuern.Wenn Sie Probleme mit Layouts in Java Swing haben, kann ich die JGoodies,
FormLayout
die Karsten Lentzsch hier als Teil der Freeware-Bibliothek Forms zur Verfügung stellt, wärmstens empfehlen .Dieser sehr beliebte Layout-Manager ist äußerst flexibel und ermöglicht die Entwicklung sehr ausgefeilter Java-Benutzeroberflächen.
Sie finden Karsten Dokumentation in finden hier , und einige ziemlich gute Dokumentation von Eclipse hier .
quelle
Diese Methoden werden von den meisten Menschen kaum verstanden. Sie sollten diese Methoden auf keinen Fall ignorieren. Es ist Sache des Layout-Managers, diese Methoden einzuhalten. Diese Seite enthält eine Tabelle, die zeigt, welche Layout-Manager welche dieser Methoden einhalten:
http://thebadprogrammer.com/swing-layout-manager-sizing/
Ich schreibe seit mehr als 8 Jahren Swing-Code und die im JDK enthaltenen Layout-Manager haben immer meine Bedürfnisse erfüllt. Ich habe noch nie einen Layout-Manager eines Drittanbieters benötigt, um meine Layouts zu erstellen.
Ich werde sagen, dass Sie nicht versuchen sollten, dem Layout-Manager mit diesen Methoden Hinweise zu geben, bis Sie sicher sind, dass Sie sie benötigen. Führen Sie Ihr Layout ohne Größenangaben aus (dh lassen Sie den Layout-Manager seine Arbeit erledigen), und nehmen Sie bei Bedarf kleinere Korrekturen vor.
quelle
Vielleicht
GridBagLayout
würde Ihre Bedürfnisse befriedigen. Außerdem gibt es im Web eine Menge Layout-Manager, und ich wette, es gibt einen, der Ihren Anforderungen entspricht.quelle
Ich sehe es anders als die akzeptierte Antwort.
1) Sollte ich die Verwendung dieser Methoden vollständig vermeiden?
Niemals meiden! Sie dienen dazu, dem Layout-Manager die Größenbeschränkungen Ihrer Komponenten auszudrücken. Sie können sie vermeiden, wenn Sie keinen Layout-Manager verwenden, und versuchen, das visuelle Layout selbst zu verwalten.
Leider wird Swing nicht mit angemessenen Standardabmessungen geliefert. Anstatt die Abmessungen einer Komponente festzulegen, ist es jedoch besser, die eigene Komponente mit angemessenen Standardeinstellungen herabzusetzen. (In diesem Fall rufen Sie setXXX in Ihrer Nachkommenklasse auf.) Alternativ können Sie die getXXX-Methoden für denselben Effekt überschreiben.
2) Die Methoden wurden aus einem bestimmten Grund definiert. Wann sollte ich sie verwenden? In welchem Kontext? Für welche Zwecke?
Immer. Wenn Sie eine Komponente erstellen, legen Sie ihre realistische minimale / bevorzugte / maximale Größe entsprechend der Verwendung dieser Komponente fest. Wenn Sie beispielsweise ein JTextField für die Eingabe von Ländersymbolen wie UK haben, muss seine bevorzugte Größe so breit sein, dass zwei Zeichen (mit der aktuellen Schriftart usw.) passen. Wahrscheinlich ist es jedoch bedeutungslos, es größer werden zu lassen. Ländersymbole sind schließlich zwei Zeichen. Wenn Sie dagegen ein JTextField zur Eingabe eines Kundennamens haben, kann es eine bevorzugte Größe wie die Pixelgröße für 20 Zeichen haben, kann jedoch größer werden, wenn die Größe des Layouts geändert wird. Stellen Sie daher die maximale Größe auf mehr ein. Gleichzeitig ist es sinnlos, ein 0px breites JTextField zu haben. Legen Sie daher eine realistische Mindestgröße fest (ich würde sagen, die Pixelgröße beträgt 2 Zeichen).
3) Was genau sind die negativen Folgen dieser Methoden?
(Ich kann mir nur vorstellen, 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 genau erfüllen kann.
Muss ich wirklich für jede kleine Variation meines Layouts einen neuen LayoutManager implementieren?
Nein, definitiv nicht. Der übliche Ansatz besteht darin, verschiedene grundlegende Layoutmanager wie das horizontale und das vertikale Layout zu kaskadieren.
Zum Beispiel das folgende Layout:
hat zwei Teile. Der linke und der rechte Teil sind horizontal angeordnet. 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 mit einem realen Layout schwierig werden. Daher sind gitterbasierte Layout-Manager wie MigLayout viel besser, wenn Sie etwas Ernstes entwickeln möchten.
5) Wenn die Antwort auf 4 "Ja" lautet, führt dies dann nicht zu einer Zunahme von LayoutManager-Klassen, deren Wartung schwierig wird?
Nein, Sie sollten definitiv keine Layout-Manager entwickeln, es sei denn, Sie benötigen etwas ganz Besonderes.
6) In einer Situation, in der ich Proportionen definieren muss ...
Ist es zwischen Kindern einer Komponente (z. B. Kind1 sollte 10% des Speicherplatzes verwenden, Kind2 40%, Kind3 50%) möglich, dies zu erreichen, ohne einen benutzerdefinierten LayoutManager zu implementieren?
Sobald die bevorzugten Größen richtig eingestellt sind, möchten Sie möglicherweise nichts mehr in Prozent tun. Einfach, weil Prozentsätze sinnlos sind (z. B. ist es sinnlos, ein JTextField zu haben, das 10% der Fenstergröße beträgt - da man das Fenster verkleinern kann, sodass JTextField 0 Pixel breit wird, oder das Fenster so erweitern kann, dass sich das JTextField über zwei Anzeigen auf einem befindet Multi-Display-Setup).
Möglicherweise verwenden Sie die Prozentsätze jedoch, um die Größe größerer Bausteine Ihrer GUI (z. B. Panels) zu steuern.
Sie können JSplitPane verwenden, wo Sie das Verhältnis der beiden Seiten voreingestellt haben. Sie können auch MigLayout verwenden, mit dem Sie solche Einschränkungen in Prozent, Pixeln und anderen Einheiten festlegen können.
quelle
btnBar.setPreferredSize( dimTouchBtn );
ist der beste Weg, das zu tun. Einfach, kein benutzerdefinierter Layout-Manager erforderlich. Ich benutze meistensGridBagLayout
mit einigenBorderLayout
undBoxLayout
niste, wenn es mir passt. Dies ist eine starke Kombination und einfach zu bedienen.Sollte ich die Verwendung dieser Methoden vollständig vermeiden? Ich würde nicht sagen "meide" sie. Ich würde sagen, wenn du denkst, dass du sie brauchst, machst du wahrscheinlich etwas falsch. Komponentengrößen werden im Kontext bestimmt. Die Größe von Textkomponenten wird beispielsweise durch die Anzahl der von Ihnen angegebenen Zeilen und Spalten in Kombination mit der von Ihnen ausgewählten Schriftart bestimmt. Ihre Schaltflächen- und Beschriftungsgröße entspricht der Größe der Grafik, falls Sie eine festlegen, oder dem Platz, der zum Anzeigen des von Ihnen festgelegten Texts erforderlich ist. Jede Komponente hat eine natürliche Größe, und die Layout-Manager verwenden diese, um alles zu gestalten, ohne dass Sie Größen angeben müssen. Die Hauptausnahme ist das JScrollPane, dessen Größe unabhängig von dem ist, was es enthält. Für diese werde ich manchmal anrufen
setSize()
und diese Größe die anfängliche Fenstergröße durch Aufrufen bestimmen lassenJFrame.pack()
. Normalerweise lasse ich die Fenstergröße die JScrollPane-Größe bestimmen. Der Benutzer bestimmt die Größe des Fensters. Viele Layout-Manager ignorieren die von Ihnen festgelegten Größen ohnehin und tun daher oft nicht viel Gutes.Die Methoden wurden aus einem bestimmten Grund definiert. Wann sollte ich sie verwenden? In welchem Kontext? Für welche Zwecke? Ich glaube, sie wurden hinzugefügt, um den Layout-Managern Hinweise zu geben. Sie wurden möglicherweise aus historischen Gründen geschrieben, weil Layout-Manager neu waren und die Leute ihnen nicht voll vertrauten. Ich kenne einige Entwickler, die Layout-Manager vermieden und alles manuell platziert haben, nur weil sie sich nicht mit dem Erlernen eines neuen Paradigmas beschäftigen wollten. Es ist eine schreckliche Idee.
Was genau sind die negativen Folgen dieser Methoden? (Ich kann mir nur vorstellen, Portabilität zwischen Systemen mit unterschiedlicher Bildschirmauflösung hinzuzufügen). Sie sind ineffektiv und erzeugen schlechte Layouts, wobei Objekte zusammengedrückt oder auf nicht natürliche Größen gedehnt werden. Und die Layouts werden spröde. Änderungen an der Fenstergröße führen manchmal zu einer Unterbrechung des Layouts und zu falschen Positionen.
Ich glaube nicht, dass ein LayoutManager alle gewünschten Layoutanforderungen genau erfüllen kann. Muss ich wirklich für jede kleine Variation meines Layouts einen neuen LayoutManager implementieren? Sie sollten keinen neuen LayoutManager "implementieren". Sie sollten vorhandene instanziieren. Ich verwende oft mehrere Layout-Manager in einem einzigen Fenster. Jedes JPanel verfügt über einen eigenen Layout-Manager. Einige Leute scheuen verschachtelte Layouts, weil sie schwer zu pflegen sind. Wenn ich sie benutze, gebe ich jedem seine eigene Erstellungsmethode, damit ich leichter sehen kann, was jeder tut. Aber ich "implementiere" niemals einen Layout-Manager. Ich instanziiere sie einfach.
Wenn die Antwort auf 4 "Ja" lautet, führt dies dann nicht zu einer Zunahme von LayoutManager-Klassen, deren Wartung schwierig wird? Wenn Sie neue Layout-Manager-Klassen für geringfügige Abweichungen im Layout implementieren, verwenden Sie diese falsch. Wenn Sie nur neue Layout-Manager implementieren, machen Sie wahrscheinlich etwas falsch. Das einzige Mal, dass ich eine LayoutManager-Klasse erweitert habe, war das Hinzufügen eines Zoom-Schiebereglers zu einem JScrollPane.
Ist es in einer Situation, in der ich Proportionen zwischen untergeordneten Elementen einer Komponente definieren muss (z. B. sollte child1 10% des Speicherplatzes verwenden, child2 40%, child3 50%), möglich, dies zu erreichen, ohne einen benutzerdefinierten LayoutManager zu implementieren? Im JSplitPane kann der Prozentsatz angegeben werden, den jede Komponente erhalten soll. Der Teiler ist standardmäßig beweglich, aber Sie können ihn deaktivieren, wenn Sie möchten. Ich benutze diese Funktion nicht viel. Normalerweise habe ich einige Komponenten, die eine festgelegte Größe einnehmen, und der Rest des Speicherplatzes wird von einem Bildlauffenster eingenommen. Die Größe des Bildlauffensters wird mit der Fenstergröße angepasst. Wenn Sie zwei Bildlauffenster nebeneinander haben, können Sie sie in ein JSplitPane einfügen und den Prozentsatz des neuen Speicherplatzes angeben, der jedem Fenster zugewiesen wird, wenn der Benutzer die Fenster erweitert und verkleinert.
quelle