Welcome!

Java IoT Authors: Yeshim Deniz, Elizabeth White, Liz McMillan, Pat Romanski, Jason Bloomberg

Related Topics: Java IoT

Java IoT: Article

SpringLayout: A Powerful & Extensible Layout Manager

SpringLayout: A Powerful & Extensible Layout Manager

The task of a layout manager is to position and size each component based on the size of its container. Each component has a preferred size that can be used to determine the real estate it wishes to occupy, as well as a minimum and maximum size. The preferred size is especially useful for components that contain user-visible strings whose size can change between development and deployment due to different fonts or different locale values, as the GUI is dynamically translated through resource bundles.

Layout managers are powerful classes for dynamically recalculating the size and position of the GUI components at runtime; however, they often lead to a less than optimal design-time experience. With WYSIWYG development tools, it frequently happens that developers position the mouse where they wish to drop a new component, only to see the entire GUI reorganize and the component placed in another location. This is due to the indirection involved in translating the developer's gesture to the correct constraint for the layout manager.

JDK 1.4 introduces a new layout manager - javax.swing.SpringLayout. The motivation behind building it was to create a layout manager that made it easier to design GUIs, was powerful enough to emulate the behavior of all the existing JRE layout managers, and be easily extensible where a new rule was required.

The most pleasant user experience with a design tool occurs when you set the layout manager to null. Then you can place your component exactly where you want it using the mouse and set its size using resize handles. The problem with not having a layout manager is that the explicit bounds of the component are fixed constants set at design time. With SpringLayout you can specify each component's x, y, width, and height, but instead of using fixed coordinates, the constraints are springs. These springs can be derived from the edges of existing components, and are able to flex under tension and compression when the window size is changed.

To illustrate SpringLayout this article demonstrates how to use springs to anchor edges of components and align widths, and how to create complex springs.

Background
To specify how each component should be positioned and sized by the layout manager you must use a constraint object, which is an instance of the inner class javax.swing.SpringLayout.Constraints. A SpringLayout.Constraints object contains six springs - for the component's width and height and each of its four edges.

A spring is analogous to a physical spring that connects the edge of the component to another point on the GUI. Each edge is controlled by a single spring, so springs are best thought of as directional. For example, a spring that fixes the left edge of a component to the right edge of another doesn't operate in reverse. When the first component's right edge moves, this affects the second component's left edge, but not vice versa.

Springs can be fixed struts that have a constant value, or else can be flexed under tension and compression. To determine how elastic a spring is, it has a preferred, minimum, and maximum value. If the minimum value is the same as the preferred value, the spring is rigid under compression, and, likewise, if the maximum value is the same as its preferred value the spring can't be expanded. If no spring is specified for a component's width or height, the default spring created defers its preferred minimum and maximum values to the component. In addition to using individual springs to anchor and size components, springs can be combined to create compound springs whose elasticity is the sum, maximum or minimum, of its arguments.

When designing a GUI using SpringLayout, draw a diagram of the components in the positions you want them to be in, and then mentally determine what will keep them in those positions. Usually this will be a fixed length spring between the component's left and top edge relative to its nearest neighbor's edges. This is very useful for components that contain user-visible strings, such as buttons and labels where the exact size isn't known until runtime, because the font used or the actual string, if it has been externalized in a locale-specific bundle, can vary.

To show how to use springs, this article builds a simple GUI that illustrates some of the common types. The screen images have red lines drawn on them to help you visualize each spring. This approach, drawing springs between components, is an intuitive way to design a GUI where you begin by drawing the components at their absolute positions and sizes and then add lines to represent the springs. A GUI builder could employ this method where you drop a control at the position you want it placed, and springs are automatically created between it and its nearest neighbors.

Constant Springs
The simplest spring is a fixed value that positions an edge a constant distance from its parent container. Figure 1 shows a button that has two constant springs used to position it at 5,10 inside a frame's contentPane. The SpringLayout class automatically generates a Constraints object for every component that's added to its container, so in order to change any of the springs you can query the Constraints object and set new values. To create a constant fixed spring, use the static method Spring.constant(int).

