Ruby с Java swing говорит, что количество равно нулю

#ruby #swing #jruby

#ruby #swing #jruby

Вопрос:

Здравствуйте, итак, я новичок в javax.swing, и я хотел спросить вас, ребята, почему я получаю эту ошибку (я собираюсь указать точную ошибку после моего кода). Я перепробовал все, что смог найти. Спасибо, ребята, и мне жаль, если это легко исправить, я действительно отстой в ruby прямо сейчас
testGui.rb

 # javaSwingHello.rb  
require 'java' # Line 2  
JFrame = javax.swing.JFrame  
JLabel = javax.swing.JLabel  
JPanel = javax.swing.JPanel
JButton = javax.swing.JButton
BorderFactory = javax.swing.BorderFactory
BorderLayout = java.awt.BorderLayout
GridLayout = java.awt.GridLayout
count = 1
frame  = JFrame.new  
panel  = JPanel.new
button = JButton.new "Click me" 
button.addActionListener self
label = JLabel.new "Number of clicks: 0"
panel.setBorder BorderFactory.createEmptyBorder(70, 70, 20, 70)
panel.setLayout GridLayout.new(0, 1)
panel.add button
panel.add label
frame.add panel, BorderLayout::CENTER
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setTitle "TEST GUI"
frame.pack
frame.setVisible true 
def actionPerformed(event)
    count  = 1
    texttoset = "Number of clicks "   count
    label.setText(texttoset)
end
 

Ошибка (я получаю это, когда нажимаю кнопку)

 Exception in thread "AWT-EventQueue-0" org.jruby.exceptions.NoMethodError: (NoMethodError) undefined method ` ' for nil:NilClass
        at testGui.actionPerformed(testGui.rb:26)
 

Комментарии:

1. count Переменная внутри actionPerformed отличается от count используемой ранее. Если вы действительно хотите создать замыкание, вам нужно использовать блок.

Ответ №1:

еще один вопрос Ruby — локальные переменные не будут скопированы в новую область:

 def actionPerformed(event)
    count  = 1
    texttoset = "Number of clicks "   count
    label.setText(texttoset)
end
 

count является локальной переменной для метода (изначально nil ), следовательно, сбой.

если вы просто тестируете вещи, вы можете обойти это, используя глобальный:

 $count = 1

def actionPerformed(event)
    $count  = 1
    texttoset = "Number of clicks "   count
    label.setText(texttoset)
end
 

при этом не используйте глобальные переменные, а скорее настройте правильный объект, который будет инкапсулировать состояние и «реализовать» actionPerformed интерфейс.

Ответ №2:

Вы не сказали, как вы собираетесь использовать actionPerformed , но одной из возможностей было бы сделать метод лямбда:

 count = 1
$ActionPerformed = -> (event) do
    count  = 1
    texttoset = "Number of clicks "   count
    label.setText(texttoset)
end
 

Вам нужно будет вызвать его как

 $ActionPerformed.call(myEvent)