Files
timi-fx-ui/src/main/java/com/imyeyu/fx/ui/components/ContextMenu.java
2026-05-11 21:38:37 +08:00

64 lines
1.7 KiB
Java

package com.imyeyu.fx.ui.components;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import java.util.List;
/**
* 支持最小尺寸的菜单,默认 90
*
* @author 夜雨
* @since 2023-03-10 11:14
*/
public class ContextMenu extends javafx.scene.control.ContextMenu {
/** 当菜单项 {@link Menu#getProperties()} 携带此标记时,该菜单不继承最小宽度属性 */
public static final String NOT_EXTENDS_FLAG = "NOT_EXTENDS_FLAG";
private static final String STYLE_TEMPLATE = "-fx-min-width: %s; -fx-pref-width: %s";
/**
* 标准构造
*
* @param items 菜单项
*/
public ContextMenu(MenuItem... items) {
super(items);
getItems().addListener((ListChangeListener<MenuItem>) c -> {
while (c.next()) {
if (c.wasAdded()) {
updateMinWidth(getItems());
}
}
});
minWidthProperty().addListener((obs, o, n) -> updateMinWidth(getItems()));
setMinWidth(90);
}
private void updateMinWidth(List<MenuItem> items) {
for (MenuItem item : items) {
if (item instanceof Menu menu) {
if (!menu.getProperties().containsKey(NOT_EXTENDS_FLAG)) {
boolean isItemsMenu = false; // 为 true 时表示子菜单是一般菜单项,继续应用最小宽度
ObservableList<MenuItem> subItems = menu.getItems();
for (MenuItem subItem : subItems) {
if (subItem.getClass().equals(MenuItem.class)) {
isItemsMenu = true;
break;
}
}
if (isItemsMenu) {
updateMinWidth(menu.getItems());
}
}
} else {
item.setStyle(STYLE_TEMPLATE.formatted(getMinWidth(), getMinWidth()));
}
}
}
}