[英]JRuby/Java with Swing: gather user input GUI?
I'm pretty new to JRuby and Java Swing GUI development. 我对JRuby和Java Swing GUI开发非常陌生。 I am trying to get user inputs through a GUI and use it in later parts of the program. 我试图通过GUI获取用户输入,并在程序的后续部分中使用它。 I am able to generate the GUI but do not know how to capture the states of the checkboxes or dropdown. 我能够生成GUI,但不知道如何捕获复选框或下拉菜单的状态。
Below is a simplified example. 下面是一个简化的示例。 1. How do I exit out of the GUI but still continue with the program? 1.如何退出GUI,但仍继续执行程序? 2. Is there a way to capture the GUI data only after user selects OK button? 2.是否只有在用户选择确定按钮之后才能捕获GUI数据?
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. 我想您真的想使用JDialog收集输入,以便它阻止程序的进一步执行。 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. 虽然不是必需的,但我更喜欢从模型中分离数据,它不是完全MVC或MVP,但是您可以理解。
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"}
>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.