返回介绍

Painting in JRuby Swing

发布于 2025-02-22 22:19:50 字数 13466 浏览 0 评论 0 收藏 0

In this part of the JRuby 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 colour is an object representing a combination of Red, Green, and Blue (RGB) intensity values. We use the Color class to work with colours in Swing.

#!/usr/local/bin/jruby

# ZetCode JRuby Swing tutorial
# 
# In this example we draw nine rectangles
# filled with nine different colors.
# 
# author: Jan Bodnar
# website: www.zetcode.com
# last modified: December 2010

include Java


import java.awt.Color
import javax.swing.JFrame
import javax.swing.JPanel


class Canvas < JPanel

  def paintComponent g
    
    self.drawColorRectangles g
    
  end
  
  def drawColorRectangles g

    g.setColor Color.new 125, 167, 116
    g.fillRect 10, 15, 90, 60

    g.setColor Color.new 42, 179, 231
    g.fillRect 130, 15, 90, 60

    g.setColor Color.new 70, 67, 123
    g.fillRect 250, 15, 90, 60

    g.setColor Color.new 130, 100, 84
    g.fillRect 10, 105, 90, 60

    g.setColor Color.new 252, 211, 61
    g.fillRect 130, 105, 90, 60

    g.setColor Color.new 241, 98, 69
    g.fillRect 250, 105, 90, 60

    g.setColor Color.new 217, 146, 54
    g.fillRect 10, 195, 90, 60

    g.setColor Color.new 63, 121, 186
    g.fillRect 130, 195, 90, 60

    g.setColor Color.new 31, 21, 1
    g.fillRect 250, 195, 90, 60
    
  end
end  

class Example < JFrame
  
  def initialize
    super "Colors"

    self.initUI
  end
    
  def initUI
    
    canvas = Canvas.new
    self.getContentPane.add canvas
    
    self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
    self.setSize 360, 300
    self.setLocationRelativeTo nil
    self.setVisible true
  end
end

Example.new

In the code example, we draw nine rectangles and fill them with different colour values.

def paintComponent 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.new 125, 167, 116

We set the context's current colour to the specified colour. All subsequent graphics operations using this graphics context use this specified colour.

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 colour value.

Colors
Figure: Colours

Shapes

The Swing painting API can draw various shapes. The following programming code example will show some of them.

#!/usr/local/bin/jruby

# ZetCode JRuby Swing tutorial
# 
# This example draws simple shapes
# on a panel.
# 
# author: Jan Bodnar
# website: www.zetcode.com
# last modified: December 2010


include Java


import java.awt.Color
import java.awt.RenderingHints
import java.awt.geom.Ellipse2D
import javax.swing.JFrame
import javax.swing.JPanel


class Canvas < JPanel

  def paintComponent g
    
    self.drawShapes g    
  end  
  
  def drawShapes g
    
    g.setColor Color.new 150, 150, 150

    rh = RenderingHints.new 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.new 10, 100, 80, 100
    g.fillArc 120, 130, 110, 100, 5, 150
    g.fillOval 270, 130, 50, 50
    
  end
end  

class Example < JFrame
  
  def initialize
    super "Shapes"

    self.initUI
  end
    
  def initUI
    
    canvas = Canvas.new
    self.getContentPane.add canvas
    
    self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
    self.setSize 350, 250
    self.setLocationRelativeTo nil
    self.setVisible true
  end
end

Example.new

In 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 colour.

rh = RenderingHints.new RenderingHints::KEY_ANTIALIASING,
    RenderingHints::VALUE_ANTIALIAS_ON

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.

g.setColor Color.new 150, 150, 150

We will be painting in some gray color.

g.fillRect 20, 20, 50, 50
g.fillRect 120, 20, 90, 60
g.fillRoundRect 250, 20, 70, 60, 25, 25

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 fillRoundRect are the horizontal and vertical diameter of the arc at the four corners.

g.fill Ellipse2D::Double.new 10, 100, 80, 100
g.fillArc 120, 130, 110, 100, 5, 150
g.fillOval 270, 130, 50, 50

These three lines draw an ellipse, an arc and an oval.

Shapes
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)

#!/usr/local/bin/jruby

# ZetCode JRuby Swing tutorial
# 
# This program draws ten
# rectangles with different
# levels of transparency.
# 
# author: Jan Bodnar
# website: www.zetcode.com
# last modified: December 2010


include Java

import java.awt.Color
import java.awt.AlphaComposite
import javax.swing.JFrame
import javax.swing.JPanel


