200

Given a variable with type Graphics, how do I cast it to Graphics2D in Scala?

USB
  • 6,019
  • 15
  • 62
  • 93
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319

2 Answers2

284

The preferred technique is to use pattern matching. This allows you to gracefully handle the case that the value in question is not of the given type:

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

This block replicates the semantics of the asInstanceOf[Graphics2D] method, but with greater flexibility. For example, you could provide different branches for various types, effectively performing multiple conditional casts at the same time. Finally, you don't really need to throw an exception in the catch-all area, you could also return null (or preferably, None), or you could enter some fallback branch which works without Graphics2D.

In short, this is really the way to go. It's a little more syntactically bulky than asInstanceOf, but the added flexibility is almost always worth it.

Daniel Spiewak
  • 54,515
  • 14
  • 108
  • 120
  • 19
    +1 because it's interesting, but a bit too much for this scenario. isn't it? – Eugene Yokota May 31 '09 at 21:07
  • what if I already patternmatched but lost reference to the casted value: base match { case MyConcrete(value) => base.asInstanceOf[MyConcrete].something(value) } , is there a way to get 'base' casted to MyConcrete even if want to extract "value" by exploiting the 'unapply' call performed by "case MyConcrete(value)" ? – mkm Dec 11 '10 at 17:52
  • 4
    Try this: `base match { case base @ MyConcrete(value) => base.something(value) }` Obviously, shadowing `base` is optional. You could just as easily use a different variable name. – Daniel Spiewak Dec 14 '10 at 01:07
  • What I don't get is how would you get the result of this pattern matching cast into a variable? like in java if it was String a = (String) b; what would the scala equivalent be? – James McMahon Jul 19 '12 at 03:58
  • @JamesMcMahon `val gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }` – Kevin Meredith Nov 14 '13 at 21:29
  • Why for casting only, they make it this complicated when in Java it is very easy? – LEMUEL ADANE Nov 25 '14 at 09:56
227
g.asInstanceOf[Graphics2D];
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
  • 37
    Once I got used to Scala, I learnt not to use `asInstanceOf`, since it defeats the purpose of having static type system and feels yucky. – Eugene Yokota Feb 26 '11 at 22:51
  • 27
    Unfortunately, this a common operation when using Swing. For custom painting operations, you need to override the 'public void paintComponent(Graphics g)' method. The Graphics parameter is actually a Graphics2D instance, but a cast is needed. The pattern matching version is probably more verbosity than warranted. Remember: Sedulously eschew obfuscatory hyperverbosity and prolixity! – hohonuuli Oct 16 '11 at 06:19
  • 7
    @hohonuuli I think the cast is fine in that specific case, but if you use `scala-swing` components, paintComponent's parameter is already Graphics2D so no cast required – Luigi Plinge Oct 16 '11 at 08:22
  • 2
    Why its so long? Why "asInstanceOf when can be only be "as" or "asof" keyword or method? Or why they did not just adopt the C++ and Java way as an option because that is the conventional and there is no big problem with that? – LEMUEL ADANE Nov 25 '14 at 10:01
  • 16
    @LemuelAdane The fact that you're using casts at all is a code smell, it makes no sense to make them easier. – Daenyth Dec 04 '14 at 20:30