2016-08-14 5 views
0

私はゲームボードを右クリックし、ポップアップメニューからいくつかのピースを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では、メニューが表示される前に遅延が発生します。

+1

問題を再現する[mcve]を投稿することを検討してください。 – copeg

+0

'正しいメニューをすぐにレンダリングする方法はありますか? ' - これはデフォルトの動作です。問題はコードにあります。 [ポップアップメニューを表示する]のSwingチュートリアルのセクションを参照してください(動作例については – camickr

答えて

0

showメソッドが呼び出された後にメニュー項目が再構成されているように聞こえることがあります。たとえば、javax.swing.event.PopupMenuListener.popupMenuWillBecomeVisibleは、コンテキストに応じてメニュー項目をリセットしている可能性があります。

この場合、コンテキストによっては、ポップアップメニューの2つの異なるインスタンスを表示し、そのうちの1つを表示することによってフリッカーを避けることができます。

+0

を参照してください)。それは私が持っていたものとまったく同じです(http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#popup)。 :2つのメニュー、再編成なし(個々のエントリの有効化と無効化を除く) – StokedOver9k

関連する問題