JButton okButton = new JButton("OK");
contentPane.add(okButton);
SpringLayout.Constraints okCst =
layout.getConstraints(okButton);
okCst.setX(Spring.constant(10));
okCst.setY(Spring.constant(5));

Springs Between Edges
In Figure 1 the springs for the OK button were fixed lengths of 5 and 10. Even though no springs were specified for the width and height of the button, some were created automatically based on the preferred, minimum, and maximum size. These springs can be queried and used in the constraints of other components so you can position them relative to each other. For example, a Cancel button can be added to the content pane, whose x spring is the right-edge spring of the OK button. To query the spring for an edge, the method public Spring getConstraint(String edgeName) can be used that takes arguments of "North", "East", "South", and "West" for each edge. To position the Cancel button so its left edge is a fixed distance away from the right edge of the OK button, a compound spring is used. The method Spring.sum(Spring spring1,Spring spring) creates a compound spring whose value is the sum of two arguments. By combining the east edge of the OK button with a constant spring of 5, a spring is created that will always be five larger than the right edge of the OK button. This spring is then used as the x spring of the Cancel button.

JButton cButton = new JButton("Cancel");
contentPane.add(cButton);
SpringLayout.Constraints cCst =
layout.getConstraints(cButton);
cCst.setY(Spring.constant(5));
cCst.setX(Spring.sum(
Spring.constant(5),
okCst.getConstraint("East")));

The result of this is shown in Figure 2 where the Cancel button is positioned to the right of the OK button with a space of 5 pixels in between.

Sizing the Window with Springs
In addition to allowing you to specify constraints for a container's components, you can specify a constraint for the container that allows you to control its edges. The content pane's right edge can be set with a compound spring as 20 away from the right edge of the cancel button. To do this, retrieve the spring for the layout manager's container, and then set its east spring.

SpringLayout.Constraints pnlCst =
layout.getConstraints(contentPane);
pnlCst.setConstraint("East",Spring.sum(
Spring.constant(20),
cCst.getConstraint("East")));

For the content pane's bottom edge a spring can be put between it and the bottom of the buttons. This spring can make the bottom of the contentPane be a distance of 15 away from the buttons, and because the OK and Cancel buttons are the same height and have the same y spring, the content pane's bottom edge can spring from either one. A compound sum spring is created that adds the south spring of the cancel button's constraint to a fixed spring of 15.

pnlCst.setConstraint("South",Spring.sum(
Spring.constant(15),
cancelCst.getConstraint("South")));

When there are springs controlling the edges of the contentPane, the window can be packed to give it an initial size (see Figure 3). In the previous examples where there were no springs for the edges of the contentPane, the window was given a fixed size of 200 by 200.

The content pane's edges can have a spring between them and a specific control, such as the Cancel button. However, if there is no single control that determines the edges of the content pane, a compound spring can be created. This compound spring needs to determine which is greater, the south spring of the OK button or the Cancel button. The method Spring.max(Spring spring1, Spring spring2) is used to create a single spring whose value is the greater of the two arguments.

pnlCst.setConstraint("South",
Spring.sum(Spring.constant(15),
Spring.max(
cancelCst.getConstraint("South")),
okCst.getConstraint("South")));

Springs for Widths and Heights
You can also use springs to set a component's size, as well as its position. For example, instead of the OK and Cancel button each being their preferred size, you want them to be the same size. The size used will need to be the larger of each button's preferred size so that neither label is clipped and a compound spring can be created based on the maximum of the two widths.

Spring widthSpring = Spring.max(
okCst.getWidth(),
cancelCst.getWidth());
okCst.setWidth(widthSpring);
cancelCst.setWidth(widthSpring);

