Schnipp
Schnipp

Reputation: 81

Right Click on a Button / Scala

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

Upvotes: 8

Views: 1436

Answers (3)

Moritz Schmidt
Moritz Schmidt

Reputation: 2813

The following works for me:

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

def handleClick(isLeftClick: Boolean): Unit = {
   //
}

Upvotes: 0

0__
0__

Reputation: 67280

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.

Upvotes: 2

Aldo Stracquadanio
Aldo Stracquadanio

Reputation: 6237

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

Upvotes: 0

Related Questions