class Canvas < JPanel

  def paintComponent g

    g.setColor Color::BLUE

    for i in 1..10 do
      g.setComposite AlphaComposite.getInstance AlphaComposite::SRC_OVER,
                            i * 0.1
      g.fillRect 50 * i, 20, 40, 40
    end
    
  end
end  

class Example < JFrame
  
  def initialize
    super "Transparent rectangles"

    self.initUI
  end
    
  def initUI
    
    canvas = Canvas.new
    self.getContentPane.add canvas
    
    self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
    self.setSize 590, 120
    self.setLocationRelativeTo nil
    self.setVisible true
  end
end

Example.new

In the example we will draw ten rectangles with different levels of transparency.

g.setComposite AlphaComposite.getInstance AlphaComposite::SRC_OVER,
                            i * 0.1

The AlphaComposite class implements basic alpha compositing rules.

Transparent rectangles
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). The AffineTransform is the class in Swing to perform affine transformations.

#!/usr/local/bin/jruby

# ZetCode JRuby Swing tutorial
# 
# In this code example, we create
# a Donut shape.
# 
# author: Jan Bodnar
# website: www.zetcode.com
# last modified: December 2010


include Java

import java.awt.BasicStroke
import java.awt.Color
import java.awt.RenderingHints
import java.awt.geom.AffineTransform
import java.awt.geom.Ellipse2D
import javax.swing.JFrame
import javax.swing.JPanel


class Canvas < JPanel

  def paintComponent g
    
    self.drawDonut g
    
  end
  
  def drawDonut g
    
    rh = RenderingHints.new 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.new 0, 0, 80, 130
    g.setStroke BasicStroke.new 1
    g.setColor Color.gray

    deg = 0
    
    72.times do
      at = AffineTransform.getTranslateInstance w / 2, h / 2
      at.rotate deg/180.0 * Math::PI 
      g.draw at.createTransformedShape e
      deg += 5
    end
    
  end
end  

class Example < JFrame
  
  def initialize
    super "Donut"

    self.initUI
  end
    
  def initUI
    
    canvas = Canvas.new
    self.getContentPane.add canvas
    
    self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
    self.setSize 350, 320
    self.setLocationRelativeTo nil
    self.setVisible true
  end
end

Example.new

In this example, we create a donut. The shape resembles a cookie, hence the name donut. The donut is centered in the window.

size = self.getSize
w = size.getWidth
h = size.getHeight

Here we determine the width and height of the window. We need these values to center the donut shape.

e = Ellipse2D::Double.new 0, 0, 80, 130

We create an ellipse shape. We will rotate this ellipse to create the donut shape.

g.setStroke BasicStroke.new 1
g.setColor Color.gray

We set the stroke and the color for the outlines of the shapes.

deg = 0

72.times do

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
at.rotate deg/180.0 * Math::PI 
g.draw at.createTransformedShape e

With the help of the 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. The rotate method takes angles in radians, so we calculate radians out of degrees.

Drawing text

In the last example, we are going to draw text on the window.

#!/usr/local/bin/jruby

# ZetCode JRuby Swing tutorial
# 
# In this example we draw lyrics of a 
# song on the window panel.
# 
# author: Jan Bodnar
# website: www.zetcode.com
# last modified: December 2010


include Java

import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
import java.awt.geom.Ellipse2D
import javax.swing.JFrame
import javax.swing.JPanel


class Canvas < JPanel

  def paintComponent g
    
    self.drawLyrics g
  end
  
  def drawLyrics g
    
    rh = RenderingHints.new RenderingHints::KEY_ANTIALIASING,
      RenderingHints::VALUE_ANTIALIAS_ON

    rh.put RenderingHints::KEY_RENDERING,
         RenderingHints::VALUE_RENDER_QUALITY

    g.setRenderingHints rh

    g.setFont Font.new "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
    
  end
end  

class Example < JFrame
  
  def initialize
    super "Soulmate"

    initUI
  end
    
  def initUI
    
    canvas = Canvas.new
    self.getContentPane.add canvas
    
    self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
    self.setSize 400, 250
    self.setLocationRelativeTo nil
    self.setVisible true
  end
end

Example.new

We draw a lyrics of a song on the window.

rh = RenderingHints.new RenderingHints::KEY_TEXT_ANTIALIASING,
  RenderingHints::VALUE_TEXT_ANTIALIAS_ON

g.setRenderingHints rh

We apply text antialiasing on the painting.

g.setFont Font.new "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.

Drawing text
Figure: Drawing text

In this part of the JRuby Swing programming tutorial, we did some painting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文