java - 当我更改 JMenuItem 的文本内容时,告诉 Swing 重新计算 JMenu 宽度

标签 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 调用之后添加适当的代码,以正确更新项目的大小。我应该调用什么方法?

最佳答案

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);
    });
  }
}

关于java - 当我更改 JMenuItem 的文本内容时,告诉 Swing 重新计算 JMenu 宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36755146/

相关文章:

java - JSCH Java 小程序

java - 如何在不创建java对象的情况下从包内的所有类访问方法

java - 静态内部类与 Companion 的内部类

java - 如果不推荐使用 Swing,还有什么替代方案?

java - 如何从 Spring 中的 Soap 消息中提取附件

java - 获取 俄罗斯时间 与当前电话时间之间的时差

java - JTable 不会动态添加行

java - 具有 ActionListener 和 DocumentListener 的 JTextField

java - InternalFrame 中的 ActionListener 打开另一个 InternalFrame

java - 如何通过单击按钮进行绘画