问题
Here is my attempt to provide a dummy implementation of a part of java.awt
related to Graphics2D
:
package java
package object awt {
object RenderingHints {
type Key = Int
val KEY_TEXT_ANTIALIASING = 0
val VALUE_TEXT_ANTIALIAS_ON = 0
}
object Color {
val GREEN = 0
}
type Color = Int
object image {
object BufferedImage {
val TYPE_INT_RGB = 0
}
class BufferedImage(w: Int, h: Int, tpe: Int) {
def createGraphics: Graphics2D = new Graphics2D
}
}
class Graphics2D {
def setColor(c: Color): Unit = ()
def fillRect(x: Int, y: Int, width: Int, height: Int): Unit = ()
def setRenderingHint(hintKey: RenderingHints.Key, hintValue: Any): Unit = ()
def drawString(str: String, x: Int, y: Int): Unit = ()
def dispose() = ()
}
}
This stub implementation is intended to allow cross-compilation of functions using Graphics2D
between JVM / Scala.js, in a code like:
import java.awt.image.BufferedImage
import java.awt
val bim = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB)
val g2d = bim.createGraphics()
g2d.setColor(aw.Color.GREEN)
g2d.fillRect(0, 0, 10, 10)
g2d.setRenderingHint(awt.RenderingHints.KEY_TEXT_ANTIALIASING, awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
g2d.setColor(awt.Color.BLACK)
g2d.drawString("Hello", 0, 20)
g2d.dispose()
The code compiles fine both on JVM and JS, the trouble is it does not pass fastOptJS
, I get errors like:
[error] Referring to non-existent class java.awt.image.BufferedImage
[error] Referring to non-existent class java.awt.Graphics2D
In fact, the code compiles fine even without my java.awt
stub, therefore it seems Scala.js somehow uses some other java.awt
sources, probably from a JDK. Is there a way I could convince the compiler to use the classes I have provided instead?
回答1:
Classes inside objects (including package objects) and packages are not the same thing on a binary (i.e. class-file) level (neither in Scala JVM nor Scala.js).
You need to put the classes into their respective packages (not objects):
package java.awt
object RenderingHints {
class Key { /* snip */ }
val KEY_TEXT_ANTIALIASING = 0
val VALUE_TEXT_ANTIALIAS_ON = 0
}
class Color { /* snip */ }
object Color { /* snip */ }
class Graphics2D { /* snip */ }
package java.awt.image
class BufferedImage { /* snip */ }
object BufferedImage { /* snip */ }
Further, as you can see from the example, you cannot use type aliases in stead of a class. Type aliases do not exist at the binary level, so a real class is required.
If you need nested static objects, you explicitly need to enable these in the Scala.js compiler (see the end of #3950).
来源:https://stackoverflow.com/questions/65897749/how-to-provide-a-stub-implementation-of-jdk-classes-like-java-awt-in-a-scala-j