Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
967 views
in Technique[技术] by (71.8m points)

cross compiling - How to provide a stub implementation of JDK classes (like java.awt) in a Scala.js project?

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?

question from:https://stackoverflow.com/questions/65897749/how-to-provide-a-stub-implementation-of-jdk-classes-like-java-awt-in-a-scala-j

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...