The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
Before you start creating a custom layout manager, make sure that no existing layout manager meets your requirements. In particular, layout managers such as GridBagLayout
, SpringLayout
, and BoxLayout
are flexible enough to work in many cases. You can also find layout managers from other sources, such as from the Internet. Finally, you can simplify layout by grouping components into containers such as panels.
GroupLayout
layout manager combined with a builder tool to lay out your GUI. One such builder tool is the NetBeans IDE. Otherwise, if you want to code by hand and do not want to use GroupLayout
, then GridBagLayout
is recommended as the next most flexible and powerful layout manager. If you are interested in using JavaFX to create your GUI, see Working With Layouts in JavaFX.
To create a custom layout manager, you must create a class that implements the LayoutManager
interface. You can either implement it directly, or implement its subinterface, LayoutManager2
.
Every layout manager must implement at least the following five methods, which are required by the LayoutManager
interface:
void addLayoutComponent(String, Component)
Container
class's add
methods. Layout managers that do not associate strings with their components generally do nothing in this method.void removeLayoutComponent(Component)
Container
methods remove
and removeAll
. Layout managers override this method to clear an internal state they may have associated with the Component
.Dimension preferredLayoutSize(Container)
Container
class's getPreferredSize
method, which is itself called under a variety of circumstances. This method should calculate and return the ideal size of the container, assuming that the components it contains will be at or above their preferred sizes. This method must take into account the container's internal borders, which are returned by the getInsets
method.Dimension minimumLayoutSize(Container)
Container
getMinimumSize
method, which is itself called under a variety of circumstances. This method should calculate and return the minimum size of the container, assuming that the components it contains will be at or above their minimum sizes. This method must take into account the container's internal borders, which are returned by the getInsets
method.void layoutContainer(Container)
layoutContainer
method does not actually draw components. It simply invokes one or more of each component's setSize
, setLocation
, and setBounds
methods to set the component's size and position. This method must take into account the container's internal borders, which are returned by the getInsets
method. If appropriate, it should also take the container's orientation (returned by the getComponentOrientation
method) into account. You cannot assume that the preferredLayoutSize
or minimumLayoutSize
methods will be called before layoutContainer
is called.
Besides implementing the preceding five methods, layout managers generally implement at least one public constructor and the toString
method.
If you wish to support component constraints, maximum sizes, or alignment, then your layout manager should implement the LayoutManager2
interface. In fact, for these reasons among many others, nearly all modern layout managers will need to implement LayoutManager2
. That interface adds five methods to those required by LayoutManager
:
addLayoutComponent(Component, Object)
getLayoutAlignmentX(Container)
getLayoutAlignmentY(Container)
invalidateLayout(Container)
maximumLayoutSize(Container)
Of these methods, the most important are addLayoutComponent(Component, Object)
and invalidateLayout(Container)
. The addLayoutComponent
method is used to add components to the layout, using the specified constraint object. The invalidateLayout
method is used to invalidate the layout, so that if the layout manager has cached information, this should be discarded. For more information about LayoutManager2
, see the LayoutManager2
API documentation.
Finally, whenever you create custom layout managers, you should be careful of keeping references to Component
instances that are no longer children of the Container
. Namely, layout managers should override removeLayoutComponent
to clear any cached state related to the Component
.
The example CustomLayoutDemo
uses a custom layout manager called DiagonalLayout
. You can find the layout manager's source code in DiagonalLayout.java
. DialogLayout
lays out components diagonally, from left to right, with one component per row. Here is a picture of CustomLayoutDemo using DialogLayout
to lay out five buttons.
Click the Launch button to run CustomLayoutDemo
using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.