Because the code changes the spring that specifies the width of the OK button, and this spring is also used to calculate the distance between the OK and Cancel buttons, the constraint between the two buttons must be defined after setting their width springs. This ensures that the x spring of the cancel constraint is not based on its original width spring, but is derived from the max spring instead. The order of setting springs that form input to compound springs is important, and the following code must be done after the OK button's width spring is set.

cancelCst.setX(Spring.sum(
Spring.constant(5),
okCst.getConstraint("East")));

Likewise the spring that's created between the content pane's right edge and the right edge of the Cancel button must be defined after the width spring is established. Generally, it's a good idea to specify any explicit width or height springs before defining the positional springs between components to ensure that no queried width or height springs are later replaced. Because the word "Cancel" is longer than "OK", the OK button's width is increased to match that of the Cancel button. However, if in a different language the lengths were reversed, the two buttons would always remain the same width. Figure 4 shows that the OK and Cancel buttons are the same size, and that the overall window size still remains 20 and 15 away from the Cancel button.

The ability to compute a component's width and height using a compound spring gives you a level of control not previously possible with other layout managers. In GridBagLayout you can align widths of components by placing them in the same column, but with SpringLayout you can align widths where the controls are side by side as shown in Figure 4. Sometimes the requirement for laying out buttons may be a rule such as "Make the buttons have the same width but make this be no smaller than 60." This can be created by having a compound spring such as:

Spring widthSpring = Spring.max(
Spring.constant(60),
Spring.max(
okCst.getWidth(),
cancelCst.getWidth()));

Components Resizing with the Container
For some components, such as JTextArea, the desired layout is to make as much use of the available space as possible. To do this springs can be made between the east and south edge of the text area and its container. Listing 1 creates a JTextArea and adds constant springs between its east edge and the container, and its south edge and the container. The lines of code setting the springs between the Cancel button can be deleted as the contentPane's constraints are attached to the text area; although, if left there the panel will use the newest springs since only one spring can be held for each constraint in the SpringLayout.Constraint class, and setting a new one replaces any existing spring.

The panel opens with a default size based on the preferred size of the JTextArea (see Figure 5).

When the panel is resized, the JTextArea will be resized with it, expanding to make use of extra width or height. This occurs with the JTextArea and not with the OK and Cancel buttons due to the default width and height springs that were initially created for each component by the layout manager. A JButton's preferred, minimum, and maximum sizes are all the same value, so there is no "give" in an arrangement of buttons connected together with "struts." By contrast, a JTextArea's minimum and maximum and size are not the same, so the default width and height springs can expand and compress. After the panel changes size, the layout manager looks at the flexibility of all its springs and, based on their elasticity, calculates their values.

The JTextArea becomes larger when the window size is expanded, and smaller when the size is reduced. The fixed-edge springs remain at their value of 10, while the JTextArea shrinks to occupy the remaining space.

With a reduced window size the springs between the edges of the JTextArea and its neighboring edges remain 10 pixels wide, and the JTextArea reduces in size because its minimum size that provides the input to its width and height springs is 0 (see Figure 6). However, rather than have the springs between the JTextArea and its neighbors rigid, they can be made flexible so they'll compress when the window size is reduced. This way, when the window is made smaller, more of the actual space can be given to the JTextArea.

In addition to defining a single value for a constant spring, you can also set a minimum and maximum size, e.g., Spring.constant(0,10,20). If the minimum and maximum values are the same as the preferred value, which occurs when the single argument constructor is used, the spring becomes an inflexible strut. However, with a minimum and maximum size, when the window size is changed, the layout manager takes these values into account to determine the new actual values of each spring. To illustrate this all the springs used in the example between the JTextArea and its neighbors were set to be constant with a minimum of 0, a maximum of 20, and a preferred size of 10.

txtCst.setY(Spring.sum(
Spring.constant(0,10,20),Spring.max(
cancelCst.getConstraint("South"),
okCst.getConstraint("South"))));
pnlCst.setConstraint("East",
Spring.sum(Spring.constant(0,10,20),
txtCst.getConstraint("East")));
pnlCst.setConstraint("South",Spring.sum(
Spring.constant(0,10,20),
txtCst.getConstraint("South")));

