原文: http://zetcode.com/gui/jrubyswing/painting/

在 JRuby Swing 编程教程的这一部分中,我们将进行绘图。

我们使用绘图来创建图表,自定义组件或创建游戏。 要进行绘图,我们使用 Swing 工具包提供的绘图 API。 绘图是在paintComponent方法中完成的。 在绘图过程中,我们使用Graphics2D对象。 它是一个图形上下文,允许应用绘制到组件上。 它是渲染二维形状,文本和图像的基础类。

色彩

颜色是代表红色,绿色和蓝色(RGB)强度值的组合的对象。 我们使用Color类在 Swing 中处理颜色。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this example we draw nine rectangles
  5. # filled with nine different colors.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.Color
  12. import javax.swing.JFrame
  13. import javax.swing.JPanel
  14. class Canvas < JPanel
  15. def paintComponent g
  16. self.drawColorRectangles g
  17. end
  18. def drawColorRectangles g
  19. g.setColor Color.new 125, 167, 116
  20. g.fillRect 10, 15, 90, 60
  21. g.setColor Color.new 42, 179, 231
  22. g.fillRect 130, 15, 90, 60
  23. g.setColor Color.new 70, 67, 123
  24. g.fillRect 250, 15, 90, 60
  25. g.setColor Color.new 130, 100, 84
  26. g.fillRect 10, 105, 90, 60
  27. g.setColor Color.new 252, 211, 61
  28. g.fillRect 130, 105, 90, 60
  29. g.setColor Color.new 241, 98, 69
  30. g.fillRect 250, 105, 90, 60
  31. g.setColor Color.new 217, 146, 54
  32. g.fillRect 10, 195, 90, 60
  33. g.setColor Color.new 63, 121, 186
  34. g.fillRect 130, 195, 90, 60
  35. g.setColor Color.new 31, 21, 1
  36. g.fillRect 250, 195, 90, 60
  37. end
  38. end
  39. class Example < JFrame
  40. def initialize
  41. super "Colors"
  42. self.initUI
  43. end
  44. def initUI
  45. canvas = Canvas.new
  46. self.getContentPane.add canvas
  47. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  48. self.setSize 360, 300
  49. self.setLocationRelativeTo nil
  50. self.setVisible true
  51. end
  52. end
  53. Example.new

在代码示例中,我们绘制了九个矩形,并用不同的颜色值填充它们。

  1. def paintComponent g

在大多数情况下,自定义绘图是在paintComponent中完成的。 g参数是图形上下文。 我们称此对象为绘图操作。

  1. g.setColor Color.new 125, 167, 116

我们将上下文的当前颜色设置为指定的颜色。 使用此图形上下文的所有后续图形操作均使用此指定的颜色。

  1. g.fillRect 10, 15, 90, 60

我们使用上面指定的颜色值填充位于x = 10y = 15且宽度= 90和高度= 60的矩形。

在 JRuby Swing 中绘图 - 图1

图:颜色

形状

Swing 绘图 API 可以绘制各种形状。 以下编程代码示例将显示其中的一些。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # This example draws simple shapes
  5. # on a panel.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.Color
  12. import java.awt.RenderingHints
  13. import java.awt.geom.Ellipse2D
  14. import javax.swing.JFrame
  15. import javax.swing.JPanel
  16. class Canvas < JPanel
  17. def paintComponent g
  18. self.drawShapes g
  19. end
  20. def drawShapes g
  21. g.setColor Color.new 150, 150, 150
  22. rh = RenderingHints.new RenderingHints::KEY_ANTIALIASING,
  23. RenderingHints::VALUE_ANTIALIAS_ON
  24. rh.put RenderingHints::KEY_RENDERING,
  25. RenderingHints::VALUE_RENDER_QUALITY
  26. g.setRenderingHints rh
  27. g.fillRect 20, 20, 50, 50
  28. g.fillRect 120, 20, 90, 60
  29. g.fillRoundRect 250, 20, 70, 60, 25, 25
  30. g.fill Ellipse2D::Double.new 10, 100, 80, 100
  31. g.fillArc 120, 130, 110, 100, 5, 150
  32. g.fillOval 270, 130, 50, 50
  33. end
  34. end
  35. class Example < JFrame
  36. def initialize
  37. super "Shapes"
  38. self.initUI
  39. end
  40. def initUI
  41. canvas = Canvas.new
  42. self.getContentPane.add canvas
  43. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  44. self.setSize 350, 250
  45. self.setLocationRelativeTo nil
  46. self.setVisible true
  47. end
  48. end
  49. Example.new

