package com.fr.plugin.event.manager.ui; import com.fr.base.GraphHelper; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButtonUI; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.general.IOUtils; import com.fr.plugin.event.manager.data.MyTree; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; /** * 单元格控件面板,包含一个sheet选择器和一个事件配置面板 * @author Joe * Created by Joe on 12/13/2020 */ public class CellWidgetPane extends BasicPane { private static final Icon LEFT_ICON = IOUtils.readIcon("com/fr/design/images/sheet/left_normal@1x.png"); private static final Icon RIGHT_ICON = IOUtils.readIcon("com/fr/design/images/sheet/right_normal@1x.png"); private static final Icon DISABLED_LEFT_ICON = IOUtils.readIcon("com/fr/design/images/sheet/left_hover@1x.png"); private static final Icon DISABLED_RIGHT_ICON = IOUtils.readIcon("com/fr/design/images/sheet/right_hover@1x.png"); private static final String ELLIPSIS = "..."; // sheetFlowPane的最大宽度 private static final int MAX_WIDTH = 810; // sheetChoosePane的理想高度 private static final int PREFERRED_HEIGHT = 24; // flow布局的默认水平间距 private static final int FLOW_GAP = 5; // 按钮的额外宽度,加上按钮文字长度可得整个按钮的宽度 private static final int BUTTON_EXTRA_WIDTH = 20; private List cellWidgetTrees; private EventConfigPane eventConfigPane; public CellWidgetPane(List cellWidgetTrees) { this.cellWidgetTrees = cellWidgetTrees; initComponentPane(); } private void initComponentPane() { setLayout(new BorderLayout(4, 0)); refreshUI(); } public String tabTitle() { return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Tab_Cell"); } @Override protected String title4PopupWindow() { return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Tab_Cell"); } /** * 刷新整个面板 * 初始化和从para切换到cell时会触发 */ public void refreshUI() { removeAll(); eventConfigPane = new EventConfigPane(cellWidgetTrees.size() > 0 ? cellWidgetTrees.get(0) : new MyTree()); add(eventConfigPane, BorderLayout.CENTER); SheetChoosePane sheetChoosePane = new SheetChoosePane(); add(sheetChoosePane, BorderLayout.NORTH); repaint(); revalidate(); } /** * 刷新事件配置面板 * 当切换sheet时触发 * * @param myTree sheet节点 */ private void populate(MyTree myTree) { eventConfigPane.setTree(myTree); eventConfigPane.refreshUI(); } /** * 为了更新此对象包含的事件配置面板 */ public void update() { eventConfigPane.update(); } /** * Sheet选择器 */ private class SheetChoosePane extends JPanel { // 总sheet按钮数 private int totalCount; // 展示的sheet按钮数 private int showCount = 0; // sheet宽度数组 private int[] widthArray; // 选中的sheet的index private int selectedIndex = 0; // 最左边的sheet的index private int scrollIndex = 0; // button数组 private List buttonList; // 左边的panel private JPanel sheetFlowPane; /** * 左移和右移按钮 */ private UIButton leftButton; private UIButton rightButton; public SheetChoosePane() { totalCount = cellWidgetTrees.size(); buttonList = new ArrayList<>(); initComponentPane(); } private void initComponentPane() { setLayout(FRGUIPaneFactory.createBorderLayout()); setBorder(BorderFactory.createEmptyBorder(4, 8, 0, 8)); add(createButtonPane(), BorderLayout.EAST); initSheetFlowPane(); add(sheetFlowPane, BorderLayout.CENTER); } /** * 初始化左边的sheet按钮面板 */ private void initSheetFlowPane() { sheetFlowPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); initWidthAndButtonArray(); addButton(); checkButton(showCount < widthArray.length); } /** * 创建前后按钮面板 * @return */ private JPanel createButtonPane() { leftButton = new UIButton(LEFT_ICON) { @Override public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, PREFERRED_HEIGHT); } }; leftButton.setUI(new UIButtonUI() { @Override protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { if (isPressed(b) && b.isPressedPainted()) { GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), UIConstants.PROPERTY_PANE_BACKGROUND); } else if (isRollOver(b)) { GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), UIConstants.PROPERTY_PANE_BACKGROUND); } else if (b.isNormalPainted()) { GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); } } }); leftButton.set4ToolbarButton(); leftButton.setDisabledIcon(DISABLED_LEFT_ICON); leftButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { moveLeft(); } }); rightButton = new UIButton(RIGHT_ICON) { @Override public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, PREFERRED_HEIGHT); } }; rightButton.setUI(new UIButtonUI() { @Override protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { if (isPressed(b) && b.isPressedPainted()) { GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), UIConstants.PROPERTY_PANE_BACKGROUND); } else if (isRollOver(b)) { GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), UIConstants.PROPERTY_PANE_BACKGROUND); } else if (b.isNormalPainted()) { GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); } } }); rightButton.set4ToolbarButton(); rightButton.setDisabledIcon(DISABLED_RIGHT_ICON); rightButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { moveRight(); } }); JPanel buttonPane = new JPanel(new BorderLayout(0, 0)); buttonPane.add(rightButton, BorderLayout.EAST); buttonPane.add(leftButton, BorderLayout.CENTER); return buttonPane; } /** * 点击前一个 */ private void moveLeft() { if (scrollIndex > 0) { scrollIndex--; refreshSheetFlowPane(); } } /** * 点击后一个 */ private void moveRight() { if (scrollIndex < totalCount - showCount) { scrollIndex++; refreshSheetFlowPane(); } } /** * 刷新左边的sheet按钮面板 */ private void refreshSheetFlowPane() { sheetFlowPane.removeAll(); sheetFlowPane.repaint(); addButton(); sheetFlowPane.revalidate(); } /** * 动态添加按钮到sheetFlowPane上 */ private void addButton() { showCount = 0; int currentWidth = FLOW_GAP; for (int i = scrollIndex; i < totalCount; i++) { currentWidth += widthArray[i] + FLOW_GAP; if (currentWidth > MAX_WIDTH) { break; } else { UIToggleButton button = buttonList.get(i); if (selectedIndex == i) { // 如果是选中状态 button.setSelected(true); } sheetFlowPane.add(button); showCount++; } } } /** * 更新前后按钮的可用状态 * @param buttonEnabled */ private void checkButton(boolean buttonEnabled) { leftButton.setEnabled(buttonEnabled); rightButton.setEnabled(buttonEnabled); } /** * 根据名字和个数计算出所有tab的宽度和名称 * * @return */ private void initWidthAndButtonArray() { widthArray = new int[totalCount]; for (int i = 0; i < totalCount; i++) { final int index = i; String sheetName = cellWidgetTrees.get(i).getData().getNodeName(); if (getStringWidth(sheetName) > MAX_WIDTH - 2 * FLOW_GAP) { sheetName = getEllipsisName(sheetName, MAX_WIDTH - 2 * FLOW_GAP); } // 按钮除了字符串还有20的宽度 widthArray[i] = getStringWidth(sheetName) + BUTTON_EXTRA_WIDTH; UIToggleButton button = new UIToggleButton(sheetName) { @Override protected MouseListener getMouseListener() { return new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { setSelectedStatus(index); eventConfigPane.update(); populate(cellWidgetTrees.get(index)); } }; } }; buttonList.add(button); } } /** * 当sheet被点击时的触发动作,只有它本身是被选中状态 * @param index */ private void setSelectedStatus(int index) { selectedIndex = index; for (int i = 0; i < buttonList.size(); i++) { if (i == index) { buttonList.get(i).setSelected(true); } else { buttonList.get(i).setSelected(false); } } } /** * 获取字符串宽度 * @param str * @return */ private int getStringWidth(String str) { return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str); } /** * 判断tab文字的长度大于能装下的最大文字长度,要用省略号 * @param name * @param maxStringlength * @return */ private String getEllipsisName(String name, int maxStringlength) { //若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度 int ellipsisWidth = getStringWidth(ELLIPSIS); int leftKeyPoint = 0; int rightKeyPoint = name.length() - 1; int leftStrWidth = 0; int rightStrWidth = 0; while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) { if (leftStrWidth <= rightStrWidth) { leftKeyPoint++; } else { rightKeyPoint--; } leftStrWidth = getStringWidth(name.substring(0, leftKeyPoint)); rightStrWidth = getStringWidth(name.substring(rightKeyPoint)); if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) { if (leftStrWidth <= rightStrWidth) { rightKeyPoint++; } break; } } return name.substring(0, leftKeyPoint) + ELLIPSIS + name.substring(rightKeyPoint); } } }