我要完成的工作是:拥有一个 ScalaFX 应用程序,其中包含一些名为Option Explicit
Private Sub Test_It()
Dim om_Item As Outlook.MailItem
Dim oi_Inspector As Outlook.Inspector
Dim wd_Doc As Word.Document
Dim wd_Selection As Word.Selection
Dim wr_Range As Word.Range
Dim b_return As Boolean
Dim str_Text As String
str_Text = "Hello World"
'Zugriff auf aktive E-Mail
Set oi_Inspector = Application.ActiveInspector()
Set om_Item = oi_Inspector.CurrentItem
Set wd_Doc = oi_Inspector.WordEditor
'Zugriff auf Textmarkierung in E-Mail
Set wd_Selection = wd_Doc.Application.Selection
wd_Selection.InsertBefore str_Text
'Zugriff auf 'virtuelle' Markierung
'wr_Range muss auf das ganze Dokument gesetzt werden !
Set wr_Range = wd_Doc.Content
'Suche in E-Mail Text
With wr_Range.Find
.Forward = True
.ClearFormatting
.MatchWholeWord = True
.MatchCase = False
.Wrap = wdFindStop
.MatchWildcards = True
.Text = "#%*%#"
End With
b_return = True
Do While b_return
b_return = wr_Range.Find.Execute
If b_return Then
' Es wurde gefunden
str_Text = wr_Range.Text
'schneide den Anfangstext und das Ende ab
'str_TextID = Mid$(str_TextID, 11, Len(str_TextID) - 12)
MsgBox ("Es wurde noch folgender Schlüssel gefunden:" & vbCrLf & str_Text)
End If
Loop
'aktiv Range ändern
'wr_Range muss auf das ganze Dokument gesetzt werden !
Set wr_Range = wd_Doc.Content
wr_Range.Start = wr_Range.Start + 20
wr_Range.End = wr_Range.End - 20
'Text formatieren
With wr_Range.Font
.ColorIndex = wdBlue
.Bold = True
.Italic = True
.Underline = wdUnderlineDotDashHeavy
End With
'Freigeben der verwendeten Variablen
Set oi_Inspector = Nothing
Set om_Item = Nothing
Set wd_Doc = Nothing
Set wd_Selection = Nothing
Set wr_Range = Nothing
End Sub
,object
,Buttons
的漂亮Labels
等等,以保持一切井井有条。
这里有一个例子来说明我的意思:
Checkboxes
此代码显示了一个带有标签和两个按钮的窗口,这些按钮更改了标签的文本。
那很好。
但是当我的代码增加了很多控件时,事情就会变得一团糟。
这就是为什么我尝试将控件转移到其他package ButtonsAndLabel
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.control.{ Button, Label }
import scalafx.event.ActionEvent
object Main extends JFXApp {
stage = new JFXApp.PrimaryStage {
title = "Test-Program"
scene = new Scene(300, 200) {
val label = new Label("Nothing happened yet") {
layoutX = 20
layoutY = 20
}
val button1 = new Button("Button 1") {
layoutX = 20
layoutY = 50
onAction = (e: ActionEvent) => {
label.text = "B1 klicked"
}
}
val button2 = new Button("Button 2") {
layoutX = 20
layoutY = 80
onAction = (e: ActionEvent) => {
label.text = "B2 klicked"
}
}
content = List(label, button1, button2)
}
}
}
(在不同文件中)的原因。我已将标签放入名为object
的对象中:
Labels
当我将其导入到主文件中时
package ButtonsAndLabel
import scalafx.scene.control.Label
import scalafx.event.ActionEvent
object Labels {
val label = new Label("Nothing happened yet") {
layoutX = 20
layoutY = 20
}
}
一切正常。
但是,然后我尝试将按钮放入import Labels.label
对象中
Buttons
这会在我尝试编译时带来错误消息:
package ButtonsAndLabel import scalafx.scene.control.Button import scalafx.event.ActionEvent import Labels.label object Buttons { val button1 = new Button("Button 1") { layoutX = 20 layoutY = 50 onAction = (e: ActionEvent) => { label.text = "B1 klicked" } } val button2 = new Button("Button 2") { layoutX = 20 layoutY = 80 onAction = (e: ActionEvent) => { label.text = "B2 klicked" } } }
现在我被困住了,因为我不知道任何 Java 。
有人知道我是否有可能做我想做的事?
到目前为止,我尚未在网上找到任何有关此的信息。问题并没有阻止我编写所需的程序,但是我编写的最后一个应用程序确实把所有控件都放在一个文件中。
我在这里俯瞰明显的东西吗?
任何帮助将不胜感激。
答案 0 :(得分:1)
首先,您的方法完全可以。
您看到的错误实际上与 Java 没有关系-它是 Scala 编译器输出的!它的全部意思是,当它期望另一种元素({{1时),已经为它提供了一种元素(在这种情况下,该函数接受scalafx.event.ActionEvent
并返回Unit
) }}实例)。
ScalaFX 只是用于 JavaFX 库的一组 Scala 友好包装器;如果没有javafx.event.EventHandler[javafx.event.ActionEvent]
转换函数在两组元素之间进行转换, Scala 编译器将抱怨在需要 JavaFX 时找到 ScalaFX 元素。 em>元素,反之亦然。
解决方案是确保将以下implicit
添加到每个 ScalaFX 源文件中:
import
(您在主源文件的顶部,但没有在其他文件的顶部。)
这将确保将您的 ScalaFX import scalafx.Includes._
处理程序转换为等效的 JavaFX ,从而使您的生活更加轻松。
这是 ScalaFX 的一种非常常见的错误类型,几乎总是通过指定以上ActionEvent
来解决。 (如果import
不能解决您的问题,则通常会出现真正的类型混淆情况,其中您只是简单地使用了错误的对象类型。)
所以,这就是我认为您的代码需要看起来像的样子:
import
:
Main.scala
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.scene.Scene
import buttonsandlabel._
object Main extends JFXApp {
stage = new JFXApp.PrimaryStage {
title = "Test-Program"
scene = new Scene(300, 200) {
content = List(Labels.label, Buttons.button1, Buttons.button2)
}
}
}
:
buttonsandlabel/Labels.scala
package buttonsandlabel
import scalafx.Includes._
import scalafx.scene.control.Label
object Labels {
val label = new Label("Nothing happened yet") {
layoutX = 20
layoutY = 20
}
}
:
buttonsandlabel/Buttons.scala
(请注意,按照惯例,程序包名称通常都是小写。)
您需要了解的一件事是 JavaFX应用程序线程:与 ScalaFX (或 JavaFX )必须在此线程上执行。如果您从其他线程访问 ScalaFX / JavaFX ,则会收到错误异常。 (这可确保所有此类应用程序都是 thread-safe 。)如果您不熟悉多线程,请不必担心, ScalaFX 会以这种方式初始化应用程序这是相当琐碎的。通常,所需要做的只是将初始化代码放入主应用程序对象的构造函数(扩展了package buttonsandlabel
import scalafx.Includes._
import scalafx.scene.control.Button
import scalafx.event.ActionEvent
import Labels.label
object Buttons {
val button1 = new Button("Button 1") {
layoutX = 20
layoutY = 50
onAction = (e: ActionEvent) => {
label.text = "B1 klicked"
}
}
val button2 = new Button("Button 2") {
layoutX = 20
layoutY = 80
onAction = (e: ActionEvent) => {
label.text = "B2 klicked"
}
}
}
的对象)中。
开始在其他类和对象中创建 ScalaFX 元素时,需要格外小心。 JFXApp
在首次引用时被初始化。如果首先由在 JavaFX Application Thread 上执行的 not 代码首先引用,那么您将获得线程错误异常。一种可能的选择是将此类代码放入object
或def
成员中,以便仅在直接引用时才执行。
或者,您可能必须通过lazy val
来调用代码。
有关 JavaFX Application Thread 的更多信息,请参阅JavaFX documentation。