在此代码示例中,我们在窗口上绘制了六个不同的形状。 正方形,矩形,圆角矩形,椭圆形,弧形和椭圆形。 我们不会绘制形状的轮廓,但是会用灰色填充形状的内部空间。

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

借助渲染提示,我们可以控制绘图的质量。 在上面的代码中,我们实现了抗锯齿。 使用抗锯齿,形状更平滑。

  1. g.setColor Color.new 150, 150, 150

我们将以某种灰色绘图。

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

在这里,我们绘制一个矩形,一个正方形和一个圆角矩形。 这些方法中的前四个参数是 x,y 坐标以及宽度和高度。 fillRoundRect的最后两个参数是四个角处圆弧的水平和垂直直径。

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

这三条线绘制一个椭圆,一个弧形和一个椭圆形。

在 JRuby Swing 中绘图 - 图2

图:形状

透明矩形

透明性是指能够透视材料的质量。 了解透明度的最简单方法是想象一块玻璃或水。 从技术上讲,光线可以穿过玻璃,这样我们就可以看到玻璃后面的物体。

在计算机图形学中,我们可以使用 alpha 合成来实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。 合成过程使用 Alpha 通道。 (wikipedia.org,answers.com)

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # This program draws ten
  5. # rectangles with different
  6. # levels of transparency.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: December 2010
  11. include Java
  12. import java.awt.Color
  13. import java.awt.AlphaComposite
  14. import javax.swing.JFrame
  15. import javax.swing.JPanel
  16. class Canvas < JPanel
  17. def paintComponent g
  18. g.setColor Color::BLUE
  19. for i in 1..10 do
  20. g.setComposite AlphaComposite.getInstance AlphaComposite::SRC_OVER,
  21. i * 0.1
  22. g.fillRect 50 * i, 20, 40, 40
  23. end
  24. end
  25. end
  26. class Example < JFrame
  27. def initialize
  28. super "Transparent rectangles"
  29. self.initUI
  30. end
  31. def initUI
  32. canvas = Canvas.new
  33. self.getContentPane.add canvas
  34. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  35. self.setSize 590, 120
  36. self.setLocationRelativeTo nil
  37. self.setVisible true
  38. end
  39. end
  40. Example.new

在示例中,我们将绘制十个具有不同透明度级别的矩形。

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

AlphaComposite类实现基本的 alpha 合成规则。

在 JRuby Swing 中绘图 - 图3

图:透明矩形

甜甜圈形状

在下面的示例中,我们通过旋转一堆椭圆来创建复杂的形状。 仿射变换由零个或多个线性变换(旋转,缩放或剪切)和平移(移位)组成。 AffineTransform是 Swing 中用于执行仿射变换的类。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this code example, we create
  5. # a Donut shape.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.BasicStroke
  12. import java.awt.Color
  13. import java.awt.RenderingHints
  14. import java.awt.geom.AffineTransform
  15. import java.awt.geom.Ellipse2D
  16. import javax.swing.JFrame
  17. import javax.swing.JPanel
  18. class Canvas < JPanel
  19. def paintComponent g
  20. self.drawDonut g
  21. end
  22. def drawDonut g
  23. rh = RenderingHints.new RenderingHints::KEY_ANTIALIASING,
  24. RenderingHints::VALUE_ANTIALIAS_ON
  25. rh.put RenderingHints::KEY_RENDERING,
  26. RenderingHints::VALUE_RENDER_QUALITY
  27. g.setRenderingHints rh
  28. size = self.getSize
  29. w = size.getWidth
  30. h = size.getHeight
  31. e = Ellipse2D::Double.new 0, 0, 80, 130
  32. g.setStroke BasicStroke.new 1
  33. g.setColor Color.gray
  34. deg = 0
  35. 72.times do
  36. at = AffineTransform.getTranslateInstance w / 2, h / 2
  37. at.rotate deg/180.0 * Math::PI
  38. g.draw at.createTransformedShape e
  39. deg += 5
  40. end
  41. end
  42. end
  43. class Example < JFrame
  44. def initialize
  45. super "Donut"
  46. self.initUI
  47. end
  48. def initUI
  49. canvas = Canvas.new
  50. self.getContentPane.add canvas
  51. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  52. self.setSize 350, 320
  53. self.setLocationRelativeTo nil
  54. self.setVisible true
  55. end
  56. end
  57. Example.new

