Java Scala swing重涂
所以我对scala非常非常陌生。我正在用GUI实现Conways的生活游戏。我不知道如何在2D阵列更改时更新面板。有人能给我指一下正确的方向吗?我的全部代码如下:Java Scala swing重涂,java,swing,scala,scala-swing,Java,Swing,Scala,Scala Swing,所以我对scala非常非常陌生。我正在用GUI实现Conways的生活游戏。我不知道如何在2D阵列更改时更新面板。有人能给我指一下正确的方向吗?我的全部代码如下: import swing._ import java.awt.{Color, Graphics2D, Dimension} // initialize variables // infinite plane variable var infCurrent = scala.collection.mutable.ListBuffer[
import swing._
import java.awt.{Color, Graphics2D, Dimension}
// initialize variables
// infinite plane variable
var infCurrent = scala.collection.mutable.ListBuffer[List[Int]]()
var infNext = scala.collection.mutable.ListBuffer[List[Int]]()
var infNext1 = scala.collection.mutable.ListBuffer[List[Int]]()
var infLifeTester = scala.collection.mutable.MutableList[List[Int]]()
// general variables
var lifeCount = 0
var yes = 1
// displayed variables
val xDim = 20
val yDim = 20
var currentState = Array.ofDim[Int](xDim, yDim)
var colorIndexList = scala.collection.mutable.ListBuffer[List[Int]]()
var colorData = Array.ofDim[Color](xDim, yDim)
// initial value
infCurrent = scala.collection.mutable.ListBuffer(List(6,6), List(6,7), List(6,8), List(5,8), List(4,7))
// this function tests if a CURRENTLY ALIVE CELL on the INF PLANE STAYS ALIVE
def infStayAlive(current: scala.collection.mutable.ListBuffer[List[Int]]): scala.collection.mutable.ListBuffer[List[Int]] = {
for (i <- current) {
var a = i(0)
var b = i(1)
if (current.contains(List(a - 1, b - 1))) lifeCount += 1
if (current.contains(List(a - 1, b))) lifeCount += 1
if (current.contains(List(a - 1, b + 1))) lifeCount += 1
if (current.contains(List(a, b - 1))) lifeCount += 1
if (current.contains(List(a, b + 1))) lifeCount += 1
if (current.contains(List(a + 1, b - 1))) lifeCount += 1
if (current.contains(List(a + 1, b))) lifeCount += 1
if (current.contains(List(a + 1, b + 1))) lifeCount += 1
if (lifeCount == 2) infNext = infNext :+ i
lifeCount = 0
}
return infNext
}
// this function gets ALL NEIGHBORS for what's on the INF PLANE
def infGetNeighbors(current: scala.collection.mutable.ListBuffer[List[Int]]): scala.collection.mutable.MutableList[List[Int]] = {
for (i <- current) {
var a = i(0)
var b = i(1)
infLifeTester = infLifeTester :+ List(a - 1, b - 1)
infLifeTester = infLifeTester :+ List(a - 1, b)
infLifeTester = infLifeTester :+ List(a - 1, b + 1)
infLifeTester = infLifeTester :+ List(a, b - 1)
infLifeTester = infLifeTester :+ List(a, b + 1)
infLifeTester = infLifeTester :+ List(a + 1, b - 1)
infLifeTester = infLifeTester :+ List(a + 1,b)
infLifeTester = infLifeTester :+ List(a + 1, b + 1)
}
infLifeTester = infLifeTester.distinct
return infLifeTester
}
// this function determines whether cells on the INF PLANE DIE or COME ALIVE
def infComeAlive(infLifeTester: scala.collection.mutable.MutableList[List[Int]]): scala.collection.mutable.ListBuffer[List[Int]] = {
for(i <- infLifeTester) {
var a = i(0)
var b = i(1)
if (infCurrent.contains(List(a - 1, b - 1))) lifeCount += 1
if (infCurrent.contains(List(a - 1, b))) lifeCount += 1
if (infCurrent.contains(List(a - 1, b + 1))) lifeCount += 1
if (infCurrent.contains(List(a, b - 1))) lifeCount += 1
if (infCurrent.contains(List(a, b + 1))) lifeCount += 1
if (infCurrent.contains(List(a + 1, b - 1))) lifeCount += 1
if (infCurrent.contains(List(a + 1, b))) lifeCount += 1
if (infCurrent.contains(List(a + 1, b + 1))) lifeCount += 1
if (lifeCount == 3) infNext1 = infNext1 :+ i
lifeCount = 0
}
infNext1 = infNext1.distinct
return infNext1
}
def printGrid(infCurrent: scala.collection.mutable.ListBuffer[List[Int]]): Array[Array[Int]] = {
for(i <- infCurrent) {
if(i(0) >= 0) {
if(i(0) < xDim) {
if(i(1) >= 0) {
if(i(1) < yDim) {
currentState(i(0))(i(1)) = 1
colorIndexList = colorIndexList :+ i
}
}
}
}
}
return currentState
}
def colorGrid(colorIndexList: scala.collection.mutable.ListBuffer[List[Int]]): Array[Array[Color]] = {
for (i <- colorIndexList) {
colorData(i(0))(i(1)) = Color.WHITE
}
return colorData
}
// define panel class
class DataPanel(data: Array[Array[Color]]) extends Panel {
override def paintComponent(g: Graphics2D) {
val dx = g.getClipBounds.width.toFloat / data.length
val dy = g.getClipBounds.height.toFloat / data.map(_.length).max
for {
x <- 0 until data.length
y <- 0 until data(x).length
x1 = (x * dx).toInt
y1 = (y * dy).toInt
x2 = ((x + 1) * dx).toInt
y2 = ((y + 1) * dy).toInt
} {
data(x)(y) match {
case c: Color => g.setColor(c)
case _ => g.setColor(Color.BLACK)
repaint
}
g.fillRect(x1, y1, x2 - x1, y2 - y1)
println("hi")
}
println("hey")
}
}
// make swing app
object Draw extends SimpleSwingApplication {
val data = colorData
def top = new MainFrame {
background = Color.RED
title = "Shombo's Game of Life"
val button = new Button {
text = "Stahhhp!!"
}
val life = new DataPanel(data) {
preferredSize = new Dimension(500, 500)
}
contents = new BoxPanel(Orientation.Vertical) {
contents += life
contents += button
}
}
}
Draw.top.visible = true
while(yes == 1) {
infLifeTester = infGetNeighbors(infCurrent)
infNext = infStayAlive(infCurrent)
infNext1 = infComeAlive(infLifeTester)
infNext = scala.collection.mutable.ListBuffer.concat(infNext, infNext1)
infCurrent = infNext
infNext = scala.collection.mutable.ListBuffer[List[Int]]()
infNext1 = scala.collection.mutable.ListBuffer[List[Int]]()
infLifeTester = scala.collection.mutable.MutableList[List[Int]]()
currentState = printGrid(infCurrent)
println(currentState.deep.mkString("\n"))
//println("\n")
colorData = colorGrid(colorIndexList)
Draw.top.contents.repaint()
currentState = Array.ofDim[Int](xDim, yDim)
colorIndexList = scala.collection.mutable.ListBuffer[List[Int]]()
colorData = Array.ofDim[Color](xDim, yDim)
yes = 1
}
导入swing_
导入java.awt.{Color,Graphics2D,Dimension}
//初始化变量
//无限平面变量
var influent=scala.collection.mutable.ListBuffer[List[Int]]()
var infNext=scala.collection.mutable.ListBuffer[List[Int]]()
var infNext1=scala.collection.mutable.ListBuffer[List[Int]]()
var inflietester=scala.collection.mutable.MutableList[List[Int]]()
//一般变量
变量寿命计数=0
var yes=1
//显示变量
val xDim=20
val yDim=20
var currentState=Array.ofDim[Int](xDim,yDim)
var colorIndexList=scala.collection.mutable.ListBuffer[List[Int]]()
var colorData=Array.ofDim[Color](xDim,yDim)
//初始值
influent=scala.collection.mutable.ListBuffer(列表(6,6)、列表(6,7)、列表(6,8)、列表(5,8)、列表(4,7))
//此函数用于测试INF平面上当前活动的单元格是否保持活动状态
def infStayAlive(当前:scala.collection.mutable.ListBuffer[List[Int]]):scala.collection.mutable.ListBuffer[List[Int]={
对于(i您不清楚将var
s与可变元素混合在一起的情况。您应该将var
s与被替换的不可变状态结合起来,或者使用可变状态(例如数组),但将其更新到位,并且不创建新数组
在应用程序中,您创建了一个DataPanel
的实例,该实例将colorData
中存储的数组作为参数。但在迭代过程中,您并没有更新colorData
的内容,而是实际创建了一个全新的数组并替换变量colorData
的值:
colorData = Array.ofDim[Color](xDim, yDim)
因此,在第一次迭代之后,您的全局状态与存储在DataPanel
中的状态不同
如果在colorData
中重复使用数组,则需要更改colorGrid
以将黑色指定给非活动单元格。现在使用null
颜色作为黑色,使用color.WHITE
作为白色。定义val colorData=array.ofDim[Boolean](xDim,yDim)更有意义
。在colorGrid
中,首先将所有元素设置为false
,然后遍历colorIndexList
您应该将迭代定义为在每个步骤中调用的函数。现在您有一个无限循环,而(yes==1)
,因为yes
从未更改。执行此操作将冻结您的计算机
还要注意,以这种方式调用Draw.top
是不好的,因为您将它定义为一个函数;每次调用时都会创建一个新窗口。始终使用lazy val top=
来防止此问题
您的代码仍然一团糟,但至少您还有一些东西需要改进。这是一个最低限度的工作示例,仅包含上面的更改:
import scala.collection.mutable.ListBuffer
val colorData = Array.ofDim[Boolean](xDim, yDim)
def colorGrid(colorIndexList: ListBuffer[List[Int]]): Unit = {
colorData.foreach { row => java.util.Arrays.fill(row, false) } // all 'black'
for (i <- colorIndexList) {
colorData(i(0))(i(1)) = true // some 'white'
}
}
class DataPanel(data: Array[Array[Boolean]]) extends Panel {
override def paintComponent(g: Graphics2D): Unit = {
val dx = g.getClipBounds.width.toFloat / data.length
val dy = g.getClipBounds.height.toFloat / data.map(_.length).max
for {
x <- 0 until data.length
y <- 0 until data(x).length
x1 = (x * dx).toInt
y1 = (y * dy).toInt
x2 = ((x + 1) * dx).toInt
y2 = ((y + 1) * dy).toInt
} {
g.setColor(if (data(x)(y)) Color.black else Color.white) // !
g.fillRect(x1, y1, x2 - x1, y2 - y1)
}
}
}
运行:Draw.main(Array())
使用观察者模式,如Java所示。
def step(): Unit = {
infLifeTester = infGetNeighbors(infCurrent)
infNext = infStayAlive(infCurrent)
infNext1 = infComeAlive(infLifeTester)
infNext = scala.collection.mutable.ListBuffer.concat(infNext, infNext1)
infCurrent = infNext
infNext = scala.collection.mutable.ListBuffer[List[Int]]()
infNext1 = scala.collection.mutable.ListBuffer[List[Int]]()
infLifeTester = scala.collection.mutable.MutableList[List[Int]]()
currentState = printGrid(infCurrent)
println(currentState.deep.mkString("\n"))
//println("\n")
colorGrid(colorIndexList)
currentState = Array.ofDim[Int](xDim, yDim)
colorIndexList = scala.collection.mutable.ListBuffer[List[Int]]()
}
object Draw extends SimpleSwingApplication {
lazy val life = new DataPanel(colorData) {
preferredSize = new Dimension(500, 500)
}
lazy val top = new MainFrame {
background = Color.RED
title = "Shombo's Game of Life"
val button = Button("Step") {
step() // updates colorData
life.repaint() // refreshes view
}
contents = new BoxPanel(Orientation.Vertical) {
contents += life
contents += button
}
}
}