当我更改JMenuItem

时间:2016-04-20 21:04:10

标签: java swing

我有点懒,而不是制作另一个窗口,我为我的更新管理器创建了单个菜单。我打算制作窗口,但还有更重要的任务要参加,所以现在必须这样做:

image description

当有更新时,单击最后一个菜单项会动态更改文本。如果用户当时正在查看菜单项,则JMenu的大小不会改变:

image description

如果我将鼠标移开并导航回菜单,则大小正确:

image description

我需要告诉Swing在更改文本时更新JMenuItem的大小。我有一个名为UpdateMenuItem的类,它使用以下函数扩展JMenuItem

  public void setDownloadAvailable(final VersionId version) {
    // Checking if the code runs in correct thread
    // this should probably also raise a warning if not in the swing thread
    if(!SwingUtilities.isEventDispatchThread()) {
      SwingUtilities.invokeLater(()->setDownloadAvailable(version));
      return;
    }
    // this is how the menu text changes
    setText("Click to download: "+version);
    setBackground(Color.ORANGE);
  }

我需要在setText调用后添加适当的代码才能正确更新项目的大小。我应该用什么方法打电话?

1 个答案:

答案 0 :(得分:1)

JMenu#getPopupMenu()JPopupMenu#pack()对我来说很好:

import java.awt.*;
import javax.swing.*;

public class JMenuItemPackTest {
  public JMenuBar makeMenuBar() {
    JMenuItem label = new JMenuItem("Up to date: 3.5-beta");
    label.setBackground(Color.GREEN);
//     UpdateMenuItem label = new UpdateMenuItem("Up to date: 3.5-beta") {
//       @Override public void setDownloadAvailable(final VersionId version) {
//         super.setDownloadAvailable(version);
//         Container c = SwingUtilities.getUnwrappedParent(this);
//         if (c instanceof JPopupMenu) {
//           ((JPopupMenu) c).pack();
//         }
//       }
//     };

    JMenu update = new JMenu("Updates");
    update.add(new JCheckBoxMenuItem("Auto-check for updates"));
    update.add(new JCheckBoxMenuItem("Auto-download"));
    update.add(label);

    JMenu menu = new JMenu("Help");
    menu.add(update);

    (new Timer(5000, e -> {
      //...
      label.setText("Click to download: 3.5-beta");
      label.setBackground(Color.ORANGE);
      update.getPopupMenu().pack();
      //or:
      //Container c = SwingUtilities.getUnwrappedParent(label);
      //if (c instanceof JPopupMenu) {
      //  ((JPopupMenu) c).pack();
      //}
    })).start();

    JMenuBar menubar = new JMenuBar();
    menubar.add(menu);
    return menubar;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.setJMenuBar(new JMenuItemPackTest().makeMenuBar());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}