在此示例中,我们创建一个甜甜圈。 形状类似于曲奇,因此得名“甜甜圈”。 甜甜圈在窗口中居中。

  1. size = self.getSize
  2. w = size.getWidth
  3. h = size.getHeight

在这里,我们确定窗口的宽度和高度。 我们需要这些值来使甜甜圈形状居中。

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

我们创建一个椭圆形。 我们将旋转此椭圆以创建甜甜圈形状。

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

我们为形状的轮廓设置笔触和颜色。

  1. deg = 0
  2. 72.times do

我们绘制一个椭圆对象 72 次。 每次,我们再将椭圆旋转 5 度。 这将创建我们的甜甜圈形状。

  1. at = AffineTransform.getTranslateInstance w / 2, h / 2
  2. at.rotate deg/180.0 * Math::PI
  3. g.draw at.createTransformedShape e

AffineTransform类的帮助下,我们将图形转换到窗口的中心。 然后我们进行旋转。 createTransformedShape方法会将这些仿射变换应用于椭圆。 然后使用draw方法绘制变换后的椭圆。 rotate方法以弧度表示角度,因此我们以度为单位计算弧度。

绘制文字

在最后一个示例中,我们将在窗口上绘制文本。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this example we draw lyrics of a
  5. # song on the window panel.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.Color
  12. import java.awt.Font
  13. import java.awt.RenderingHints
  14. import java.awt.geom.Ellipse2D
  15. import javax.swing.JFrame
  16. import javax.swing.JPanel
  17. class Canvas < JPanel
  18. def paintComponent g
  19. self.drawLyrics g
  20. end
  21. def drawLyrics g
  22. rh = RenderingHints.new RenderingHints::KEY_ANTIALIASING,
  23. RenderingHints::VALUE_ANTIALIAS_ON
  24. rh.put RenderingHints::KEY_RENDERING,
  25. RenderingHints::VALUE_RENDER_QUALITY
  26. g.setRenderingHints rh
  27. g.setFont Font.new "Purisa", Font::PLAIN, 13
  28. g.drawString "Most relationships seem so transitory", 20, 30
  29. g.drawString "They're all good but not the permanent one", 20, 60
  30. g.drawString "Who doesn't long for someone to hold", 20, 90
  31. g.drawString "Who knows how to love you without being told", 20, 120
  32. g.drawString "Somebody tell me why I'm on my own", 20, 150
  33. g.drawString "If there's a soulmate for everyone", 20, 180
  34. end
  35. end
  36. class Example < JFrame
  37. def initialize
  38. super "Soulmate"
  39. initUI
  40. end
  41. def initUI
  42. canvas = Canvas.new
  43. self.getContentPane.add canvas
  44. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  45. self.setSize 400, 250
  46. self.setLocationRelativeTo nil
  47. self.setVisible true
  48. end
  49. end
  50. Example.new

我们在窗口上画一首歌的歌词。

  1. rh = RenderingHints.new RenderingHints::KEY_TEXT_ANTIALIASING,
  2. RenderingHints::VALUE_TEXT_ANTIALIAS_ON
  3. g.setRenderingHints rh

我们在画上应用文字抗锯齿。

  1. g.setFont Font.new "Purisa", Font::PLAIN, 13

我们指定字体名称,样式和磅值,并在其中绘制歌词。

  1. g.drawString "Most relationships seem so transitory", 20, 30

drawString方法绘制文本。

在 JRuby Swing 中绘图 - 图4

图:绘制文本

在 JRuby Swing 编程教程的这一部分中,我们做了一些绘图。