我是Scala的新手,但是它似乎是一种我想学习的非常有趣的语言。目前,我一直在研究各种简单的应用程序来学习该语言。从基本语法到网络等等,我只是想牢固地了解语言和库的工作方式。
截至目前,我正在使用一个简单的GUI计算器。构建GUI非常简单,我对它的实际视觉组件没有任何疑问。问题在交互式部分内。由于某些原因,我无法弄清楚如何通过按键实现某种全球关注。那可能是一个糟糕的措词方式,但这就是我的意思。除了程序首次打开时,我无法使程序响应按键。我认为问题出在重点所在,但我无法弄清楚。
这是我的代码(略有剥离):
package SimplePrograms
import scala.swing._
import javax.swing.{BorderFactory, UIManager}
import scala.swing.event.{Key, KeyPressed}
/**
* Created by Tony on 2/9/14.
*/
object SimpleCalculator {
def main(args: Array[String]){
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel")
val calculator = new CalcGrid
val frame = new MainFrame{
title = "Calculator"
contents = calculator.CalcPanel()
listenTo()
reactions += {
case KeyPressed(_,Key.Numpad1,_,_)
=> calculator.numTxt.text += "1"
}
size = new Dimension(200,270)
centerOnScreen()
resizable = false
}
frame.open()
}
}
class CalcGrid(){
var numTxt = new TextField(" "){
font = new Font("Arial",0,40)
background = new Color(200,130,20)
opaque = true
border = BorderFactory.createCompoundBorder(
BorderFactory.createLoweredBevelBorder(),
BorderFactory.createEmptyBorder(0,5,0,5))
editable = false
horizontalAlignment = Alignment.Right
}
val btn1 = new Button("1"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn2 = new Button("2"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn3 = new Button("3"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn4 = new Button("4"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn5 = new Button("5"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn6 = new Button("6"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn7 = new Button("7"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn8 = new Button("8"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn9 = new Button("9"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btn0 = new Button("0"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btnPeriod = new Button("."){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btnEqual = new Button("="){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,60)
}
val btnMinus = new Button("-"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
val btnPlus = new Button("+"){
font = new Font("Arial",0,20)
background = new Color(200,130,20)
preferredSize = new Dimension(40,35)
}
def CalcPanel(): GridBagPanel = {
val contents = new GridBagPanel(){
var c = new Constraints()
c.gridx = 0
c.gridy = 0
c.gridwidth = 4
c.insets = new Insets(3,3,3,3)
c.fill = GridBagPanel.Fill.Horizontal
add(numTxt,c)
c.gridwidth = 1
c.fill = GridBagPanel.Fill.None
c.gridx = 0
c.gridy = 1
add(btn7,c)
c.gridx = 1
c.gridy = 1
add(btn8,c)
c.gridx = 2
c.gridy = 1
add(btn9,c)
c.gridx = 0
c.gridy = 2
add(btn4,c)
c.gridx = 1
c.gridy = 2
add(btn5,c)
c.gridx = 2
c.gridy = 2
add(btn6,c)
c.gridx = 0
c.gridy = 3
add(btn1,c)
c.gridx = 1
c.gridy = 3
add(btn2,c)
c.gridx = 2
c.gridy = 3
add(btn3,c)
c.gridx = 3
c.gridy = 1
add(btnMinus,c)
c.gridx = 3
c.gridy = 2
add(btnPlus,c)
c.gridx = 0
c.gridy = 4
c.gridwidth = 2
c.fill = GridBagPanel.Fill.Horizontal
add(btn0,c)
c.gridwidth = 1
c.fill = GridBagPanel.Fill.None
c.gridx = 2
c.gridy = 4
add(btnPeriod,c)
c.gridx = 3
c.gridy = 3
c.gridheight = 4
c.fill = GridBagPanel.Fill.Vertical
add(btnEqual,c)
}
contents
}
}
我为松散的代码表示歉意,但是正如我所说,只是快速地提出了一些建议。仅仅测试各种代码选项并搜索互联网,就已经为此工作了几天。
有什么帮助吗?
编辑:作为一个简短的说明,我意识到在其他一些问题中,listenTo方法没有填写参数,但这是在经过一些令人烦恼的反复试验之后,并且我认为发布多个版本可能不是需要。
最佳答案
您的方法通常是正确的。但是,使用listenTo
方法时,必须使用正确的发布者。例如,如果您编写以下内容,则当标签为“ 1”的按钮聚焦时,您将能够输入“ 1”:
listenTo(calculator.btn1.keys)
关键事件由特殊发布者
.keys
调度,而不是组件本身。因此,这里最简单的方法是监听计算器的每个组成部分(所有按钮和面板)
listenTo(calculator.btn1.keys, calculator.btn2.keys, ...)
在Swing中,关键事件不会自动使组件层次结构冒泡,而只会分派给具有焦点的组件。 (Java)Swing中有另一种方法,称为键绑定。有关概述,请参见:
How to Write a Key Listener
How to Use Key Bindings
您可以使用第二种方法来侦听活动窗口中任何位置的按键。但是,作为Scala初学者,这可能会造成混淆,因为您将不得不使用Java Swing而不是Scala Swing包装层。为了完整起见,我向大家展示了一般如何做到这一点:
import javax.swing.{JComponent, KeyStroke} // Java world
val calculator = new CalcGrid
val frame = new Frame{
title = "Calculator"
val panel = calculator.CalcPanel()
contents = panel
val act1 = Action("key1") {
calculator.numTxt.text += "1"
}
// the mapping is done in your top component, so `panel`.
// you must use the input map which is active whenever the window
// in which the panel is located has focus:
val imap = panel.peer.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
val amap = panel.peer.getActionMap
// you need to map a KeyStroke to an (arbitrarily chosen) action name,
// and that action name to the action itself.
imap.put(KeyStroke.getKeyStroke(Key.Numpad1.id, 0), "key1")
imap.put(KeyStroke.getKeyStroke(Key.Key1 .id, 0), "key1") // can map several keys
amap.put("key1", act1.peer)
size = new Dimension(200,270)
centerOnScreen()
resizable = false
}
frame.open()
关于java - Scala GUI-事件处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21734961/