Showing posts with label Jython Swing. Show all posts
Showing posts with label Jython Swing. Show all posts
Saturday, April 13, 2013
Nibbles Video Game in Jython Swing
Nibbles
In this part of the Jython Swing programming tutorial, we will create a Nibbles game clone.Nibbles is an older classic video game. It was first created in late 70s. Later it was brought to PCs. In this game the player controls a snake. The objective is to eat as many apples as possible. Each time the snake eats an apple, its body grows. The snake must avoid the walls and its own body.
Development
The size of each of the joints of a snake is 10px. The snake is controlled with the cursor keys. Initially, the snake has three joints. The game starts immediately. When the game is finished, we display "Game Over" message in the center of the window.import randomFirst we will define some constants used in our game.
from java.awt import Color
from java.awt import Font
from java.awt import Toolkit
from java.awt.event import ActionListener
from java.awt.event import KeyEvent
from java.awt.event import KeyListener
from javax.swing import ImageIcon
from javax.swing import JPanel
from javax.swing import Timer
WIDTH = 300
HEIGHT = 300
DOT_SIZE = 10
ALL_DOTS = WIDTH * HEIGHT / (DOT_SIZE * DOT_SIZE)
RAND_POS = 29
DELAY = 140
x = [0] * ALL_DOTS
y = [0] * ALL_DOTS
class Board(JPanel, KeyListener, ActionListener):
def __init__(self):
super(Board, self).__init__()
self.initUI()
def initUI(self):
self.setBackground(Color.black)
iid = ImageIcon("dot.png")
self.ball = iid.getImage()
iia = ImageIcon("apple.png")
self.apple = iia.getImage()
iih = ImageIcon("head.png")
self.head = iih.getImage()
self.setFocusable(True)
self.addKeyListener(self)
self.initGame()
def initGame(self):
self.left = False
self.right = True
self.up = False
self.down = False
self.inGame = True
self.dots = 3
for i in range(self.dots):
x[i] = 50 - i * 10
y[i] = 50
self.locateApple()
self.timer = Timer(DELAY, self)
self.timer.start()
def paint(self, g):
# due to bug, cannot call super()
JPanel.paint(self, g)
if self.inGame:
self.drawObjects(g)
else:
self.gameOver(g)
def drawObjects(self, g):
g.drawImage(self.apple, self.apple_x, self.apple_y, self)
for z in range(self.dots):
if (z == 0):
g.drawImage(self.head, x[z], y[z], self)
else:
g.drawImage(self.ball, x[z], y[z], self)
Toolkit.getDefaultToolkit().sync()
g.dispose()
def gameOver(self, g):
msg = "Game Over"
small = Font("Helvetica", Font.BOLD, 14)
metr = self.getFontMetrics(small)
g.setColor(Color.white)
g.setFont(small)
g.drawString(msg, (WIDTH - metr.stringWidth(msg)) / 2,
HEIGHT / 2)
def checkApple(self):
if x[0] == self.apple_x and y[0] == self.apple_y:
self.dots = self.dots + 1
self.locateApple()
def move(self):
z = self.dots
while z > 0:
x[z] = x[(z - 1)]
y[z] = y[(z - 1)]
z = z - 1
if self.left:
x[0] -= DOT_SIZE
if self.right:
x[0] += DOT_SIZE
if self.up:
y[0] -= DOT_SIZE
if self.down:
y[0] += DOT_SIZE
def checkCollision(self):
z = self.dots
while z > 0:
if z > 4 and x[0] == x[z] and y[0] == y[z]:
self.inGame = False
z = z - 1
if y[0] > HEIGHT - DOT_SIZE:
self.inGame = False
if y[0] < 0:
self.inGame = False
if x[0] > WIDTH - DOT_SIZE:
self.inGame = False
if x[0] < 0:
self.inGame = False
def locateApple(self):
r = random.randint(0, RAND_POS)
self.apple_x = r * DOT_SIZE
r = random.randint(0, RAND_POS)
self.apple_y = r * DOT_SIZE
# public void actionPerformed(ActionEvent e) {
def actionPerformed(self, e):
if self.inGame:
self.checkApple()
self.checkCollision()
self.move()
else:
self.timer.stop()
self.repaint()
def keyPressed(self, e):
key = e.getKeyCode()
if key == KeyEvent.VK_LEFT and not self.right:
self.left = True
self.up = False
self.down = False
if key == KeyEvent.VK_RIGHT and not self.left:
self.right = True
self.up = False
self.down = False
if key == KeyEvent.VK_UP and not self.down:
self.up = True
self.right = False
self.left = False
if key == KeyEvent.VK_DOWN and not self.up:
self.down = True
self.right = False
self.left = False
The
WIDTH and HEIGHT constants determine the size of the Board. The DOT_SIZE is the size of the apple and the dot of the snake. The ALL_DOTS constant defines the maximum number of possible dots on the Board. The RAND_POS constant is used to calculate a random position of an apple. The DELAY constant determines the speed of the game. x = [0] * ALL_DOTSThese two arrays store x, y coordinates of all possible joints of a snake.
y = [0] * ALL_DOTS
The
initGame() method initializes variables, loads images and starts a timeout function. def paint(self, g):Inside the
JPanel.paint(self, g)
if self.inGame:
self.drawObjects(g)
else:
self.gameOver(g)
paint() method, we check the inGame variable. If it is true, we draw our objects. The apple and the snake joints. Otherwise we display "Game over" text. def drawObjects(self, g):The
g.drawImage(self.apple, self.apple_x, self.apple_y, self)
for z in range(self.dots):
if (z == 0):
g.drawImage(self.head, x[z], y[z], self)
else:
g.drawImage(self.ball, x[z], y[z], self)
Toolkit.getDefaultToolkit().sync()
g.dispose()
drawObjects() method draws the apple and the joints of the snake. The first joint of a snake is its head, which is represented by a red circle. The Toolkit.getDefaultToolkit().sync() method ensures that the display is up-to-date. It is useful for animation. def checkApple(self):The
if x[0] == self.apple_x and y[0] == self.apple_y:
self.dots = self.dots + 1
self.locateApple()
checkApple() method checks, if the snake has hit the apple object. If so, we add another snake joint and call the locateApple() method, which randomly places a new apple object. In the
move() method we have the key algorithm of the game. To understand it, look at how the snake is moving. You control the head of the snake. You can change its direction with the cursor keys. The rest of the joints move one position up the chain. The second joint moves where the first was, the third joint where the second was etc. while z > 0:This code moves the joints up the chain.
x[z] = x[(z - 1)]
y[z] = y[(z - 1)]
z = z - 1
if self.left:Move the head to the left.
x[0] -= DOT_SIZE
In the
checkCollision() method, we determine if the snake has hit itself or one of the walls. while z > 0:Finish the game, if the snake hits one of its joints with the head.
if z > 4 and x[0] == x[z] and y[0] == y[z]:
self.inGame = False
z = z - 1
if y[0] > HEIGHT - DOT_SIZE:Finish the game, if the snake hits the bottom of the Board.
self.inGame = False
The
locateApple() method locates an apple randomly on the board. r = random.randint(0, RAND_POS)We get a random number from 0 to RAND_POS - 1.
self.apple_x = r * DOT_SIZEThese lines set the x, y coordinates of the apple object.
...
self.apple_y = r * DOT_SIZE
def actionPerformed(self, e):Every DELAY ms, the
if self.inGame:
self.checkApple()
self.checkCollision()
self.move()
else:
self.timer.stop()
self.repaint()
actionPerformed() method is called. If we are in the game, we call three methods, that build the logic of the game. Otherwise we stop the timer. In the
keyPressed() method of the Board class, we determine the keys that were pressed. if key == KeyEvent.VK_LEFT and not self.right:If we hit the left cursor key, we set
self.left = True
self.up = False
self.down = False
left variable to true. This variable is used in the move()method to change coordinates of the snake object. Notice also, that when the snake is heading to the right, we cannot turn immediately to the left. #!/usr/local/bin/jythonIn this class, we set up the Nibbles game.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This is a simple Nibbles game
clone.
author: Jan Bodnar
website: zetcode.com
last edited: December 2010
"""
from java.awt import Dimension
from javax.swing import JFrame
from Board import Board
class Nibbles(JFrame):
def __init__(self):
super(Nibbles, self).__init__()
self.initUI()
def initUI(self):
self.board = Board()
self.board.setPreferredSize(Dimension(300, 300))
self.add(self.board)
self.setTitle("Nibbles")
self.pack()
self.setResizable(False)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Nibbles()
Figure: Nibbles
This was the Nibbles computer game programmed with the Swing library and the Jython programming language.
Painting in Jython Swing
Painting
In this part of the Jython Swing programming tutorial we will do some painting.We use painting to create charts, custom components or create games. To do the painting, we use the painting API provided by the Swing toolkit. The painting is done within the
paintComponent() method. In the painting process, we use the Graphics2D object. It is a graphics context that allows an application to draw onto components. It is the fundamental class for rendering 2-dimensional shapes, text and images. Colors
A color is an object representing a combination of Red, Green, and Blue (RGB) intensity values. We use theColorclass to work with colors in Swing. #!/usr/local/bin/jythonIn the code example, we draw nine rectangles and fill them with different color values.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program draws ten
rectangles filled with different
colors.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Color
from javax.swing import JFrame
from javax.swing import JPanel
class Canvas(JPanel):
def __init__(self):
super(Canvas, self).__init__()
def paintComponent(self, g):
self.drawColorRectangles(g)
def drawColorRectangles(self, g):
g.setColor(Color(125, 167, 116))
g.fillRect(10, 15, 90, 60)
g.setColor(Color(42, 179, 231))
g.fillRect(130, 15, 90, 60)
g.setColor(Color(70, 67, 123))
g.fillRect(250, 15, 90, 60)
g.setColor(Color(130, 100, 84))
g.fillRect(10, 105, 90, 60)
g.setColor(Color(252, 211, 61))
g.fillRect(130, 105, 90, 60)
g.setColor(Color(241, 98, 69))
g.fillRect(250, 105, 90, 60)
g.setColor(Color(217, 146, 54))
g.fillRect(10, 195, 90, 60)
g.setColor(Color(63, 121, 186))
g.fillRect(130, 195, 90, 60)
g.setColor(Color(31, 21, 1))
g.fillRect(250, 195, 90, 60)
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.canvas = Canvas()
self.getContentPane().add(self.canvas)
self.setTitle("Colors")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(360, 300)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
def paintComponent(self, g):Custom painting is done in
paintComponent() in most cases. The g parameter is the graphics context. We call the painting operations on this object. g.setColor(Color(125, 167, 116))We set the context's current color to the specified color. All subsequent graphics operations using this graphics context use this specified color.
g.fillRect(10, 15, 90, 60)We fill a rectangle located at x=10, y=15 having width=90 and height=60 with the above specified color value.
Figure: Colors
Shapes
The Swing painting API can draw various shapes. The following programming code example will show some of them.#!/usr/local/bin/jythonIn this code example, we draw six different shapes on the window. A square, a rectangle, a rounded rectangle, an ellipse, an arc and an oval. We do not draw outlines of the shapes, but we fill the inner space of the shapes with a gray color.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program draws basic shapes
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Color
from java.awt import RenderingHints
from java.awt.geom import Ellipse2D
from javax.swing import JFrame
from javax.swing import JPanel
class Canvas(JPanel):
def __init__(self):
super(Canvas, self).__init__()
def paintComponent(self, g):
self.drawShapes(g)
def drawShapes(self, g):
g.setColor(Color(150, 150, 150))
rh = RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON)
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
g.setRenderingHints(rh)
g.fillRect(20, 20, 50, 50)
g.fillRect(120, 20, 90, 60)
g.fillRoundRect(250, 20, 70, 60, 25, 25)
g.fill(Ellipse2D.Double(10, 100, 80, 100))
g.fillArc(120, 130, 110, 100, 5, 150)
g.fillOval(270, 130, 50, 50)
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.canvas = Canvas()
self.getContentPane().add(self.canvas)
self.setTitle("Shapes")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(350, 250)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
rh = RenderingHints(RenderingHints.KEY_ANTIALIASING,With the rendering hints, we control the quality of the painting. In the above code, we implement antialiasing. With antialiasing, the shapes are more smooth.
RenderingHints.VALUE_ANTIALIAS_ON)
g.setColor(Color(150, 150, 150))We will be painting in some gray color.
g.fillRect(20, 20, 50, 50)Here we draw a rectangle, a square and a rounded rectangle. The first four parameters in these methods are the x, y coordinates and width and height. The last two parameters for the
g.fillRect(120, 20, 90, 60)
g.fillRoundRect(250, 20, 70, 60, 25, 25)
fillRoundRect()are the horizontal and vertical diameter of the arc at the four corners. g.fill(Ellipse2D.Double(10, 100, 80, 100))These three lines draw an ellipse, an arc and an oval.
g.fillArc(120, 130, 110, 100, 5, 150)
g.fillOval(270, 130, 50, 50)
Figure: Shapes
Transparent rectangles
Transparency is the quality of being able to see through a material. The easiest way to understand transparency is to imagine a piece of glass or water. Technically, the rays of light can go through the glass and this way we can see objects behind the glass.In computer graphics, we can achieve transparency effects using alpha compositing. Alpha compositing is the process of combining an image with a background to create the appearance of partial transparency. The composition process uses an alpha channel. (wikipedia.org, answers.com)
"""In the example we will draw ten rectangles with different levels of transparency.
ZetCode Jython Swing tutorial
This program draws ten
rectangles with different
levels of transparency.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import AlphaComposite
from java.awt import Color
from javax.swing import JFrame
from javax.swing import JPanel
class Canvas(JPanel):
def __init__(self):
super(Canvas, self).__init__()
def paintComponent(self, g):
self.drawRectangles(g)
def drawRectangles(self, g):
g.setColor(Color.BLUE)
for i in range(1, 11):
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
i * 0.1))
g.fillRect(50 * i, 20, 40, 40)
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.canvas = Canvas()
self.getContentPane().add(self.canvas)
self.setTitle("Transparent rectangles")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(590, 120)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, i * 0.1))The
AlphaComposite class implements basic alpha compositing rules. Figure: Transparent rectangles
Donut Shape
In the following example we create a complex shape by rotating a bunch of ellipses. An affine transform is composed of zero or more linear transformations (rotation, scaling or shear) and translation (shift). TheAffineTransformis the class in Swing to perform affine transformations. #!/usr/local/bin/jythonIn this example, we create a donut. The shape resembles a cookie, hence the name donut. The donut is centered in the window.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we create a donut
shape.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BasicStroke
from java.awt import Color
from java.awt import RenderingHints
from java.awt.geom import AffineTransform
from java.awt.geom import Ellipse2D
from javax.swing import JFrame
from javax.swing import JPanel
import math
class Canvas(JPanel):
def __init__(self):
super(Canvas, self).__init__()
def paintComponent(self, g):
self.drawDonutShape(g)
def drawDonutShape(self, g):
rh = RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON)
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
g.setRenderingHints(rh)
size = self.getSize()
w = size.getWidth()
h = size.getHeight()
e = Ellipse2D.Double(0, 0, 80, 130)
g.setStroke(BasicStroke(1))
g.setColor(Color.gray)
for deg in range(0, 360, 5):
at = AffineTransform.getTranslateInstance(w / 2, h / 2)
at.rotate(math.radians(deg))
g.draw(at.createTransformedShape(e))
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.canvas = Canvas()
self.getContentPane().add(self.canvas)
self.setTitle("Donut")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(350, 320)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
size = self.getSize()Here we determine the width and height of the window. We need these values to center the donut shape.
w = size.getWidth()
h = size.getHeight()
e = Ellipse2D.Double(0, 0, 80, 130)We create an ellipse shape. We will rotate this ellipse to create the donut shape.
g.setStroke(BasicStroke(1))We set the stroke and the color for the outlines of the shapes.
g.setColor(Color.gray)
for deg in range(0, 360, 5):We draw an ellipse object 72 times. Each time, we rotate the ellipse by additional 5 degrees. This will create our donut shape.
at = AffineTransform.getTranslateInstance(w / 2, h / 2)With the help of the
at.rotate(math.radians(deg))
g.draw(at.createTransformedShape(e))
AffineTransform class we translate the drawing to the center of the window. Then we do rotation. The createTransformedShape() method will apply these affine transforms to the ellipse. And the transformed ellipse is drawn using the draw() method. Drawing text
In the last example, we are going to draw text on the window.#!/usr/local/bin/jythonWe draw a lyrics of a song on the window.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program draws lyrics of a
song on the window.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Font
from java.awt import RenderingHints
from javax.swing import JFrame
from javax.swing import JPanel
class Canvas(JPanel):
def __init__(self):
super(Canvas, self).__init__()
def paintComponent(self, g):
self.drawLyrics(g)
def drawLyrics(self, g):
rh = RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
g.setRenderingHints(rh)
g.setFont(Font("Purisa", Font.PLAIN, 13))
g.drawString("Most relationships seem so transitory", 20, 30)
g.drawString("They're all good but not the permanent one", 20, 60)
g.drawString("Who doesn't long for someone to hold", 20, 90)
g.drawString("Who knows how to love you without being told", 20, 120)
g.drawString("Somebody tell me why I'm on my own", 20, 150)
g.drawString("If there's a soulmate for everyone", 20, 180)
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.canvas = Canvas()
self.getContentPane().add(self.canvas)
self.setTitle("Soulmate")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(400, 250)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
rh = RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING,We apply text antialiasing on the painting.
RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
g.setRenderingHints(rh)
g.setFont(Font("Purisa", Font.PLAIN, 13))
We specify the font name, style and point size, in which we draw the lyrics. g.drawString("Most relationships seem so transitory", 20, 30)
The drawString() method draws the text. Figure: Drawing text
In this part of the Jython Swing programming tutorial, we did some painting.
Dialogs in Jython Swing
Dialogs
In this part of the Jython Swing programming tutorial, we will work with dialogs.Dialog windows or dialogs are an indispensable part of most modern GUI applications. A dialog is defined as a conversation between two or more persons. In a computer application a dialog is a window which is used to "talk" to the application. A dialog is used to input data, modify data, change the application settings etc. Dialogs are important means of communication between a user and a computer program.
Message boxes
Message boxes are convenient dialogs that provide messages to the user of the application. The message consists of text and image data.#!/usr/local/bin/jythonWe use the
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we show various
message boxes.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import GridLayout
from javax.swing import JButton
from javax.swing import JFrame
from javax.swing import JOptionPane
from javax.swing import JPanel
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.panel = JPanel()
self.panel.setLayout(GridLayout(2, 2))
error = JButton("Error", actionPerformed=self.onError)
warning = JButton("Warning", actionPerformed=self.onWarning)
question = JButton("Question", actionPerformed=self.onQuestion)
inform = JButton("Information", actionPerformed=self.onInform)
self.panel.add(error)
self.panel.add(warning)
self.panel.add(question)
self.panel.add(inform)
self.add(self.panel)
self.setTitle("Message boxes")
self.setSize(300, 200)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onError(self, e):
JOptionPane.showMessageDialog(self.panel, "Could not open file",
"Error", JOptionPane.ERROR_MESSAGE)
def onWarning(self, e):
JOptionPane.showMessageDialog(self.panel, "A deprecated call",
"Warning", JOptionPane.WARNING_MESSAGE)
def onQuestion(self, e):
JOptionPane.showMessageDialog(self.panel, "Are you sure to quit?",
"Question", JOptionPane.QUESTION_MESSAGE)
def onInform(self, e):
JOptionPane.showMessageDialog(self.panel, "Download completed",
"Information", JOptionPane.INFORMATION_MESSAGE)
if __name__ == '__main__':
Example()
GridLayout manager to set up a grid of four buttons. Each of the buttons shows a different message box. def onError(self, e):In case we pressed the error button, we show the error dialog. We use the
JOptionPane.showMessageDialog(self.panel, "Could not open file",
"Error", JOptionPane.ERROR_MESSAGE)
showMessageDialog() method to show the dialog on the screen. The first parameter of this method is the frame, in which the dialog is displayed. The second parameter is the message to be displayed. The third parameter is the title of the dialog. The final parameter is the message type. The default icon is determined by the message type. In our case, we have ERROR_MESSAGE message type for the error dialog. Figure: Error message dialog
JColorChooser
TheJColorChooser is a standard dialog for selecting a color. #!/usr/local/bin/jythonIn the example, we have a white panel in the center of the window. We will change the background color of the panel by selecting a color from the color chooser dialog.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we use the
JColorChooser to change the color
of a panel.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from java.awt import Color
from javax.swing import BorderFactory
from javax.swing import JColorChooser
from javax.swing import JButton
from javax.swing import JToolBar
from javax.swing import JPanel
from javax.swing import JFrame
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.panel = JPanel()
self.panel.setLayout(BorderLayout())
toolbar = JToolBar()
openb = JButton("Choose color", actionPerformed=self.onClick)
toolbar.add(openb)
self.display = JPanel()
self.display.setBackground(Color.WHITE)
self.panel.setBorder(BorderFactory.createEmptyBorder(30, 50, 30, 50))
self.panel.add(self.display)
self.add(self.panel)
self.add(toolbar, BorderLayout.NORTH)
self.setTitle("Color chooser")
self.setSize(300, 250)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onClick(self, e):
clr = JColorChooser()
color = clr.showDialog(self.panel, "Choose Color", Color.white)
self.display.setBackground(color)
if __name__ == '__main__':
Example()
clr = JColorChooser()This code shows a color chooser dialog. The
color = clr.showDialog(self.panel, "Choose Color", Color.white)
self.display.setBackground(color)
showDialog() method returns the selected color value. We change the display panel background to the newly selected color. Figure: ColorDialog
JFileChooser
JFileChooser dialog allows user to select a file from the filesystem.#!/usr/local/bin/jythonIn our code example, we use the
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we use the
JFileChooser to select a file from
a filesystem.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from javax.swing import BorderFactory
from javax.swing import JFileChooser
from javax.swing import JTextArea
from javax.swing import JScrollPane
from javax.swing import JButton
from javax.swing import JToolBar
from javax.swing import JPanel
from javax.swing import JFrame
from javax.swing.filechooser import FileNameExtensionFilter
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.panel = JPanel()
self.panel.setLayout(BorderLayout())
toolbar = JToolBar()
openb = JButton("Choose file", actionPerformed=self.onClick)
toolbar.add(openb)
self.area = JTextArea()
self.area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))
pane = JScrollPane()
pane.getViewport().add(self.area)
self.panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))
self.panel.add(pane)
self.add(self.panel)
self.add(toolbar, BorderLayout.NORTH)
self.setTitle("File chooser")
self.setSize(300, 250)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onClick(self, e):
chooseFile = JFileChooser()
filter = FileNameExtensionFilter("c files", ["c"])
chooseFile.addChoosableFileFilter(filter)
ret = chooseFile.showDialog(self.panel, "Choose file")
if ret == JFileChooser.APPROVE_OPTION:
file = chooseFile.getSelectedFile()
text = self.readFile(file)
self.area.setText(text)
def readFile(self, file):
filename = file.getCanonicalPath()
f = open(filename, "r")
text = f.read()
return text
if __name__ == '__main__':
Example()
JFileChooser dialog to select a C file and display its contents in a JTextArea. self.area = JTextArea()This is the
JTextArea in which we will show the contents of a selected file. chooseFile = JFileChooser()We create an instance of the
filter = FileNameExtensionFilter("c files", ["c"])
chooseFile.addChoosableFileFilter(filter)
JFileChooser dialog. We create a filter which will show only C files. ret = chooseFile.showDialog(self.panel, "Choose file")The dialog is shown on the screen. We get the return value.
if ret == JFileChooser.APPROVE_OPTION:If the user has selected a file, we get the name of the file. Read its contents and set the text to the text area component.
file = chooseFile.getSelectedFile()
text = self.readFile(file)
self.area.setText(text)
def readFile(self, file):This code reads the text from the file. The
filename = file.getCanonicalPath()
f = open(filename, "r")
text = f.read()
return text
getCanonicalPath()returns an absolute file name. Figure: JFileChooser
In this part of the Jython Swing tutorial, we worked with dialog windows.
Menus And toolbars in Jython Swing
Menus & toolbars
In this part of the Jython Swing programming tutorial, we will work with menus and toolbar.A menubar is one of the most visible parts of the GUI application. It is a group of commands located in various menus. While in console applications you had to remember all those arcane commands, here we have most of the commands grouped into logical parts. There are accepted standards that further reduce the amount of time spending to learn a new application. Menus group commands that we can use in an application. Toolbars provide a quick access to the most frequently used commands.
Simple menu
The first example will show a simple menu.#!/usr/local/bin/jythonOur example will show a menu with one item. By selecting the exit menu item we close the application.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program creates a simple
menu.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt.event import KeyEvent
from java.lang import System
from javax.swing import ImageIcon
from javax.swing import JFrame
from javax.swing import JMenu
from javax.swing import JMenuBar
from javax.swing import JMenuItem
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
menubar = JMenuBar()
icon = ImageIcon("exit.png")
file = JMenu("File")
file.setMnemonic(KeyEvent.VK_F)
fileExit = JMenuItem("Exit", icon,
actionPerformed=self.onSelect)
fileExit.setMnemonic(KeyEvent.VK_C)
fileExit.setToolTipText("Exit application")
file.add(fileExit)
menubar.add(file)
self.setJMenuBar(menubar)
self.setTitle("Simple menu")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(250, 200)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onSelect(self, e):
System.exit(0)
if __name__ == '__main__':
Example()
menubar = JMenuBar()Here we create a menubar.
icon = ImageIcon("exit.png")
We will display an icon in the menu item. file = JMenu("File")
file.setMnemonic(KeyEvent.VK_F)
We create a menu object. A menu is a popup window containing JMenuItems. Menus are located on the menubar. The menus can be accessed via the keybord as well. To bind a menu to a particular key, we use the setMnemonic() method. In our case, the menu can be opened with the ALT + F shortcut. fileExit = JMenuItem("Exit", icon,
actionPerformed=self.onSelect)
fileExit.setMnemonic(KeyEvent.VK_C)
fileExit.setToolTipText("Exit application")
Here we create a JMenuItem. A menu item is an object shown in a popup window of the selected menu. We also provide a shortcut for the menu item and a tooltip as well. file.add(fileExit)A menu item is added to the menu.
menubar.add(file)A menu is added to the menubar.
Figure: Simple menu
Submenu
A submenu is a menu plugged into another menu object. The next example demonstrates this.#!/usr/local/bin/jythonIn the example, we have three options in a submenu of a file menu.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program creates a simple
submenu.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.lang import System
from java.awt.event import KeyEvent
from java.awt.event import ActionEvent
from javax.swing import JFrame
from javax.swing import JMenuBar
from javax.swing import JMenuItem
from javax.swing import JMenu
from javax.swing import ImageIcon
from javax.swing import KeyStroke
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
menubar = JMenuBar()
iconNew = ImageIcon("new.png")
iconOpen = ImageIcon("open.png")
iconSave = ImageIcon("save.png")
iconExit = ImageIcon("exit.png")
file = JMenu("File")
file.setMnemonic(KeyEvent.VK_F)
imp = JMenu("Import")
imp.setMnemonic(KeyEvent.VK_M)
newsf = JMenuItem("Import newsfeed list...")
bookm = JMenuItem("Import bookmarks...")
mail = JMenuItem("Import mail...")
imp.add(newsf)
imp.add(bookm)
imp.add(mail)
fileNew = JMenuItem("New", iconNew)
fileNew.setMnemonic(KeyEvent.VK_N)
fileOpen = JMenuItem("Open", iconOpen)
fileNew.setMnemonic(KeyEvent.VK_O)
fileSave = JMenuItem("Save", iconSave)
fileSave.setMnemonic(KeyEvent.VK_S)
fileExit = JMenuItem("Exit", iconExit,
actionPerformed=self.onSelect)
fileExit.setMnemonic(KeyEvent.VK_C)
fileExit.setToolTipText("Exit application")
fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
ActionEvent.CTRL_MASK))
file.add(fileNew)
file.add(fileOpen)
file.add(fileSave)
file.addSeparator()
file.add(imp)
file.addSeparator()
file.add(fileExit)
menubar.add(file)
self.setJMenuBar(menubar)
self.setTitle("Submenu")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(320, 220)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onSelect(self, e):
System.exit(0)
if __name__ == '__main__':
Example()
imp = JMenu("Import")
...
file.add(imp)
A submenu is just like any other normal menu. It is created the same way. We simply add a menu to existing menu. fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,An accelerator is a key shortcut that launches a menu item. In our case, by pressing Ctrl + W we close the application.
ActionEvent.CTRL_MASK))
file.addSeparator()A separator is a horizontal line that visually separates the menu items. This way we can group items into some logical places.
Figure: Submenu
Popup menu
In the next example, we create a popup menu.#!/usr/local/bin/jythonIn our example, we create a popup menu with two menu items.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program creates a popup menu.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt.event import MouseListener
from java.lang import System
from javax.swing import JFrame
from javax.swing import JMenuItem
from javax.swing import JPopupMenu
class Example(JFrame, MouseListener):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.menu = JPopupMenu()
menuItemBeep = JMenuItem("Beep", actionPerformed=self.onBeep)
self.menu.add(menuItemBeep)
menuItemClose = JMenuItem("Exit", actionPerformed=self.onExit)
self.menu.add(menuItemClose);
self.addMouseListener(self)
self.setTitle("Popup menu")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(250, 200)
self.setLocationRelativeTo(None)
self.setVisible(True)
def mouseReleased(self, e):
if e.getButton() == e.BUTTON3:
self.menu.show(e.getComponent(), e.getX(), e.getY())
def onExit(self, e):
System.exit(0)
def onBeep(self, e):
toolkit = self.getToolkit()
toolkit.beep()
if __name__ == '__main__':
Example()
self.menu = JPopupMenu()We create a popup menu and a menu item.
menuItemBeep = JMenuItem("Beep", actionPerformed=self.onBeep)
def mouseReleased(self, e):We show the popup menu window at the x, y coordinates of the mouse click.
if e.getButton() == e.BUTTON3:
self.menu.show(e.getComponent(), e.getX(), e.getY())
Figure: Popup menu
JToolbar
Menus group commands that we can use in an application. Toolbars provide a quick access to the most frequently used commands. In Swing, theJToolBar class creates a toolbar in an application. #!/usr/local/bin/jythonThe example creates a toolbar with one exit button.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program, we create a simple
toolbar.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from java.lang import System
from javax.swing import ImageIcon
from javax.swing import JFrame
from javax.swing import JMenu
from javax.swing import JMenuBar
from javax.swing import JToolBar
from javax.swing import JButton
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
menubar = JMenuBar()
file = JMenu("File")
menubar.add(file)
self.setJMenuBar(menubar)
toolbar = JToolBar()
icon = ImageIcon("exit.png")
exitButton = JButton(icon, actionPerformed=self.onClick)
toolbar.add(exitButton)
self.add(toolbar, BorderLayout.NORTH)
self.setTitle("Toolbar")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(350, 250)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onClick(self, e):
System.exit(0)
if __name__ == '__main__':
Example()
toolbar = JToolBar()A toolbar is created.
exitButton = JButton(icon, actionPerformed=self.onClick)We create a button and add it to the toolbar.
toolbar.add(exitButton)
self.add(toolbar, BorderLayout.NORTH)The toolbar is placed into the north part of the
BorderLayoutmanager. Figure: Toolbar
In this part of the Jython Swing tutorial, we mentioned menus and toolbars.
Components in Jython Swing
Components
In this part of the Jython Swing programming tutorial, we will cover basic Swing components.Components are basic building blocks of a GUI application. Over the years, several components became a standard in all toolkits on all OS platforms. For example a button, a check box or a scroll bar. Swing has a rich set of components which cover most of the programming needs. More specialized components can be created as custom components.
JCheckBox
The JCheckBox is a component, that has two states. On and Off. The On state is visualized by a check mark. It is used to denote some boolean property. The JCheckBox component provides a check box with a text label.#!/usr/local/bin/jythonIn our example, we place a check box on the window. The check box shows/hides the title of the window.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program uses JCheckBox
component to show/hide the title
of the window
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Dimension
from javax.swing import Box
from javax.swing import BoxLayout
from javax.swing import JCheckBox
from javax.swing import JFrame
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setLayout(BoxLayout(self.getContentPane(), BoxLayout.Y_AXIS))
self.add(Box.createRigidArea(Dimension(15, 20)))
cb = JCheckBox("Show Title", True, actionPerformed=self.onSelect)
cb.setFocusable(False)
self.add(cb)
self.setTitle("JCheckBox example")
self.setSize(280, 200)
self.setResizable(False)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onSelect(self, e):
source = e.getSource()
isSelected = source.isSelected()
if isSelected:
self.setTitle("JCheckBox example")
else:
self.setTitle("")
if __name__ == '__main__':
Example()
self.setLayout(BoxLayout(self.getContentPane(), BoxLayout.Y_AXIS))In this example, we use a
self.add(Box.createRigidArea(Dimension(15, 20)))
BoxLayout layout manager. We put some space there, so that the check box is not too close to the corner. cb = JCheckBox("Show Title", True, actionPerformed=self.onSelect)
The JCheckBox component is created. The first parameter of the constructor is its text label. The second parameter is a boolean value indicating the initial selection state. If True the check box is selected. The third parameter specifies the method, which is called when we select or unselect the check box. cb.setFocusable(False)We disable the focus for the check box. A
JCheckBox that has a focus may be selected or unselected with a spacebar. source = e.getSource()From the event object, we get the source component. In our case is the a check box. We find out the selection state of the check box. Depending on the state of the check box, we show or hide the title of the window.
isSelected = source.isSelected()
if isSelected:
self.setTitle("JCheckBox example")
else:
self.setTitle("")
Figure: JCheckBox
JLabel
TheJLabel component is used to display text, image or both. No user interaction is available. #!/usr/local/bin/jythonOur example shows lyrics of a song in the window. We can use HTML tags in
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program uses JLabel component to
show lyrics of a song
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from java.awt import Font
from javax.swing import BorderFactory
from javax.swing import JFrame
from javax.swing import JLabel
from javax.swing import JPanel
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
lyrics = """<html>It's way too late to think of<br>
Someone I would call now<br>
And neon signs got tired<br>
Red eye flights help the stars out<br>
I'm safe in a corner<br>
Just hours before me<br>
<br>
I'm waking with the roaches<br>
The world has surrendered<br>
I'm dating ancient ghosts<br>
The ones I made friends with<br>
The comfort of fireflies<br>
Long gone before daylight<br>
<br>
And if I had one wishful field tonight<br>
I'd ask for the sun to never rise<br>
If God leant his voice for me to speak<br>
I'd say go to bed, world<br>
<br>
I've always been too late<br>
To see what's before me<br>
And I know nothing sweeter than<br>
Champaign from last New Years<br>
Sweet music in my ears<br>
And a night full of no fears<br>
<br>
But if I had one wishful field tonight<br>
I'd ask for the sun to never rise<br>
If God passed a mic to me to speak<br>
I'd say stay in bed, world<br>
Sleep in peace</html>"""
panel = JPanel()
panel.setLayout(BorderLayout(10, 10))
label = JLabel(lyrics)
label.setFont(Font("Georgia", Font.PLAIN, 14))
panel.add(label, BorderLayout.CENTER)
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))
self.add(panel)
self.pack()
self.setTitle("No Sleep")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
JLabel component. We use the <br> tag to separate lines. lyrics = """<html>It's way too late to think of<br>We define a multi line text.
Someone I would call now<br>
And neon signs got tired<br>
...
label = JLabel(lyrics)Here we create the label component. We set its font to plain Georgia, 14 px tall.
label.setFont(Font("Georgia", Font.PLAIN, 14))
panel.add(label, BorderLayout.CENTER)We put the label into the center of the panel. We put 10px around the label.
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))
Figure: JLabel component
JSlider
JSlider is a component that lets the user graphically select a value by sliding a knob within a bounded interval. Our example will show a volume control. #!/usr/local/bin/jythonIn the code example, we show a
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
In this program we use the JSlider
component to create a volume control
user interface
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from java.awt import Dimension
from javax.swing import BorderFactory
from javax.swing import Box
from javax.swing import BoxLayout
from javax.swing import ImageIcon
from javax.swing import JFrame
from javax.swing import JLabel
from javax.swing import JPanel
from javax.swing import JSlider
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.mute = ImageIcon("mute.png")
self.min = ImageIcon("min.png")
self.med = ImageIcon("med.png")
self.max = ImageIcon("max.png")
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.X_AXIS))
panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40))
self.setLayout(BorderLayout())
panel.add(Box.createHorizontalGlue())
slider = JSlider(0, 150, 0, stateChanged=self.onSlide)
slider.setPreferredSize(Dimension(150, 30))
panel.add(slider)
panel.add(Box.createRigidArea(Dimension(5, 0)))
self.label = JLabel(self.mute, JLabel.CENTER)
panel.add(self.label)
panel.add(Box.createHorizontalGlue())
self.add(panel, BorderLayout.CENTER)
self.pack()
self.setTitle("JSlider")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onSlide(self, e):
sender = e.getSource()
value = sender.getValue()
if value == 0:
self.label.setIcon(self.mute)
elif value > 0 and value <= 30:
self.label.setIcon(self.min)
elif value > 30 and value < 80:
self.label.setIcon(self.med)
else:
self.label.setIcon(self.max)
if __name__ == '__main__':
Example()
JSlider and a JLabel. By dragging the slider, we change the icon on the label component. We have four images that represent various states of the sound. self.mute = ImageIcon("mute.png")
Here we create an image icon. panel.setLayout(BoxLayout(panel, BoxLayout.X_AXIS))Panel component has a horizontal
BoxLayout. panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40))We creare a 40px border around the panel.
panel.add(Box.createHorizontalGlue())We put resizable space to bo both sides, left and right. It is to prevent
JSlider from growing to unnatural sizes. slider = JSlider(0, 150, 0, stateChanged=self.onSlide)This is a
JSlider constructor. The parameters are minimum value, maximum value and current value. When we slide the knob of the slider, the onSlide() method is being called. panel.add(Box.createRigidArea(Dimension(5, 0)))We place a 5px rigid space between the two components. They are too close to each other, when the slider is at the end position.
self.label = JLabel(self.mute, JLabel.CENTER)This line creates a
JLabel instance with the specified image and horizontal alignment. The label is centered vertically in its display area by default. Figure: JSlider component
JToggleButton
JToggleButton is a button that has two states. Pressed and not pressed. You toggle between these two states by clicking on it. There are situations where this functionality fits well. #!/usr/local/bin/jythonIn the code example, we use three toggle buttons to change the color of a rectangular component.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program uses toggle buttons to
change the background color of
a panel
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import Color
from java.awt import Dimension
from javax.swing import BorderFactory
from javax.swing import Box
from javax.swing import BoxLayout
from javax.swing import JFrame
from javax.swing import JPanel
from javax.swing import JToggleButton
from javax.swing.border import LineBorder
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setPreferredSize(Dimension(280, 200))
bottom = JPanel()
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
bottom.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20))
leftPanel = JPanel()
leftPanel.setLayout(BoxLayout(leftPanel, BoxLayout.Y_AXIS))
redButton = JToggleButton("red", actionPerformed=self.onToggle)
greenButton = JToggleButton("green", actionPerformed=self.onToggle)
blueButton = JToggleButton("blue", actionPerformed=self.onToggle)
blueButton.setMaximumSize(greenButton.getMaximumSize())
redButton.setMaximumSize(greenButton.getMaximumSize())
leftPanel.add(redButton)
leftPanel.add(Box.createRigidArea(Dimension(25, 7)))
leftPanel.add(greenButton)
leftPanel.add(Box.createRigidArea(Dimension(25, 7)))
leftPanel.add(blueButton)
bottom.add(leftPanel)
bottom.add(Box.createRigidArea(Dimension(20, 0)))
self.display = JPanel()
self.display.setPreferredSize(Dimension(110, 110))
self.display.setBorder(LineBorder.createGrayLineBorder())
self.display.setBackground(Color.black)
bottom.add(self.display)
self.add(bottom)
self.pack()
self.setTitle("JToggleButton")
self.setResizable(False)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onToggle(self, e):
color = self.display.getBackground()
red = color.getRed()
green = color.getGreen()
blue = color.getBlue()
if e.getActionCommand() == "red":
if red == 0:
red = 255
else:
red = 0
if e.getActionCommand() == "green":
if green == 0:
green = 255
else:
green = 0
if e.getActionCommand() == "blue":
if blue == 0:
blue = 255
else:
blue = 0
setCol = Color(red, green, blue)
self.display.setBackground(setCol)
if __name__ == '__main__':
Example()
redButton = JToggleButton("red", actionPerformed=self.onToggle)
We create a JToggleButton component. When we click on the button, the onToggle() method is launched. blueButton.setMaximumSize(greenButton.getMaximumSize())We make all three buttons of equal size.
redButton.setMaximumSize(greenButton.getMaximumSize())
color = self.display.getBackground()We determine the current red, green, blue parts of the display background color.
red = color.getRed()
green = color.getGreen()
blue = color.getBlue()
if e.getActionCommand() == "red":We determine, which button was toggled, and update the color part of the RGB value accordingly.
if red == 0:
red = 255
else:
red = 0
setCol = Color(red, green, blue)Here a new color is created and the display panel is updated to a new color.
self.display.setBackground(setCol)
Figure: JToggleButton component
JList
JList is a component that displays a list of objects. It allows the user to select one or more items. #!/usr/local/bin/jythonIn our example, we will display a
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program shows all system fonts
in a JList component
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.awt import BorderLayout
from java.awt import Dimension
from java.awt import Font
from java.awt import GraphicsEnvironment
from javax.swing import JFrame
from javax.swing import BorderFactory
from javax.swing import JScrollPane
from javax.swing import JPanel
from javax.swing import JLabel
from javax.swing import JList
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
panel = JPanel()
panel.setLayout(BorderLayout())
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20))
ge = GraphicsEnvironment.getLocalGraphicsEnvironment()
fonts = ge.getAvailableFontFamilyNames()
list = JList(fonts, valueChanged=self.onChanged)
pane = JScrollPane()
pane.getViewport().add(list)
pane.setPreferredSize(Dimension(250, 200))
panel.add(pane)
self.label = JLabel("Aguirre, der Zorn Gottes")
self.label.setFont(Font("Serif", Font.PLAIN, 12))
self.add(self.label, BorderLayout.SOUTH)
self.add(panel)
self.pack()
self.setTitle("JList")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onChanged(self, e):
sender = e.getSource()
if not e.getValueIsAdjusting():
name = sender.getSelectedValue()
font = Font(name, Font.PLAIN, 13)
self.label.setFont(font)
if __name__ == '__main__':
Example()
JList and a JLabel components. The list component contains a list of all available font family names on our system. If we select an item from the list, the label will be displayed in a font, we have chosen. ge = GraphicsEnvironment.getLocalGraphicsEnvironment()Here we obtain all possible font family names on our system.
fonts = ge.getAvailableFontFamilyNames()
list = JList(fonts, valueChanged=self.onChanged)We create an instance of the
JList component. If we select an option from the list, the onChanged() method is called. if not e.getValueIsAdjusting():Events in list selection are grouped. We receive events for both selecting and deselecting. To filter only the selecting events, we use the
getValueIsAdjusting() method. name = sender.getSelectedValue()We get the selected item and set a new font for the label.
font = Font(name, Font.PLAIN, 13)
self.label.setFont(font)
pane = JScrollPane()
pane.getViewport().add(list)
JList component is not scrollable by default. We put the list into the JScrollPane to make it scrollable. Figure: JList component
In this part of the Jython Swing tutorial, we have presented several Swing components.
Layout management in Jython Swing
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.
JPanelhas 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")
rotLabel = JLabel(rot)
rotLabel.setBounds(20, 20, rot.getIconWidth(), rot.getIconHeight())
We create an ImageIcon object. We put the icon into the JLabelcomponent 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")
closeButton = JButton("Close")
These are the two buttons, that will go into the bottom right corner of the window. 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.
Introduction to Jython Swing
Introduction to Jython Swing
In this part of the Jython Swing tutorial, we will introduce the Swing toolkit and create our first programs using the Jython programming language.The purpose of this tutorial is to get you started with the Swing toolkit with the Jython language. Images used in this tutorial can be downloaded here. I used some icons from the Tango icons pack of the Gnome project.
About
Swing library is an official Java GUI toolkit for the Java programming language. It is used to create Graphical user interfaces with Java. Swing is an advanced GUI toolkit. It has a rich set of components. From basic ones like buttons, labels, scrollbars to advanced components like trees and tables. Swing itself is written in Java. Swing is available for other languages too. For example Jython, JRuby, Groovy or Scala.Jython is an implementation of the Python programming language written in Java. Jython can import any Java class.
There are two basic ways to execute the examples in this tutorial. One way is to install a Python NetBeans plugin. It contains Jython as well. When you create a new Python project, be sure to select the Jython platform.
The other way is to download an installer from the jython.orgwebsite.
$ java -jar jython_installer-2.5.2rc2.jarWe install the Jython. You go through a series of dialogs.
$ java -jar jython.jar simple.pyWe have installed Jython in a selected directory. In this directory, we will find jython.jar file, which is used to execute Jython scripts.
$ cat /usr/local/bin/jythonOptionally, we can create a bash file which will automatically start our Jython scripts. We can then put the #!/usr/bin/local/jython path to our scripts.
#!/bin/bash
/home/vronskij/bin/jdk1.6.0_21/bin/java -jar /home/vronskij/bin/jython/jython.jar $1
Simple example
In our first example, we will show a basic window on the screen.#!/usr/local/bin/jythonWhile this code is very small, the application window can do quite a lot. It can be resized, maximized, minimized. All the complexity that comes with it has been hidden from the application programmer.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This example shows a simple
window on the screen.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from javax.swing import JFrame
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setTitle("Simple")
self.setSize(250, 200)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
from javax.swing import JFrameWe import a
JFrame class. The JFrame is a top-level window with a title and a border. self.initUI()We delegate the creation of the user interface to the
initUI() method. self.setTitle("Simple")
We set the title of the window using the setTitle() method. self.setSize(250, 200)We set the size of the window.
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)This method ensures that the window terminates, if we click on the close button of the titlebar. By default nothing happens.
self.setLocationRelativeTo(None)We center the window on the screen.
self.setVisible(True)Finally, the window is showed on the screen.
Tooltip
A tooltip is a small rectangular window, which gives a brief information about an object. It is usually a GUI component. It is part of the help system of the application.#!/usr/local/bin/jythonIn the example, we set the tooltip for the frame and the button.
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This code shows a tooltip on
a window and a button.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from javax.swing import JButton
from javax.swing import JFrame
from javax.swing import JPanel
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
panel = JPanel()
self.getContentPane().add(panel)
panel.setLayout(None)
panel.setToolTipText("A Panel container")
button = JButton("Button")
button.setBounds(100, 60, 100, 30)
button.setToolTipText("A button component")
panel.add(button)
self.setTitle("Tooltips")
self.setSize(300, 200)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
if __name__ == '__main__':
Example()
panel = JPanel()We create a
self.getContentPane().add(panel)
JPanel component. It is a generic lightweight container. JFrame has an area, where you put the components called the content pane. We put the panel into this pane. panel.setLayout(None)By default, the
JPanel has a FlowLayout manager. The layout manager is used to place widgets onto the containers. If we call setLayout(None) we can position our components absolutely. For this, we use the setBounds() method. panel.setToolTipText("A Panel container")
To enable a tooltip, we call the setTooltipText() method. Figure: Tooltip
Quit button
In the last example of this section, we will create a quit button. When we press this button, the application terminates.#!/usr/local/bin/jythonWe position a
# -*- coding: utf-8 -*-
"""
ZetCode Jython Swing tutorial
This program creates a quit
button. When we press the button,
the application terminates.
author: Jan Bodnar
website: www.zetcode.com
last modified: November 2010
"""
from java.lang import System
from javax.swing import JButton
from javax.swing import JFrame
from javax.swing import JPanel
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
panel = JPanel()
self.getContentPane().add(panel)
panel.setLayout(None)
qbutton = JButton("Quit", actionPerformed=self.onQuit)
qbutton.setBounds(50, 60, 80, 30)
panel.add(qbutton)
self.setTitle("Quit button")
self.setSize(300, 200)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setLocationRelativeTo(None)
self.setVisible(True)
def onQuit(self, e):
System.exit(0)
if __name__ == '__main__':
Example()
JButton on the window. We will add an action listener to this button. qbutton = JButton("Quit", actionPerformed=self.onQuit)
qbutton.setBounds(50, 60, 80, 30)
Here we create a button. We position it by calling the setBounds() method. The actionPerformed parameter specifies the method which is called, when we click on the button. def onQuit(self, e):The onQuit() method exits the application.
System.exit(0)
Figure: Quit button
This section was an introduction to the Swing toolkit with the Jython language.
Subscribe to:
Posts (Atom)