1

我对 JRuby 和 Java Swing GUI 开发还很陌生。我正在尝试通过 GUI 获取用户输入并在程序的后面部分使用它。我能够生成 GUI,但不知道如何捕获复选框或下拉列表的状态。

下面是一个简化的例子。1. 如何退出 GUI 但仍继续程序?2. 有没有办法只在用户选择 OK 按钮后捕获 GUI 数据?

谢谢你。

# 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>
4

1 回答 1

2

我认为您真的想使用 JDialog 来收集输入,以便阻止程序的进一步执行。以下将收集输入,然后获取数据。虽然没有必要,但我更喜欢从模型中拆分数据,它不完全是 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"}
>> 
于 2013-11-14T19:30:25.543 回答