What occurs now is that when the window is reduced in size, the springs can be compressed. The layout manager looks at the compressibility of each spring, including the implicit spring that the JTextArea has for its width and height, to determine the size and position of the controls. When the window is made smaller, the springs compress and the JTextArea occupies more of the available real estate. When the window size was reduced to a height of 77, the JTextArea, with rigid springs around it, was made 26 high, enough to show two lines of text. However, the flexible springs mean that they can take the strain and allow the JTextArea to have a larger size (see Figure 7). The top and bottom Springs are compressed to a value of 4, and the JTextArea has 12 extra pixels available for its height, making it 28 high so it can display an extra row of text. If flexible springs were also used for the top of the two buttons, the window could be further optimized so that yet more of the more available space was allocated to the JTextArea under compression.

The rules by which the layout manager determines how much to compress each of the springs are based on how much it resists being compressed. When a spring is compressed, imagine that it provides an opposite force that increases as it reaches its minimum value. If the minimum and preferred values are the same, the force is an irresistible one and the spring is rigid.

The springs between the edges have a minimum value of 0 and a preferred of 10, and the JTextArea's height spring is based on its minimumSize's height of 0 and preferredSize's height of 5 rows of characters at the current font. Both of these springs are compressed as the window size decreases. When the window is increased, the edge springs have a maximum size of 20 and a preferred size of 10, however, the maximumSize of the JTextArea is based on the look and feel but is likely to be Integer.MAX_VALUE. Because the resistance of a spring increases as its value approaches its maximum value, for the JTextArea's width or height to become rigid the window would have to become enormous. Use of compressible springs between components allows you to create a GUI that reallocates its available spaces across its components as it changes size, so the user has more available working component area and the window remains effective over a longer range of overall sizes.

Convenience Methods for Attaching Springs Between Edges
To attach the Cancel button to the OK button and make them 5 apart:

cancelCst.setX(Spring.sum(
Spring.constant(5),
okCst.getConstraint("East")));

This scenario, where you attach the edge of one component a fixed distance from another, occurs frequently when creating GUIs with SpringLayout, so there's a helper method

SpringLayout.putConstraint(String targetEdge,
Component targetComponent, int distance,
String sourceEdge, Component sourceComponent);
layoutManager.putConstraint("East",
cancelButton , 5, "East", okButton);

Creating Springs in the Correct Order
Because of the cyclic nature of springs, i.e., they are often calculated based on existing springs that are combined to create new compound springs, the order in which the constraints are set is important. For example, if you query the west or width spring of a component, should you then set its east spring, afterward this could affect either of the previously queried springs, making their values stale. Therefore, it's important to establish and query strings in the correct order. The analogy is that of a spreadsheet whose cells' values are based on calculations that include other cells' values as input.

An application window is made up of a set of components, and SpringLayout lets you add a set of springs into this picture. The springs define the positions and sizes of components, and can be anchored to other components' edges, or can be derived from calculations using existing springs.

We hope that you'll have some fun with SpringLayout and that it helps solve some of those difficult layout problems where things don't work out quite the way you want. In our minds at least, the holy grail of layout experiences would be a GUI builder that would allow the user to add constraints between components visually - rather than having to write code. This is quite a difficult problem; if you're working on a GUI builder or have ideas about the best way to do this - drop us a line!

