我正在尝试将Java类转换为其JRuby计数器部分,但我不知道如何翻译Java 内部类。将Java内部类转换为JRuby对应部分
这个问题众所周知,通常来自Java和Ruby之间的可见性/范围差异。有时可以使用集团而不是内部类来解决这个问题。
Java示例如下,可在Zetcode网站上找到。我也在下面给我的Ruby尝试。
该问题位于扩展TimerClass的内部ScheduleTask类中。在运行时(使用Java),ScheduleTask的run()方法允许调用它所属的Board对象的repaint()方法。这在Java中非常方便:在正常的时间间隔内,Board面板重新绘制。如何在JRuby中翻译此内容?我只是试图字面翻译这一点,但随后的重绘方法不是由红宝石内部ScheduleTask知...
package com.zetcode;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel {
private final int B_WIDTH = 350;
private final int B_HEIGHT = 350;
private final int INITIAL_X = -40;
private final int INITIAL_Y = -40;
private final int INITIAL_DELAY = 100;
private final int PERIOD_INTERVAL = 25;
private Image star;
private Timer timer;
private int x, y;
public Board() {
initBoard();
}
private void loadImage() {
ImageIcon ii = new ImageIcon("star.png");
star = ii.getImage();
}
private void initBoard() {
setBackground(Color.BLACK);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
setDoubleBuffered(true);
loadImage();
x = INITIAL_X;
y = INITIAL_Y;
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(),
INITIAL_DELAY, PERIOD_INTERVAL);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawStar(g);
}
private void drawStar(Graphics g) {
g.drawImage(star, x, y, this);
Toolkit.getDefaultToolkit().sync();
}
private class ScheduleTask extends TimerTask {
@Override
public void run() {
x += 1;
y += 1;
if (y > B_HEIGHT) {
y = INITIAL_Y;
x = INITIAL_X;
}
repaint();
}
}
这里是JRuby的尝试,其中ScheduleTask类已提取从董事会...
include Java
import java.awt.Color
import java.awt.Dimension
import java.awt.Graphics
import java.awt.Image
import java.awt.Toolkit
import java.util.Timer
import java.util.TimerTask
import javax.swing.ImageIcon
import javax.swing.JPanel
B_WIDTH = 650
B_HEIGHT = 450
INITIAL_X = -40
INITIAL_Y = -40
INITIAL_DELAY = 100
PERIOD_INTERVAL = 25
class Board < JPanel
def initialize
super
initBoard()
end
def loadImage
ii = ImageIcon.new("mario2.png")
@star = ii.getImage()
end
def initBoard
setBackground(Color.new(255, 255, 255))
setPreferredSize(Dimension.new(B_WIDTH, B_HEIGHT))
setDoubleBuffered(true)
loadImage()
@x = INITIAL_X
@y = INITIAL_Y
@timer = Timer.new()
task=ScheduleTask.new
task.init(@x,@y)
@timer.scheduleAtFixedRate(task, INITIAL_DELAY, PERIOD_INTERVAL)
end
def paintComponent(g)
repaint() # WAS : super.paintComponent(g)
drawStar(g)
end
def drawStar(g)
g.drawImage(@star, @x, @y, self)
Toolkit.getDefaultToolkit().sync()
end
class ScheduleTask < TimerTask \t
def init x,y
@x,@y=x,y
end
def run
@x += 1
@y += 1
if (@y > B_HEIGHT)
@y = INITIAL_Y
@x = INITIAL_X
end
repaint() # <===== ERROR in Ruby. Unknown method
end
end #ScheduleTask
end #Board
最后这里是启动应用程序的方式:
require_relative 'board'
include Java
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.SwingUtilities
class UtilityTimerExample < JFrame
def initialize
super
initUI();
setVisible(true)
end
def initUI
add(Board.new());
setResizable(false);
pack();
setTitle("Star");
setLocationRelativeTo(nil)
setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
end
end
SwingUtilities.invoke_later do
UtilityTimerExample.new
end
究竟是用代码您的问题,我不明白你的问题。 – phoet 2015-04-02 21:11:24
@phoet。我稍微修改了我对问题的解释和我在Ruby中的尝试。与Java相比,在Ruby中使用内部类,我们失去了repaint()方法的可见性。 – JCLL 2015-04-03 07:59:30
与'jruby swing.rb'正常工作 - 没有错误打印/发生在运行时! – kares 2015-04-05 17:45:04