感謝@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
這不是Native Java Default時出現的彈出窗口中最令人討厭的問題之一......並且發生同樣的事情!
我的意思是?當LnF不是默認Metal
時,在彈出菜單顯示後單擊任何其他可操作組件上的popupMenu的外部在第一次單擊時不起作用(這隻會將彈出框設置爲不可見)。然後你必須再次點擊組件(第二次)才能觸發它的Action ...非常討厭它了嗎?
想要了解這種情況,只需取消上述代碼的UIManager
部分(我從@Guillaume Polet的美麗解決方案中取得了該部分)並取消註釋我添加的Button
部分,然後運行該程序並查看在發生什麼情況時您在顯示popupMenu
後立即嘗試單擊該按鈕。有趣的是,這個問題不會發生,當使用Java的默認金屬LnF
我已經與Windows 7系統默認外觀和感覺作戰這個問題無濟於事,所以我決定讓睡覺的狗謊言......但說實話,我認爲這件事有一個解決辦法......我知道肯定有人對這件事情有所斬獲......解決這個問題的代碼塊,方向,鏈接,任何地方都會讓我非常高興。感謝好人!
請問什麼'lettersList',爲了更好的幫助,儘快發佈[SSCCE](http://sscce.org/),短的可運行的,可編譯的,只是添加了'JPopup'的'JFrame',僅包含'lettersList' – mKorbel 2013-03-14 18:59:10
'lettersList'只是一個從'letters'數組創建的字符串ArrayList(參見代碼行7),使我能夠檢查(僅在2行)參數'letter'是否是Array的元素之一' letters'。只是不想做一步一步的迭代。 – CodeBurner 2013-03-14 19:20:25
我迷路了,也許有1K的變化,簡單的從這個線程沒有在你身邊的SSCCE – mKorbel 2013-03-14 19:22:03