简体   繁体   English

带有Swing的JRuby / Java:收集用户输入GUI?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM