私はゲームボードを右クリックし、ポップアップメニューからいくつかのピースを1つ選んでピースを置くことができるゲームを実装しています。 「ホットシート」モードでは、両方のプレイヤーが同じUIを使用しているため、異なるメニューインスタンスが表示されます。すぐにJPopupMenuをレンダリングするには?
JMenuItem.show
メソッドを呼び出すと、間違ったメニューが最初にレンダリングされ、すぐに正しいメニューに置き換えられます(メニューエントリに使用されているアイコンの色がプレーヤーごとに異なるため)。
show
を呼び出した直後にThread.sleep(1000)
を追加することで問題を悪化させる可能性があります。その後、右クリックすると、1秒間前に表示された他のプレイヤーのメニュー(または最初の呼び出しで正しいサイズの背景のみ)が表示され、次にメニューがリフレッシュされ、正しい部分がレンダリングされます。
正しいメニューをすぐにレンダリングする方法はありますか?
これが重要であるかどうかはわかりませんが、isPopupTrigger
ブランチのクリック処理コールバックのどこでもrepaint
への呼び出しがありません。
編集: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)
}
編集2
私はMac上でこの振る舞いを見ている場合の例を追加。 Windowsでは、メニューが表示される前に遅延が発生します。
問題を再現する[mcve]を投稿することを検討してください。 – copeg
'正しいメニューをすぐにレンダリングする方法はありますか? ' - これはデフォルトの動作です。問題はコードにあります。 [ポップアップメニューを表示する]のSwingチュートリアルのセクションを参照してください(動作例については – camickr