プロセスでSSCCE cosを試して書くように私に勧めてくれた@mKorbelに感謝し、解決策を見つけました。とにかく、これが私のSSCCEです。他の人にとっては役立つかもしれません。知るか?コピーして実行するだけで、どのように機能するかを確認できます。
(注: コードはそれほど短くはありませんが、この後に提起する予定の二次的な質問のためです)
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class CustomPopup extends JPopupMenu
{
private JMenuItem menuItem1 = new JMenuItem("One");
private JMenuItem menuItem2 = new JMenuItem("Two");
private JMenuItem menuItem3 = new JMenuItem("Three");
private JMenuItem menuItem4 = new JMenuItem("Four");
private JMenuItem menuItem5 = new JMenuItem("Five");
public CustomPopup()
{
this.add(menuItem1);
this.add(menuItem2);
this.add(menuItem3);
this.add(menuItem4);
this.add(menuItem5);
addListeners(this);
}
private void addListeners(final JPopupMenu popup /*, final String someLetter*/)
{
popup.addPopupMenuListener(new PopupMenuListener(){
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent evt)
{
JMenuItem menuItem = (JMenuItem)popup.getComponent(3);
String[] letters = {"A", "B", "C", "D"};
ArrayList<String> lettersList = new ArrayList<String>();
lettersList.addAll(Arrays.asList(letters));
String someLetter = getRandomAlphabet();
if(lettersList.contains(someLetter)){
menuItem.setEnabled(true);
}
else{
menuItem.setEnabled(false);
}
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent evt){
// No Override
}
@Override
public void popupMenuCanceled(PopupMenuEvent evt){
// No Override
}
});
}
private String getRandomAlphabet()
{
String alpha = "";
String Alphas[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"};
double bigNum = Math.random() * 1000000;
String str = String.valueOf(bigNum);
int idx = Integer.valueOf(String.valueOf(str.charAt(str.length() - 1)));
if(idx < 6)
{
alpha = Alphas[idx];
}
else
{
alpha = Alphas[idx - 5];
}
return alpha;
}
public static void main(String[] args)
{
/*try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
JPanel panel = new JPanel();
JPopupMenu popupMenu = new CustomPopup();
panel.setComponentPopupMenu(popupMenu);
panel.setLayout(new GridBagLayout());
/*JButton button = new JButton("Action");
button.setSize(new Dimension(60, 20));
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(null, "Button was clicked");
}
});
panel.add(button);*/
JFrame frame = new JFrame("popupTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(200, 200));
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
質問: これでやりたいことができたので (つまり、menuItem4
指定された計算からのランダムな結果に基づいて動的に有効化および無効化するgetRandomAlphabet()
)、@Guillaume Polet の Lovely 実装を見てテストしました。とてもいいですね...それで、ボタンを追加してUIManager
、ネイティブJavaのデフォルトではないポップアップを使用したときにこれまでに発生した最も厄介な問題の1つをテストすることにしました...そして同じことが起こります!
どういう意味ですか?LnF が defaultMetal
でない場合、popupMenu が表示された後に他の Actionable コンポーネントの popupMenu の外側をクリックしても、最初のクリックでは機能しません (これはポップアップを非表示に設定するだけです)。次に、コンポーネントのアクションを起動する前に、コンポーネントをもう一度 (2 回目) クリックする必要があります... 非常に面倒ですよね?
このシナリオの感触をUIManager
つかむには、上記のコードのセクションのコメントを外し (@Guillaume Polet の美しいソリューションから取得しました)、Button
追加したセクションのコメントを外してから、プログラムを実行して、が表示された直後のボタンpopupMenu
。面白いことに、Java のデフォルトの Metal LnF
を使用している場合、この問題は発生しません。Windows 7 でシステムのデフォルトのルック アンド フィールを使用してこの問題と戦いましたが、役に立たなかったので、寝ている犬を寝かせることにしました...このことの回避策...このことをハックした人がいるに違いないことは知っています...コードブロック、方向、リンク、何でも、この問題を解決する場所はどこでも私の最大の喜びです。良い人たちに感謝します!