J'implémente un jeu où le joueur peut placer une pièce en faisant un clic droit sur le plateau de jeu et en choisissant l'une des pièces parmi un menu contextuel. En mode "hot seat", les deux joueurs utilisent la même interface utilisateur, ce qui permet d'afficher différentes instances de menu. Le problème est que l'appel de la méthode JMenuItem.show
entraîne le rendu incorrect du mauvais menu, puis son remplacement rapide par le bon menu (vous pouvez dire que les icônes utilisées dans les entrées de menu ont des couleurs de fond différentes pour chaque lecteur). Je peux aggraver le problème en ajoutant Thread.sleep(1000)
immédiatement après avoir appelé show
. Ensuite, cliquez avec le bouton droit de la souris sur le menu de l'autre joueur précédemment affiché (ou seulement sur l'arrière-plan de la bonne taille, sur la toute première invocation) pendant une seconde, suivi d'un rafraîchissement du menu.Comment rendre un JPopupMenu immédiatement?
Y at-il un moyen de rendre le menu correct immédiatement?
Vous ne savez pas si cela est important, mais il n'y a aucun appel à repaint
n'importe où dans le rappel de traitement de clic dans la branche isPopupTrigger
.
Edit: ajout d'un exemple dans Scala
import java.awt.event._
import javax.swing._
object MenuDemo extends App {
val frame = new JFrame()
frame.setTitle("Menu Demo")
frame.setSize(600, 400)
frame.setLocation(0, 0)
frame.addWindowListener(new WindowAdapter {
override def windowClosing(e: WindowEvent): Unit = System.exit(0)
})
var index = 0
def tick() = index = (index + 1) % 2
def makeMenuItem(i: Int) = {
val menuItem = new JMenuItem("item in menu #" + i)
menuItem.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = tick()
})
menuItem
}
def makeMenu(i: Int) = {
val menu = new JPopupMenu()
menu.add(makeMenuItem(i))
menu
}
val menus: Seq[JPopupMenu] = Seq(0, 1).map(i => makeMenu(i))
def showMenu(e: MouseEvent): Unit = {
menus(index).show(e.getComponent, e.getX, e.getY)
Thread.sleep(1000)
}
val panel = new JPanel()
panel.add(new JLabel("right click me"))
panel.addMouseListener(new MouseAdapter {
override def mousePressed(e: MouseEvent): Unit = {
if (e.isPopupTrigger) showMenu(e)
}
override def mouseReleased(e: MouseEvent): Unit = {
if (e.isPopupTrigger) showMenu(e)
}
})
frame.getContentPane.add(panel)
frame.setVisible(true)
}
Edit 2
Je ne vois que ce comportement sur un Mac. Sous Windows, le délai se produit avant l'affichage du menu.
Pensez à poster un [mcve] qui reproduit le problème. – copeg
'Yat-il un moyen de rendre le menu correct immédiatement?' - C'est le comportement par défaut, le problème est avec votre code. Lisez la section du tutoriel Swing sur [Appeler un menu contextuel] (http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#popup) pour un exemple de travail – camickr