Layout management
In this part of the Jython Swing programming tutorial, we will introduce layout managers.When we design the GUI of our application, we decide what components we will use and how we will organize those components in the application. To organize our components, we use specialized non visible objects called layout managers. The Swing toolkit has two kind of components. Containers and children. The containers group children into suitable layouts. To create layouts, we use layout managers.
Absolute positioning
In most cases, programmers should use layout managers. There are a few situations, where we can use absolute positioning. In absolute positioning, the programmer specifies the position and the size of each widget in pixels. The size and the position of a widget do not change, if you resize a window. Applications look different on various platforms, and what looks OK on Linux, might not look OK on Mac. Changing fonts in your application might spoil the layout. If you translate your application into another language, you must redo your layout. For all these issues, use the absolute positioning only when you have a reason to do so.#!/usr/local/bin/jythonIn this example, we show three images using absolute positioning.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we lay out widgets
using absolute positioning
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Color
from javax.swing import ImageIcon
from javax.swing import JFrame
from javax.swing import JPanel
from javax.swing import JLabel
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
panel = JPanel()
panel.setLayout(None)
panel.setBackground(Color(66, 66, 66))
self.getContentPane().add(panel)
rot = ImageIcon("rotunda.jpg")
rotLabel = JLabel(rot)
rotLabel.setBounds(20, 20, rot.getIconWidth(), rot.getIconHeight())
min = ImageIcon("mincol.jpg")
minLabel = JLabel(min)
minLabel.setBounds(40, 160, min.getIconWidth(), min.getIconHeight())
bar = ImageIcon("bardejov.jpg")
barLabel = JLabel(bar)
barLabel.setBounds(170, 50, bar.getIconWidth(), bar.getIconHeight())
panel.add(rotLabel)
panel.add(minLabel)
panel.add(barLabel)
self.setTitle("Absolute")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(350, 300)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
panel.setLayout(None)Containers in Swing already have a default layout manager.
JPanel
has a FlowLayout
manager as its default layout manager. We use the setLayout()
method with a None parameter to remove the default layout manager and use absolute positioning instead. rot = ImageIcon("rotunda.jpg")We create an
rotLabel = JLabel(rot)
rotLabel.setBounds(20, 20, rot.getIconWidth(), rot.getIconHeight())
ImageIcon
object. We put the icon into the JLabel
component to display it. Then we use the setBounds()
method to position the label on the panel. The first two parameters are the x, y position of the label. The 3th and 4th parameters are the width and the height of the icon. panel.add(rotLabel)We add the label to the panel container.
Figure: Absolute positioning
Buttons example
In the following example, we will position two buttons in the bottom right corner of the window.#!/usr/local/bin/jythonWe will create two panels. The basic panel has a vertical box layout. The bottom panel has a horizontal one. We will put a bottom panel into the basic panel. We will right align the bottom panel. The space between the top of the window and the bottom panel is expandable. It is done by the vertical glue.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, use box layouts
to position two buttons in the
bottom right corner of the window
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Dimension
from javax.swing import JButton
from javax.swing import JFrame
from javax.swing import JPanel
from javax.swing import BoxLayout
from javax.swing import Box
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
basic = JPanel()
basic.setLayout(BoxLayout(basic, BoxLayout.Y_AXIS))
self.add(basic)
basic.add(Box.createVerticalGlue())
bottom = JPanel()
bottom.setAlignmentX(1.0)
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
okButton = JButton("OK")
closeButton = JButton("Close")
bottom.add(okButton)
bottom.add(Box.createRigidArea(Dimension(5, 0)))
bottom.add(closeButton)
bottom.add(Box.createRigidArea(Dimension(15, 0)))
basic.add(bottom)
basic.add(Box.createRigidArea(Dimension(0, 15)))
self.setTitle("Buttons")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(300, 150)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
basic = JPanel()The basic panel has a vertical box layout. The bottom panel has a horizontal box layout.
basic.setLayout(BoxLayout(basic, BoxLayout.Y_AXIS))
...
bottom = JPanel()
...
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
bottom.setAlignmentX(1.0)The bottom panel is right aligned.
basic.add(Box.createVerticalGlue())We create a vertical glue. The glue is vertically expandable white space, which will push the horizontal box with the buttons to the bottom.
okButton = JButton("OK")These are the two buttons, that will go into the bottom right corner of the window.
closeButton = JButton("Close")
bottom.add(okButton)We put the OK button into the horizontal box. We put some rigid space next to the button. So that there is some space between the two buttons.
bottom.add(Box.createRigidArea(Dimension(5, 0)))
basic.add(Box.createRigidArea(Dimension(0, 15)))We put some space between the buttons and the border of the window.
Figure: Buttons example
Windows example
The following example creates the windows dialog using theGroupLayout
manager. The dialog comes from the JDeveloper application. The
GroupLayout
manager divides the creation of the layout into two steps. In one step, we lay out components alongside the horizontal axis. In the second step, we lay out components along the vertical axis. This is an unusual idea within layout managers, but it works well. There are two types of arrangements. Sequential and parallel. In both kinds of layouts we can arrange components sequentially or in parallel. In a horizontal layout, a row of components is called a sequential group. A column of components is called a parallel group. In a vertical layout, a column of components is called a sequential group. And a row of components is called a parallel group. You must understand these definitions right in order to work with the
GroupLayout
manager. #!/usr/local/bin/jythonIn the above example, we see a chained calls of
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This code lays out components
using the GroupLayout manager
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Dimension
from java.awt import Color
from javax.swing import JButton
from javax.swing import SwingConstants
from javax.swing import JFrame
from javax.swing import JLabel
from javax.swing import JTextArea
from javax.swing import BorderFactory
from javax.swing import GroupLayout
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
layout = GroupLayout(self.getContentPane())
self.getContentPane().setLayout(layout)
layout.setAutoCreateGaps(True)
layout.setAutoCreateContainerGaps(True)
self.setPreferredSize(Dimension(350, 300))
windows = JLabel("Windows")
area = JTextArea()
area.setEditable(False)
area.setBorder(BorderFactory.createLineBorder(Color.gray))
activate = JButton("Activate")
close = JButton("Close")
help = JButton("Help")
ok = JButton("OK")
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(windows)
.addComponent(area)
.addComponent(help))
.addGroup(layout.createParallelGroup()
.addComponent(activate)
.addComponent(close)
.addComponent(ok))
)
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(windows)
.addGroup(layout.createParallelGroup()
.addComponent(area)
.addGroup(layout.createSequentialGroup()
.addComponent(activate)
.addComponent(close)))
.addGroup(layout.createParallelGroup()
.addComponent(help)
.addComponent(ok))
)
layout.linkSize(SwingConstants.HORIZONTAL, [ok, help, close, activate])
self.pack()
self.setTitle("Windows")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
addComponent()
methods. This is possible because the addComponent()
method returns the group on which it is called. Thanks to this, we do not need local variables to hold the groups. Also note, that the code is properly indented for better readability. layout.setHorizontalGroup(layout.createSequentialGroup()In the first step, we have a horizontal layout. It consists of two parallel groups of three components.
.addGroup(layout.createParallelGroup()
.addComponent(windows)
.addComponent(area)
.addComponent(help))
.addGroup(layout.createParallelGroup()
.addComponent(activate)
.addComponent(close)
.addComponent(ok))
)
layout.setVerticalGroup(layout.createSequentialGroup()Vertical layout is a bit more complex. First, we add a single component. Then we add a parallel group of a single component and a sequential group of two components. Finally, we add a parallel group of two components.
.addComponent(windows)
.addGroup(layout.createParallelGroup()
.addComponent(area)
.addGroup(layout.createSequentialGroup()
.addComponent(activate)
.addComponent(close)))
.addGroup(layout.createParallelGroup()
.addComponent(help)
.addComponent(ok))
)
layout.linkSize(SwingConstants.HORIZONTAL, [ok, help, close, activate])This line makes all buttons the same size. We only need to set their width, because their height is already the same by default.
Figure: Windows example
Look at the screenshot of the example. Notice, that components can be grouped into vertical and horizontal sets of components. For example, the label the area and the Help button component can form a vertical group of components. This is exactly what the GroupLayout
managers does. It lays out components by forming vertical and horizontal groups of components. In this part of the Jython Swing tutorial, we mentioned layout management of widgets.
No comments:
Post a Comment