Search code examples
rubyswingjruby

Ruby with Java swing is saying that count is nil


Hello so i am new to javax.swing and i wanted to ask you guys why am i getting this error(i am going to put the exact error after my code). I have tried everything i can find. Thank you guys and im sorry if this is an easy fix i really suck at ruby right now
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

Error( I am getting this when i press the button )

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

Solution

  • more of a Ruby question - local variables won't be copied into a new scope:

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

    count is a local variable for the method (initially nil) thus the failure.

    if you're just testing things out you can work-around this using a global:

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

    that being said do not use globals and rather setup a proper object that will encapsulate the state and 'implement' the actionPerformed inteface.