8

I'm currently trying to code a minesweeper using scala, but I can't find the way to listen to a right click on a button.

I've already searched on the Internet the way to do it, but I definitely was not able to find it.

If anyone could help me out, I would be really grateful :)

Thanks,

Schnipp

(Note: Scala is a new language to me and I am not a Java user, so I am sorry if my questions sound dumb)

EDIT:

I am trying to find (or implement) a function 'ButtonClickedRight' that could listen to a right-click on a button.

like this

import scala.swing._
import scala._
import scala.swing.event._

object Right extends MainFrame with App {
    title = ""
    visible = true

    val b = new button("")
    listenTo(b)
    reactions += {
       case ButtonClicked(`b`) => *code*
       case ButtonClickedRight(`b`) => *code*
    }
}

EDIT 2 --

I would like to know if the user has clicked on the Button "1" or not. The problem I have is that this code prints "Mouse clicked at " + e.point+" type "+e.modifiers when I click on the label but not on the button.

object App extends SimpleSwingApplication {
  lazy val ui = new GridPanel(2,1) {
    contents += new Button("1")
    contents += new Label("2")
    listenTo(mouse.clicks)
    reactions += {
      case e: MouseClicked =>
        println("Mouse clicked at " + e.point+" type "+e.modifiers)
    }
  }
  def top = new MainFrame {
    contents = ui
    visible = true
    preferredSize = new Dimension(500,500)
  }
}
Schnipp
  • 81
  • 3
  • 1
    Which graphics toolkit/library are you using? Assuming Swing, your google-fu is weak: http://stackoverflow.com/questions/6877117/how-do-i-recognize-mouse-clicks-in-scala and http://stackoverflow.com/questions/3700730/scala-mouseevent-how-to-know-which-button-was-pressed – The Archetypal Paul Feb 22 '15 at 15:13
  • 1
    Thank you for you answer. I had seen these two questions before posting but I can't understand how it works. I am sorry my question was not clear enough (I am indeed using swing). I've edited the question. – Schnipp Feb 26 '15 at 06:53
  • So, what's working or not working? What error are you getting? What is happening and what did you expect? – The Archetypal Paul Feb 26 '15 at 10:34
  • I would like to know if the user has right-clicked on a button. I don't know how to add some code in a comment, so I edited my question. – Schnipp Mar 01 '15 at 08:44

3 Answers3

2

Button events are fired through a specific publisher .mouse.clicks.

import scala.swing._
import scala.swing.event._

object App extends SimpleSwingApplication {
  lazy val ui = new GridPanel(2,1) {
    val button = new Button("1")
    contents += button
    contents += new Label("2")
    listenTo(button.mouse.clicks) // !
    reactions += {
      case evt @ MouseClicked(`button`, pt, _, _, _) =>
        val which = evt.peer.getButton
        if (which > 1) {
          println(s"Mouse clicked at (${pt.x}; ${pt.y}) - button: $which")
        }
    }
  }
  lazy val top = new MainFrame {
    contents = ui
    size = new Dimension(500,500)
  }
}

Note that at least on Linux my right button has number 3 not 2. You could also use the triggersPopup flag, but then you must ensure to monitor both MousePressed and MouseReleased, as this flag is platform-dependent.

0__
  • 66,707
  • 21
  • 171
  • 266
0

I think that you are on the right path, for my understanding of scala swings I think that the problem is that you are not attaching the listener correctly. For one I would assign the button to a value and call listenTo only on it:

val button = new Button("1")
listenTo(button)

Then, in the reactions, I would write the pattern checking in the event that it comes from the button (probably redundant if you only call listenTo passing the button) and that it has the correct button:

case ButtonClicked(b) if b == button && b.peer.getButton == MouseEvent.BUTTON_2 => ...

So the code you provided in your edit would become:

object App extends SimpleSwingApplication {
  lazy val ui = new GridPanel(2,1) {
    val button = new Button("1")
    contents += button
    contents += new Label("2")
    listenTo(button)
    reactions += {
      case evt @ MouseClicked(b, pt, _, _, _) if b == button && evt.peer.getButton == java.awt.event.MouseEvent.BUTTON2 =>
        println(s"Mouse clicked at (${pt.x}; ${pt.y}) - button: ${evt.peer.getButton}")
    }
  }
  def top = new MainFrame {
    contents = ui
    visible = true
    preferredSize = new Dimension(500,500)
  }
}
Aldo Stracquadanio
  • 6,167
  • 1
  • 23
  • 34
  • I'd love to award this bounty, but I'd need the code to actually compile in Scala (preferably 2.11). I'm getting the following errors: `object MouseEvent is not a member of package scala.swing.event Note: class MouseEvent exists, but it has no companion object. value getButton is not a member of javax.swing.AbstractButton` – Walrus the Cat Oct 15 '15 at 16:28
  • The reason is that the `MouseEvent` I am referring to is from `java.awt`. I updated my code example, please let me know if neither that compiles. – Aldo Stracquadanio Oct 15 '15 at 16:55
  • thanks -- still getting `value getButton is not a member of javax.swing.AbstractButton` – Walrus the Cat Oct 15 '15 at 17:43
  • apparently `ButtonClicked` extends `ActionEvent`, whereas `MouseEvent` extends `InputEvent`. Thoughts? – Walrus the Cat Oct 15 '15 at 18:08
  • Right, I made another mistake, I edited it, I wonder if there is any way to use the `Modifiers` from the event rather than resorting to the awt peer but I couldn't find any. – Aldo Stracquadanio Oct 15 '15 at 21:32
  • this isn't printing anything for me, even after removing the `if` tests precedent to the `println` statement in the pattern matching. – Walrus the Cat Oct 16 '15 at 22:18
  • or to keep it classy you could just not respond. that'd be high status. – Walrus the Cat Oct 20 '15 at 17:52
0

The following works for me:

new Button {
   listenTo(mouse.clicks)
   reactions += {
     case MouseClicked(_, _, c, _, _) => handleClick(c == 0)
   }
}

def handleClick(isLeftClick: Boolean): Unit = {
   //
}
Moritz Schmidt
  • 2,635
  • 3
  • 27
  • 51