I'm pretty new to JRuby and Java Swing GUI development. I am trying to get user inputs through a GUI and use it in later parts of the program. I am able to generate the GUI but do not know how to capture the states of the checkboxes or dropdown.
Below is a simplified example. 1. How do I exit out of the GUI but still continue with the program? 2. Is there a way to capture the GUI data only after user selects OK button?
Thank you.
# Menu Title: GUI - Get user input
include Java
import java.awt.event.ActionListener
import javax.swing.JButton
import javax.swing.JCheckBox
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.JLabel
import javax.swing.JComboBox
import javax.swing.JDialog
class Example < JFrame
def initialize
# header title
super("Test Settings")
self.initUI
end
def initUI
# define components
panel = JPanel.new
panel.setLayout(nil)
self.getContentPane.add(panel)
cb_itemA = JCheckBox.new("Check item A", true)
cb_itemB = JCheckBox.new("Check item B", false)
lbl_dropdown = JLabel.new("Traversal: ")
jCombo_dropdown = JComboBox.new()
jCombo_dropdown.addItem("Choice 1")
jCombo_dropdown.addItem("Choice 2")
jCombo_dropdown.setSelectedIndex(1) # default choice is #2
okButton = JButton.new("OK")
cancelButton = JButton.new("Cancel")
# hard-code positions
cb_itemA.setBounds(10, 10, 150, 20)
cb_itemB.setBounds(10, 30, 150, 20)
lbl_dropdown.setBounds(10, 50, 150, 20)
jCombo_dropdown.setBounds(10, 70, 150, 20)
okButton.setBounds(10, 110, 80, 25 )
cancelButton.setBounds(100, 110, 80, 25)
panel.add(cb_itemA); panel.add(cb_itemB)
panel.add(lbl_dropdown); panel.add(jCombo_dropdown)
panel.add(okButton); panel.add(cancelButton)
# == ACTION LISTENERS ==
actionTaken = ClickAction.new()
cb_itemA.addActionListener(actionTaken)
cb_itemB.addActionListener(actionTaken)
jCombo_dropdown.addActionListener(actionTaken)
okButton.addActionListener(actionTaken) # proceed to next code
cancelButton.addActionListener( actionTaken ) # exit script
# == WINDOW SETTINGS ==
win_width = 200
win_height = 180
self.setSize(win_width, win_height)
self.setLocationRelativeTo(nil)
self.setVisible(true)
self.setDefaultCloseOperation(JFrame::DISPOSE_ON_CLOSE)
end
# centralized action handler
class ClickAction
include java.awt.event.ActionListener
def actionPerformed(evt)
if evt.getActionCommand() == "Check item A"
javax.swing.JOptionPane.showMessageDialog(nil, "item A checked")
elsif evt.getActionCommand() == "Check item B"
javax.swing.JOptionPane.showMessageDialog(nil, "item B checked")
elsif evt.getActionCommand() == "Cancel"
# how to exit GUI from here?
elsif evt.getActionCommand() == "OK"
# how to exit GUI from here?
end
end
end
end
# --------------
Example.new
# <use user input selection here>
I'm thinking you really want to use a JDialog to gather input so it blocks further execution of your program. The following will take collect input, then you grab the data. While not necessary, I prefer splitting the data from the model it's not exactly MVC or MVP, but you get the idea.
include Java
import java.awt.event.ActionListener
import javax.swing.JButton
import javax.swing.JCheckBox
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.JLabel
import javax.swing.JComboBox
import javax.swing.JDialog
class View < JDialog
attr_accessor :presenter
def initialize
@frame = JFrame.new
super @frame, true
initUI
end
def initUI
# define components
setLayout(nil)
@cb_itemA = JCheckBox.new("Check item A", true)
@cb_itemB = JCheckBox.new("Check item B", false)
lbl_dropdown = JLabel.new("Traversal: ")
@jCombo_dropdown = JComboBox.new()
@jCombo_dropdown.addItem("Choice 1")
@jCombo_dropdown.addItem("Choice 2")
@jCombo_dropdown.setSelectedIndex(1) # default choice is #2
okButton = JButton.new("OK")
cancelButton = JButton.new("Cancel")
# hard-code positions
@cb_itemA.setBounds(10, 10, 150, 20)
@cb_itemB.setBounds(10, 30, 150, 20)
lbl_dropdown.setBounds(10, 50, 150, 20)
@jCombo_dropdown.setBounds(10, 70, 150, 20)
okButton.setBounds(10, 110, 80, 25 )
cancelButton.setBounds(100, 110, 80, 25)
add(@cb_itemA)
add(@cb_itemB)
add(lbl_dropdown)
add(@jCombo_dropdown)
add(okButton)
add(cancelButton)
# == ACTION LISTENERS ==
@cb_itemA.addActionListener do |e|
@presenter.check_item_a item_a
end
@cb_itemB.addActionListener do |e|
@presenter.check_item_b item_b
end
@jCombo_dropdown.addActionListener do |e|
@presenter.combo_box_selected combo
end
okButton.addActionListener do |e|
@presenter.ok
end
cancelButton.addActionListener do |e|
@presenter.cancel
end
# == WINDOW SETTINGS ==
win_width = 200
win_height = 180
self.setSize(win_width, win_height)
self.setLocationRelativeTo(nil)
self.setDefaultCloseOperation(JFrame::DISPOSE_ON_CLOSE)
end
def item_a
@cb_itemA.selected?
end
def item_b
@cb_itemB.selected?
end
def combo
@jCombo_dropdown.selected_item.to_s
end
def close
set_visible(false)
@frame.dispose
dispose
end
end
class Presenter
attr_accessor :data
def initialize(view)
# set view to presenter and vice versa
@view = view
@view.presenter = self
#get initial state, it would be better to set the state of view from
# the data and not the other way around
@data = {:item_a => @view.item_a,
:item_b => @view.item_b,
:combo => @view.combo}
end
def show_view
@view.show
end
def close_view
@view.close
end
def check_item_a selected
puts "checked item a"
@data[:item_a] = selected
end
def check_item_b selected
puts "checked item b"
@data[:item_b] = selected
end
def combo_box_selected selected
puts "combo box selected"
@data[:combo] = selected
end
def cancel
puts "canceled"
@view.close
end
def ok
puts "ok"
@view.close
end
end
>> view = View.new
>> presenter = Presenter.new(view)
>> presenter.show_view #gui gets displayed to user
checked item b
ok
=> nil
>> presenter.data
=> {:item_a=>true, :item_b=>true, :combo=>"Choice 2"}
>>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.