Resources

  • Online tutorial of SpringLayout: http://java.sun.com/docs/books/ tutorial/uiswing/layout/spring.html
  • JDK 1.4 SDK download: http://java.sun.com/j2se/1.4/download.html
  • More Stories By Joe Winchester

    Joe Winchester, Editor-in-Chief of Java Developer's Journal, was formerly JDJ's longtime Desktop Technologies Editor and is a software developer working on development tools for IBM in Hursley, UK.

    Comments (4) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    hubert.gockel 08/17/04 08:10:52 AM EDT

    Excellent! Was trying hard to to come across all the mysteries of this new layout management technique but did not succeed prior to studying this fine article.

    Dean Johnston 03/19/03 02:50:00 PM EST

    And before OS/2, Motif did it. Nice to see Smalltalk and something to learn as well.

    Fred Johnson 12/12/02 02:08:00 PM EST

    IBM's VisualAge Smalltalk implemented the same flexibility back in the days of OS/2, only they called it "anchoring" and tended to specify the connections as pixels or percentages. Of course, their GUI builder also generated executable code for events and messages, not just a blank form. In many areas, Smalltalk achieved years ago what is now considered leading edge in Java.

    Dave Paules 12/09/02 10:31:00 AM EST

    This is a great way to build GUIs. The Mac folks have been building UIs with springs with Apple's Interface Builder. It's great to be able to visualize what will happen to a UI BEFORE it is run. I'm glad to see that Sun is imitating best practices like this in the industry. Let's hope that Apple will push swing even further (directly or indirectly).

    @ThingsExpo Stories
    We build IoT infrastructure products - when you have to integrate different devices, different systems and cloud you have to build an application to do that but we eliminate the need to build an application. Our products can integrate any device, any system, any cloud regardless of protocol," explained Peter Jung, Chief Product Officer at Pulzze Systems, in this SYS-CON.tv interview at @ThingsExpo, held November 1-3, 2016, at the Santa Clara Convention Center in Santa Clara, CA
    With major technology companies and startups seriously embracing Cloud strategies, now is the perfect time to attend 21st Cloud Expo October 31 - November 2, 2017, at the Santa Clara Convention Center, CA, and June 12-14, 2018, at the Javits Center in New York City, NY, and learn what is going on, contribute to the discussions, and ensure that your enterprise is on the right path to Digital Transformation.
    In his session at @ThingsExpo, Eric Lachapelle, CEO of the Professional Evaluation and Certification Board (PECB), provided an overview of various initiatives to certify the security of connected devices and future trends in ensuring public trust of IoT. Eric Lachapelle is the Chief Executive Officer of the Professional Evaluation and Certification Board (PECB), an international certification body. His role is to help companies and individuals to achieve professional, accredited and worldwide re...
    The Internet giants are fully embracing AI. All the services they offer to their customers are aimed at drawing a map of the world with the data they get. The AIs from these companies are used to build disruptive approaches that cannot be used by established enterprises, which are threatened by these disruptions. However, most leaders underestimate the effect this will have on their businesses. In his session at 21st Cloud Expo, Rene Buest, Director Market Research & Technology Evangelism at Ara...
    SYS-CON Events announced today that Enzu will exhibit at SYS-CON's 21st Int\ernational Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Enzu’s mission is to be the leading provider of enterprise cloud solutions worldwide. Enzu enables online businesses to use its IT infrastructure to their competitive advantage. By offering a suite of proven hosting and management services, Enzu wants companies to focus on the core of their ...
    Internet of @ThingsExpo, taking place October 31 - November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA, is co-located with 21st Cloud Expo and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The Internet of Things (IoT) is the most profound change in personal and enterprise IT since the creation of the Worldwide Web more than 20 years ago. All major researchers estimate there will be tens of billions devic...
    Amazon started as an online bookseller 20 years ago. Since then, it has evolved into a technology juggernaut that has disrupted multiple markets and industries and touches many aspects of our lives. It is a relentless technology and business model innovator driving disruption throughout numerous ecosystems. Amazon’s AWS revenues alone are approaching $16B a year making it one of the largest IT companies in the world. With dominant offerings in Cloud, IoT, eCommerce, Big Data, AI, Digital Assista...
    SYS-CON Events announced today that Cloud Academy named "Bronze Sponsor" of 21st International Cloud Expo which will take place October 31 - November 2, 2017 at the Santa Clara Convention Center in Santa Clara, CA. Cloud Academy is the industry’s most innovative, vendor-neutral cloud technology training platform. Cloud Academy provides continuous learning solutions for individuals and enterprise teams for Amazon Web Services, Microsoft Azure, Google Cloud Platform, and the most popular cloud com...
    When growing capacity and power in the data center, the architectural trade-offs between server scale-up vs. scale-out continue to be debated. Both approaches are valid: scale-out adds multiple, smaller servers running in a distributed computing model, while scale-up adds fewer, more powerful servers that are capable of running larger workloads. It’s worth noting that there are additional, unique advantages that scale-up architectures offer. One big advantage is large memory and compute capacity...
    No hype cycles or predictions of zillions of things here. IoT is big. You get it. You know your business and have great ideas for a business transformation strategy. What comes next? Time to make it happen. In his session at @ThingsExpo, Jay Mason, Associate Partner at M&S Consulting, presented a step-by-step plan to develop your technology implementation strategy. He discussed the evaluation of communication standards and IoT messaging protocols, data analytics considerations, edge-to-cloud tec...
    "When we talk about cloud without compromise what we're talking about is that when people think about 'I need the flexibility of the cloud' - it's the ability to create applications and run them in a cloud environment that's far more flexible,” explained Matthew Finnie, CTO of Interoute, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
    SYS-CON Events announced today that MobiDev, a client-oriented software development company, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. MobiDev is a software company that develops and delivers turn-key mobile apps, websites, web services, and complex software systems for startups and enterprises. Since 2009 it has grown from a small group of passionate engineers and business...
    SYS-CON Events announced today that GrapeUp, the leading provider of rapid product development at the speed of business, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Grape Up is a software company, specialized in cloud native application development and professional services related to Cloud Foundry PaaS. With five expert teams that operate in various sectors of the market acr...
    SYS-CON Events announced today that Ayehu will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on October 31 - November 2, 2017 at the Santa Clara Convention Center in Santa Clara California. Ayehu provides IT Process Automation & Orchestration solutions for IT and Security professionals to identify and resolve critical incidents and enable rapid containment, eradication, and recovery from cyber security breaches. Ayehu provides customers greater control over IT infras...
    With the introduction of IoT and Smart Living in every aspect of our lives, one question has become relevant: What are the security implications? To answer this, first we have to look and explore the security models of the technologies that IoT is founded upon. In his session at @ThingsExpo, Nevi Kaja, a Research Engineer at Ford Motor Company, discussed some of the security challenges of the IoT infrastructure and related how these aspects impact Smart Living. The material was delivered interac...
    Artificial intelligence, machine learning, neural networks. We’re in the midst of a wave of excitement around AI such as hasn’t been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. Will this time be different? Most likely. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Furthermore, the funding and research going into AI now comes from a wide range of com...
    In his session at Cloud Expo, Alan Winters, an entertainment executive/TV producer turned serial entrepreneur, presented a success story of an entrepreneur who has both suffered through and benefited from offshore development across multiple businesses: The smart choice, or how to select the right offshore development partner Warning signs, or how to minimize chances of making the wrong choice Collaboration, or how to establish the most effective work processes Budget control, or how to ma...
    IoT solutions exploit operational data generated by Internet-connected smart “things” for the purpose of gaining operational insight and producing “better outcomes” (for example, create new business models, eliminate unscheduled maintenance, etc.). The explosive proliferation of IoT solutions will result in an exponential growth in the volume of IoT data, precipitating significant Information Governance issues: who owns the IoT data, what are the rights/duties of IoT solutions adopters towards t...
    SYS-CON Events announced today that CA Technologies has been named "Platinum Sponsor" of SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. CA Technologies helps customers succeed in a future where every business - from apparel to energy - is being rewritten by software. From planning to development to management to security, CA creates software that fuels transformation for companies in the applic...
    SYS-CON Events announced today that IBM has been named “Diamond Sponsor” of SYS-CON's 21st Cloud Expo, which will take place on October 31 through November 2nd 2017 at the Santa Clara Convention Center in Santa Clara, California.