我在我的應用程序中有一個彈出式菜單,我想用自定義的替換,以使其與應用程序的其餘部分的外觀&相匹配。實質上,我不想在彈出窗口中使用正常的菜單項,而是要重用應用程序中其他位置已存在的組件,以便以「分頁」方式瀏覽項目層次結構,而不是使用子菜單。因此,如果您單擊包含子項目的列表中的項目,則會顯示下一個頁面,將列表中的當前項目替換爲所單擊項目的子項列表。更新JPopupMenu高度,同時可見
使用「分頁」組件的好處是它可以很好地適應應用程序的其他部分(它已經用於其他不是彈出窗口的地方),並且在瀏覽時有一些漂亮的動畫效果頁面。
我遇到的問題是分頁組件的首選高度在顯示不同的頁面時發生變化(列表中項目的數量發生變化),我希望彈出菜單高度更新以便它適合分頁組件確切地說,但到目前爲止,我們嘗試更新彈出式菜單的高度時卻發現失敗。
下面是一個示例應用程序演示該問題:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class PopupSizeTestFrame extends JFrame {
private static final int PREFFERED_WIDTH = 300;
private static JPanel resizingPanel;
private static JPopupMenu popupMenu;
private static PopupSizeTestFrame frame;
private static void resizePopupMenu() {
// What should I do here so that the size of the popup menu is updated?
/**
* Calling pack() works in this example, but I cannot call pack in the
* actual application since there is a smooth transition animation when
* clicking on the inner panel and pack() essentially re-adds the
* components of the popup menu (removeNotify and addNotify is called),
* which interferes with the animation and causes the menu to flicker.
* The flickering when clicking the inner panel can also be seen in this
* example when uncommenting the pack() call.
*/
//popupMenu.pack();
//
// I tried combinations of the following, without success:
//popupMenu.invalidate();
//popupMenu.revalidate();
//popupMenu.validate();
//popupMenu.doLayout();
// Repaint
popupMenu.repaint();
}
public static void main(String args[]) {
// Create popup child panel with height that changes when clicked
resizingPanel = new JPanel(new BorderLayout());
int initialHeight = 30;
final JLabel label = new JLabel("Click me (" + initialHeight + "px)");
resizingPanel.add(label);
resizingPanel.setBackground(Color.GREEN);
resizingPanel.setPreferredSize(new Dimension(PREFFERED_WIDTH, initialHeight));
resizingPanel.addMouseListener(new MouseAdapter() {
private int clickCount = 0;
@Override
public void mouseClicked(MouseEvent e) {
int height = ((clickCount % 3) + 1) * 50;
resizingPanel.setPreferredSize(new Dimension(PREFFERED_WIDTH, height));
clickCount++;
label.setText("Click me (" + height + "px)");
resizePopupMenu();
}
});
// Create popup
popupMenu = new JPopupMenu();
popupMenu.setLayout(new BorderLayout());
popupMenu.add(new JLabel("Header"), BorderLayout.NORTH);
popupMenu.add(resizingPanel, BorderLayout.CENTER);
popupMenu.add(new JLabel("Footer"), BorderLayout.SOUTH);
// Create frame
frame = new PopupSizeTestFrame();
frame.setLayout(new BorderLayout());
frame.setPreferredSize(new Dimension(400, 400));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
popupMenu.show(frame, e.getX(), e.getY());
}
}
});
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame.setVisible(true);
}
});
}
}
運行例如當上面,你會看到,如果它被關閉和被點擊的內板後打開彈出式菜單尺寸被更新,但它在彈出窗口不可見時不會更新。
我可以在resizePopupMenu()中做些什麼來更新JPopupMenu的高度?
必須爲包容器調用JPopupMemu(BasicPopupSomething,可從Window或SwingUtilities訪問) – mKorbel 2014-10-06 10:29:47
@mKorbel非常感謝你,這個技巧:'SwingUtilities.getWindowAncestor(popupMenu).pack();'。如果您將其添加爲答案,我會將其標記爲正確。 – ughzan 2014-10-06 12:43:30
正確/正確的方式之一+1 :-) – mKorbel 2014-10-06 12:54:17