|
|
|
@ -1,8 +1,7 @@
|
|
|
|
|
package com.fr.design.file; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.fr.base.GraphHelper; |
|
|
|
|
import com.fr.base.svg.IconUtils; |
|
|
|
|
import com.fine.theme.icon.LazyIcon; |
|
|
|
|
import com.fr.base.vcs.DesignerMode; |
|
|
|
|
import com.fr.design.actions.UpdateAction; |
|
|
|
|
import com.fr.design.actions.file.LocateAction; |
|
|
|
@ -15,67 +14,45 @@ import com.fr.design.i18n.DesignSizeI18nManager;
|
|
|
|
|
import com.fr.design.i18n.Toolkit; |
|
|
|
|
import com.fr.design.mainframe.DesignerContext; |
|
|
|
|
import com.fr.design.mainframe.JTemplate; |
|
|
|
|
import com.fr.design.mainframe.TemplateSavingChecker; |
|
|
|
|
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager; |
|
|
|
|
import com.fr.design.utils.DesignUtils; |
|
|
|
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
|
|
|
import com.fr.design.utils.gui.GUIPaintUtils; |
|
|
|
|
import com.fr.design.worker.WorkerManager; |
|
|
|
|
import com.fr.design.worker.save.CallbackSaveWorker; |
|
|
|
|
import com.fr.file.FILE; |
|
|
|
|
import com.fr.file.FileNodeFILE; |
|
|
|
|
import com.fr.general.ComparatorUtils; |
|
|
|
|
import com.fr.general.IOUtils; |
|
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
|
import com.fr.stable.Constants; |
|
|
|
|
import com.fr.stable.collections.combination.Pair; |
|
|
|
|
import com.fr.third.javax.annotation.Nonnull; |
|
|
|
|
import com.fr.workspace.WorkContext; |
|
|
|
|
import com.fr.workspace.server.lock.TplOperator; |
|
|
|
|
|
|
|
|
|
import javax.swing.BorderFactory; |
|
|
|
|
import javax.swing.ButtonModel; |
|
|
|
|
import javax.swing.Icon; |
|
|
|
|
import javax.swing.ImageIcon; |
|
|
|
|
import javax.swing.JComponent; |
|
|
|
|
import javax.swing.JMenu; |
|
|
|
|
import javax.swing.JMenuItem; |
|
|
|
|
import javax.swing.JOptionPane; |
|
|
|
|
import javax.swing.JPanel; |
|
|
|
|
import javax.swing.JSeparator; |
|
|
|
|
import javax.swing.MenuElement; |
|
|
|
|
import javax.swing.SwingConstants; |
|
|
|
|
import javax.swing.SwingUtilities; |
|
|
|
|
import javax.swing.ToolTipManager; |
|
|
|
|
import javax.swing.plaf.basic.BasicMenuItemUI; |
|
|
|
|
import java.awt.AWTEvent; |
|
|
|
|
import java.awt.AlphaComposite; |
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
import java.awt.Color; |
|
|
|
|
import java.awt.Dimension; |
|
|
|
|
import java.awt.GradientPaint; |
|
|
|
|
import java.awt.Graphics; |
|
|
|
|
import java.awt.Graphics2D; |
|
|
|
|
import java.awt.RenderingHints; |
|
|
|
|
import java.awt.event.AWTEventListener; |
|
|
|
|
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.awt.event.MouseMotionListener; |
|
|
|
|
import java.awt.geom.GeneralPath; |
|
|
|
|
import java.awt.geom.Line2D; |
|
|
|
|
import java.awt.geom.Path2D; |
|
|
|
|
import java.awt.geom.RoundRectangle2D; |
|
|
|
|
import java.awt.event.MouseMotionAdapter; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.Map; |
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
import static com.fine.theme.utils.FineUIScale.scale; |
|
|
|
|
import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog; |
|
|
|
|
import static javax.swing.JOptionPane.OK_CANCEL_OPTION; |
|
|
|
|
import static javax.swing.JOptionPane.OK_OPTION; |
|
|
|
|
import static javax.swing.JOptionPane.WARNING_MESSAGE; |
|
|
|
|
|
|
|
|
|
// todo: 自己绘制组件
|
|
|
|
|
/** |
|
|
|
|
* 改个名字,一个拼写 n 个错误 |
|
|
|
|
* |
|
|
|
@ -84,28 +61,14 @@ import static javax.swing.JOptionPane.WARNING_MESSAGE;
|
|
|
|
|
* <p> |
|
|
|
|
* created by daisy on 2013/08/05 |
|
|
|
|
**/ |
|
|
|
|
public class MultiTemplateTabPane extends JComponent { |
|
|
|
|
|
|
|
|
|
private static Icon LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list"); |
|
|
|
|
private static Icon MOUSE_OVER_LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list_pressed.svg"); |
|
|
|
|
private static Icon MOUSE_PRESS_LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list_pressed.svg"); |
|
|
|
|
private static Icon CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close"); |
|
|
|
|
private static Icon MOUSE_OVER_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_mouseover.svg"); |
|
|
|
|
private static Icon MOUSE_PRESS_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_press.svg"); |
|
|
|
|
private static final Icon WHITE_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/white_saving_close.gif")); |
|
|
|
|
private static final Icon GREY_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/grey_saving_close.gif")); |
|
|
|
|
private static final String ELLIPSIS = "..."; |
|
|
|
|
private static final int GAP = 5; |
|
|
|
|
private static final int SMALLGAP = 3; |
|
|
|
|
private static final int LIST_BUTTON_WIDTH = 34; |
|
|
|
|
private static final int HEIGHT = 26; |
|
|
|
|
private static final int LIST_DOWN_HEIGHT = 25; |
|
|
|
|
private static final double CORNOR_RADIUS = 0.0; |
|
|
|
|
//选了30度和60度的特殊角度的x,y作为经过的两个点的坐标
|
|
|
|
|
private static final double SPECIAL_LOCATION_1 = 2.5; |
|
|
|
|
private static final double SPECIAL_LOCATION_2 = 4.330127; |
|
|
|
|
private static final int ICON_WIDTH = 22; |
|
|
|
|
public class MultiTemplateTabPane extends JPanel { |
|
|
|
|
|
|
|
|
|
private static final String UI_CLASS_ID = "TemplateTabPaneUI"; |
|
|
|
|
private static final int GAP = 6; |
|
|
|
|
private static final int SMALLGAP = 4; |
|
|
|
|
private static final int TRAILING_WIDTH = 34; |
|
|
|
|
|
|
|
|
|
private static final int LEADING_WIDTH = 38; |
|
|
|
|
|
|
|
|
|
//每个标签页的最大的长度和最小长度。这些长度均为均分
|
|
|
|
|
|
|
|
|
@ -122,8 +85,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
private int mouseOveredIndex = -1; |
|
|
|
|
|
|
|
|
|
//tab栏可以放下的每个tab的实际宽度
|
|
|
|
|
private int realWidth = MAXWIDTH; |
|
|
|
|
|
|
|
|
|
private int tabWidth; |
|
|
|
|
|
|
|
|
|
//当前标签页栏存放的所有标签页的index
|
|
|
|
|
private int minPaintIndex = 0; |
|
|
|
@ -132,13 +94,12 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
//每个关闭图标的起始位置
|
|
|
|
|
private int[] startX; |
|
|
|
|
|
|
|
|
|
private boolean[] isNeedToolTips; |
|
|
|
|
|
|
|
|
|
//记录关闭按钮的状态
|
|
|
|
|
private int closeIconIndex = -1; |
|
|
|
|
private boolean isCloseCurrent = false; |
|
|
|
|
private Icon clodeMode = CLOSE; |
|
|
|
|
private Icon listDownMode = LIST_DOWN; |
|
|
|
|
private boolean hoverMoreAction = false; |
|
|
|
|
private Icon clodeIcon = new LazyIcon("clear"); |
|
|
|
|
private boolean isShowList = false; |
|
|
|
|
|
|
|
|
|
//自动新建的模板B若没有进行任何编辑,切换到其他
|
|
|
|
@ -146,10 +107,14 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
// 模板时,模板B会自动关闭
|
|
|
|
|
private JTemplate<?, ?> temTemplate = null; |
|
|
|
|
|
|
|
|
|
// private final Color selectedColor = UIManager.getColor("TabbedPane.hoverColor");
|
|
|
|
|
// private Color hoverColor = UIManager.getColor("TabbedPane.inactiveUnderlineColor");
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public String getUIClassID() { |
|
|
|
|
return UI_CLASS_ID; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 单例 |
|
|
|
|
*/ |
|
|
|
|
public static MultiTemplateTabPane getInstance() { |
|
|
|
|
if (THIS == null) { |
|
|
|
|
THIS = new MultiTemplateTabPane(); |
|
|
|
@ -162,27 +127,19 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
* 多工作簿面板 |
|
|
|
|
*/ |
|
|
|
|
public MultiTemplateTabPane() { |
|
|
|
|
this.setLayout(new BorderLayout(0, 0)); |
|
|
|
|
this.addMouseListener(new MultiTemplateTabMouseListener()); |
|
|
|
|
this.addMouseMotionListener(new MultiTemplateTabMouseMotionListener()); |
|
|
|
|
this.setBorder(null); |
|
|
|
|
// this.setForeground(new Color(58, 56, 58));
|
|
|
|
|
this.setFont(DesignUtils.getDefaultGUIFont().applySize(12)); |
|
|
|
|
openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList(); |
|
|
|
|
selectedIndex = openedTemplate.size() - 1; |
|
|
|
|
AWTEventListener awt = new AWTEventListener() { |
|
|
|
|
@Override |
|
|
|
|
public void eventDispatched(AWTEvent event) { |
|
|
|
|
if (event instanceof MouseEvent) { |
|
|
|
|
MouseEvent mv = (MouseEvent) event; |
|
|
|
|
if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MultiTemplateTabPane.this)) { |
|
|
|
|
isShowList = false; |
|
|
|
|
} |
|
|
|
|
java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(event -> { |
|
|
|
|
if (event instanceof MouseEvent) { |
|
|
|
|
MouseEvent mv = (MouseEvent) event; |
|
|
|
|
if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MultiTemplateTabPane.this)) { |
|
|
|
|
isShowList = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK); |
|
|
|
|
}, AWTEvent.MOUSE_EVENT_MASK); |
|
|
|
|
addMouseListener(new MouseAdapter() { |
|
|
|
|
@Override |
|
|
|
|
public void mousePressed(MouseEvent e) { |
|
|
|
@ -229,6 +186,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 判断模板是否可以关闭,两个条件:1、是否满足CloseOption里面的条件(在左侧、在右侧等)2、是否和当前正在编辑模板属于同一种模板tab操作类型 |
|
|
|
|
* |
|
|
|
|
* @param closeJTemplate |
|
|
|
|
* @param tplIndex |
|
|
|
|
* @param i |
|
|
|
@ -369,7 +327,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
if (openedTemplate.size() == 0) { |
|
|
|
|
DesignerContext.getDesignerFrame().addAndActivateJTemplate(); |
|
|
|
|
} else if (option == CloseOption.All){ |
|
|
|
|
} else if (option == CloseOption.All) { |
|
|
|
|
//openedTemplate(0)是JVirtualTemplate时需重新打开
|
|
|
|
|
openedTemplate.get(0).activeOldJTemplate(); |
|
|
|
|
} else { |
|
|
|
@ -417,9 +375,10 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 关闭所有指定模板tab操作类型的模板 |
|
|
|
|
* |
|
|
|
|
* @param operatorType |
|
|
|
|
*/ |
|
|
|
|
public void closeOtherByOperatorType(String operatorType){ |
|
|
|
|
public void closeOtherByOperatorType(String operatorType) { |
|
|
|
|
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); |
|
|
|
|
if (saveSomeTempaltePane.showSavePane(null, false, true)) { |
|
|
|
@ -438,6 +397,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 关闭指定的非当前编辑模板 |
|
|
|
|
* |
|
|
|
|
* @param templates |
|
|
|
|
* @param operatorType |
|
|
|
|
*/ |
|
|
|
@ -471,91 +431,19 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Dimension getPreferredSize() { |
|
|
|
|
Dimension dimension = super.getPreferredSize(); |
|
|
|
|
dimension.height = HEIGHT; |
|
|
|
|
return dimension; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private UIMenuItem initCloseOther() { |
|
|
|
|
UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_FS_Close_Other_Templates")); |
|
|
|
|
// Yvan: 英文下文本显示不全,后续发现如果将模板名设置的比较短,其它语言也会出现显示不全的问题,所以设置一下文本水平居中
|
|
|
|
|
closeOther.setHorizontalAlignment(SwingConstants.CENTER); |
|
|
|
|
setListDownItemPreferredSize(closeOther); |
|
|
|
|
closeOther.addActionListener(new ActionListener() { |
|
|
|
|
@Override |
|
|
|
|
public void actionPerformed(ActionEvent e) { |
|
|
|
|
if (openedTemplate.size() == 1) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (!TemplateSavingChecker.check()) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); |
|
|
|
|
//点击关闭其他模板,并且点击确定保存
|
|
|
|
|
if (saveSomeTempaltePane.showSavePane()) { |
|
|
|
|
JTemplate<?, ?>[] panes = new JTemplate<?, ?>[openedTemplate.size()]; |
|
|
|
|
for (int i = 0; i < openedTemplate.size(); i++) { |
|
|
|
|
panes[i] = openedTemplate.get(i); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < panes.length; i++) { |
|
|
|
|
if (i != selectedIndex) { |
|
|
|
|
JTemplate<?, ?> jTemplate = panes[i]; |
|
|
|
|
//判断关闭的模板是不是格式刷的被参照的模板
|
|
|
|
|
openedTemplate.remove(jTemplate); |
|
|
|
|
closeFormat(jTemplate); |
|
|
|
|
HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); |
|
|
|
|
closeAndFreeLock(jTemplate); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
HistoryTemplateListCache.getInstance().removeAllHistory(); |
|
|
|
|
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); |
|
|
|
|
THIS.repaint(); |
|
|
|
|
} |
|
|
|
|
//如果取消保存了,则不关闭其他模板
|
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
if (openedTemplate.size() == 1) { |
|
|
|
|
closeOther.setEnabled(false); |
|
|
|
|
} |
|
|
|
|
return closeOther; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private UIMenuItem[] createListDownTemplate() { |
|
|
|
|
UIMenuItem[] templates = new UIMenuItem[openedTemplate.size()]; |
|
|
|
|
for (int i = 0; i < openedTemplate.size(); i++) { |
|
|
|
|
final int index = i; |
|
|
|
|
final JTemplate tem = openedTemplate.get(i); |
|
|
|
|
templates[i] = new UIMenuItem(tempalteShowName(tem), tem.getIcon()); |
|
|
|
|
// templates[i].setUI(new UIListDownItemUI());
|
|
|
|
|
setListDownItemPreferredSize(templates[i]); |
|
|
|
|
if (i == selectedIndex) { |
|
|
|
|
//画选中的高亮
|
|
|
|
|
// templates[i].setBackground(UIConstants.SHADOW_CENTER);
|
|
|
|
|
} |
|
|
|
|
templates[i].addActionListener(new ActionListener() { |
|
|
|
|
@Override |
|
|
|
|
public void actionPerformed(ActionEvent e) { |
|
|
|
|
selectedIndex = index; |
|
|
|
|
tem.activeNewJTemplate(); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
return templates; |
|
|
|
|
private String tempalteShowName(JTemplate<?, ?> template) { |
|
|
|
|
return template.getTabShowName(template); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void setListDownItemPreferredSize(UIMenuItem item) { |
|
|
|
|
Dimension dimension = item.getPreferredSize(); |
|
|
|
|
dimension.height = LIST_DOWN_HEIGHT; |
|
|
|
|
item.setPreferredSize(dimension); |
|
|
|
|
public String getTemplateShowNameByIndex(int index) { |
|
|
|
|
JTemplate template = openedTemplate.get(index); |
|
|
|
|
return template.getTabShowName(template); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String tempalteShowName(JTemplate<?, ?> template) { |
|
|
|
|
return template.getTabShowName(template); |
|
|
|
|
public Icon getTemplateIconByIndex(int index) { |
|
|
|
|
JTemplate template = openedTemplate.get(index); |
|
|
|
|
return template.getIcon(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -585,145 +473,23 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void paintComponent(Graphics g) { |
|
|
|
|
super.paintComponent(g); |
|
|
|
|
double maxWidth = getWidth() - LIST_BUTTON_WIDTH * 1.0D; //最大宽度
|
|
|
|
|
Graphics2D g2d = (Graphics2D) g; |
|
|
|
|
paintBackgroundAndLine(g2d, maxWidth); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void paint(Graphics g) { |
|
|
|
|
//不可见时,按钮.4f透明
|
|
|
|
|
AlphaComposite composite = DesignerMode.isVcsMode() |
|
|
|
|
? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f) |
|
|
|
|
: (AlphaComposite) ((Graphics2D) g).getComposite(); |
|
|
|
|
((Graphics2D) g).setComposite(composite); |
|
|
|
|
super.paint(g); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void paintBackgroundAndLine(Graphics2D g2d, double maxWidth) { |
|
|
|
|
paintDefaultBackground(g2d); |
|
|
|
|
//最多能画的个数
|
|
|
|
|
int maxTemplateNum = (int) (maxWidth) / MINWIDTH; |
|
|
|
|
//计算开始画的最小模板index和最大模板index
|
|
|
|
|
double maxWidth = getWidth() - scale(TRAILING_WIDTH) - scale(LEADING_WIDTH); //最大宽度
|
|
|
|
|
int maxTemplateNum = (int) (maxWidth) / scale(MINWIDTH); |
|
|
|
|
calMinAndMaxIndex(maxTemplateNum); |
|
|
|
|
calculateRealAverageWidth(maxWidth, maxTemplateNum); |
|
|
|
|
int maxStringlength = calculateStringMaxLength(); |
|
|
|
|
if (selectedIndex >= openedTemplate.size()) { |
|
|
|
|
selectedIndex = openedTemplate.size() - 1; |
|
|
|
|
} |
|
|
|
|
if (selectedIndex < 0) { |
|
|
|
|
selectedIndex = 0; |
|
|
|
|
} |
|
|
|
|
double templateStartX = 0; |
|
|
|
|
startX = new int[maxPaintIndex - minPaintIndex + 1]; |
|
|
|
|
isNeedToolTips = new boolean[maxPaintIndex - minPaintIndex + 1]; |
|
|
|
|
|
|
|
|
|
//从可以开始展示在tab面板上的tab开始画
|
|
|
|
|
for (int i = minPaintIndex; i <= maxPaintIndex; i++) { |
|
|
|
|
JTemplate template = openedTemplate.get(i); |
|
|
|
|
if (!showJTemplateTab(template)){ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
Icon icon = template.getIcon(); |
|
|
|
|
String name = tempalteShowName(template); |
|
|
|
|
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
|
|
|
|
|
if (getStringWidth(name) > maxStringlength) { |
|
|
|
|
name = getEllipsisName(name, maxStringlength); |
|
|
|
|
isNeedToolTips[i - minPaintIndex] = true; |
|
|
|
|
} else { |
|
|
|
|
isNeedToolTips[i - minPaintIndex] = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Icon selectedIcon; |
|
|
|
|
if (i == closeIconIndex) { |
|
|
|
|
selectedIcon = clodeMode; |
|
|
|
|
} else { |
|
|
|
|
selectedIcon = CLOSE; |
|
|
|
|
} |
|
|
|
|
if (i == selectedIndex) { |
|
|
|
|
if (template.isSaving()) { |
|
|
|
|
selectedIcon = WHITE_SAVING_CLOSE_ICON; |
|
|
|
|
} |
|
|
|
|
startX[i - minPaintIndex] = paintSelectedTab(g2d, icon, templateStartX, name, selectedIcon); |
|
|
|
|
} else { |
|
|
|
|
if (template.isSaving()) { |
|
|
|
|
selectedIcon = GREY_SAVING_CLOSE_ICON; |
|
|
|
|
} |
|
|
|
|
boolean isLeft = i < selectedIndex; |
|
|
|
|
startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i); |
|
|
|
|
} |
|
|
|
|
templateStartX += realWidth; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!DesignerMode.isVcsMode()) { |
|
|
|
|
paintListDown(g2d, maxWidth); |
|
|
|
|
} |
|
|
|
|
paintUnderLine(templateStartX, maxWidth, g2d); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void paintUnderLine(double templateStartX, double maxWidth, Graphics2D g2d) { |
|
|
|
|
//画下面的那条线
|
|
|
|
|
if (templateStartX < maxWidth) { |
|
|
|
|
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, 2); |
|
|
|
|
generalPath.moveTo((float) templateStartX, (float) (getHeight() - 1.0D)); |
|
|
|
|
generalPath.lineTo((float) maxWidth, (float) (getHeight() - 1.0D)); |
|
|
|
|
g2d.fill(generalPath); |
|
|
|
|
//TODO hzzz delete
|
|
|
|
|
// g2d.setPaint(UIConstants.LINE_COLOR);
|
|
|
|
|
// g2d.draw(new Line2D.Double((float) templateStartX, getHeight() - 1, (float) maxWidth + LIST_BUTTON_WIDTH, getHeight() - 1));
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void paintDefaultBackground(Graphics2D g2d) { |
|
|
|
|
//画默认背景
|
|
|
|
|
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground())); |
|
|
|
|
g2d.fillRect(0, 0, getWidth(), getHeight()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void paintListDown(Graphics2D g2d, double maxWidth) { |
|
|
|
|
int x = (int) maxWidth + (LIST_BUTTON_WIDTH - listDownMode.getIconWidth()) / 2; |
|
|
|
|
int y = (getHeight() - listDownMode.getIconHeight()) / 2; |
|
|
|
|
listDownMode.paintIcon(this, g2d, x, y); |
|
|
|
|
calculateClosePosition(); |
|
|
|
|
super.paintComponent(g); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 判断tab文字的长度大于能装下的最大文字长度,要用省略号 |
|
|
|
|
* |
|
|
|
|
* @param name |
|
|
|
|
* @param maxStringlength |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private String getEllipsisName(String name, int maxStringlength) { |
|
|
|
|
|
|
|
|
|
//若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度
|
|
|
|
|
// int maxellipsislength = maxStringlength - ELLIPSIS.length();
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
private void calculateClosePosition() { |
|
|
|
|
startX = new int[maxPaintIndex - minPaintIndex + 1]; |
|
|
|
|
double templateStartX = scale(LEADING_WIDTH); |
|
|
|
|
for (int i = getViewRange().getFirst(); i <= getViewRange().getSecond(); i++) { |
|
|
|
|
int closePosition = (int) templateStartX + getTabWidth() - clodeIcon.getIconWidth() - GAP; |
|
|
|
|
startX[i - minPaintIndex] = closePosition; |
|
|
|
|
templateStartX += getTabWidth(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void calMinAndMaxIndex(int maxTemplateNum) { |
|
|
|
@ -766,9 +532,10 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 先计算出需要补充的tab个数 |
|
|
|
|
* |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private int calTabCountComplemented(){ |
|
|
|
|
private int calTabCountComplemented() { |
|
|
|
|
int a = 0; |
|
|
|
|
for (int i = minPaintIndex; i <= maxPaintIndex; i++) { |
|
|
|
|
JTemplate template = openedTemplate.get(i); |
|
|
|
@ -783,9 +550,9 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
/** |
|
|
|
|
* 由于可能存在宽度为0的tab,所以这边需要重新check下,先往后补,再往前补 |
|
|
|
|
*/ |
|
|
|
|
private void checkActualPaintIndex(){ |
|
|
|
|
private void checkActualPaintIndex() { |
|
|
|
|
int tabCount = calTabCountComplemented(); |
|
|
|
|
if (tabCount == 0){ |
|
|
|
|
if (tabCount == 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (maxPaintIndex < openedTemplate.size() - 1) { |
|
|
|
@ -795,19 +562,19 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
tabCount--; |
|
|
|
|
} |
|
|
|
|
maxPaintIndex++; |
|
|
|
|
if (tabCount == 0){ |
|
|
|
|
if (tabCount == 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (minPaintIndex > 0){ |
|
|
|
|
if (minPaintIndex > 0) { |
|
|
|
|
for (int i = minPaintIndex - 1; i >= 0; i--) { |
|
|
|
|
JTemplate template = openedTemplate.get(i); |
|
|
|
|
if (showJTemplateTab(template)) { |
|
|
|
|
tabCount--; |
|
|
|
|
} |
|
|
|
|
minPaintIndex--; |
|
|
|
|
if (tabCount == 0){ |
|
|
|
|
if (tabCount == 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -821,170 +588,15 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
List<JTemplate<?, ?>> showTemplates = getOpenedJTemplatesByOperator(jTemplate.getTemplateTabOperatorType()); |
|
|
|
|
|
|
|
|
|
int num = Math.min(showTemplates.size(), templateNum); |
|
|
|
|
realWidth = (int) (maxwidth / (num)); |
|
|
|
|
if (realWidth > MAXWIDTH) { |
|
|
|
|
realWidth = MAXWIDTH; |
|
|
|
|
} else if (realWidth < MINWIDTH) { |
|
|
|
|
tabWidth = (int) (maxwidth / (num)); |
|
|
|
|
if (tabWidth > scale(MAXWIDTH)) { |
|
|
|
|
tabWidth = scale(MAXWIDTH); |
|
|
|
|
} else if (tabWidth < scale(MINWIDTH)) { |
|
|
|
|
//平均下来每个的宽度小于最小宽度
|
|
|
|
|
realWidth = MINWIDTH; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 计算过长度之后的每个tab的能接受的文字的英文字符数 |
|
|
|
|
* |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private int calculateStringMaxLength() { |
|
|
|
|
return realWidth - 3 * GAP - ICON_WIDTH - SMALLGAP - CLOSE.getIconWidth(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private int getStringWidth(String str) { |
|
|
|
|
return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 画选中的tab |
|
|
|
|
* |
|
|
|
|
* @param g2d |
|
|
|
|
* @param sheeticon |
|
|
|
|
* @param templateStartX |
|
|
|
|
* @param sheetName |
|
|
|
|
* @param closeIcon |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private int paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) { |
|
|
|
|
double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; |
|
|
|
|
double[] y = {1, getHeight() + 1, getHeight() + 1, 1, 1}; |
|
|
|
|
RoundRectangle2D.Double rect1 = new RoundRectangle2D.Double(templateStartX, 1, this.getWidth(), this.getHeight(), 7, 7); |
|
|
|
|
g2d.setPaint(new GradientPaint(1, 1, getBackground(), (float) (getWidth() -1.0d), 1, getBackground())); |
|
|
|
|
//选了30度和60度的特殊角度的x,y作为经过的两个点的坐标
|
|
|
|
|
double specialLocation1 = 2.5; |
|
|
|
|
double specialLocation2 = 4.330127; |
|
|
|
|
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); |
|
|
|
|
generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - specialLocation1), (y[0] + CORNOR_RADIUS - specialLocation2), ((float) x[0] + CORNOR_RADIUS - specialLocation2), (y[0] + CORNOR_RADIUS - specialLocation1), x[0], y[0] + CORNOR_RADIUS); |
|
|
|
|
|
|
|
|
|
for (int index = 1; index <= 2; index++) { |
|
|
|
|
generalPath.lineTo((float) x[index], (float) y[index]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); |
|
|
|
|
generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + specialLocation1), ((float) y[3] + CORNOR_RADIUS - specialLocation2), ((float) x[3] - CORNOR_RADIUS + specialLocation2), ((float) y[3] + CORNOR_RADIUS - specialLocation1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); |
|
|
|
|
generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
|
|
|
|
|
generalPath.closePath(); |
|
|
|
|
g2d.fill(generalPath); |
|
|
|
|
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
|
// g2d.setPaint(Color.red);
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
|
|
|
|
|
// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1]));
|
|
|
|
|
// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2]));
|
|
|
|
|
// g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS));
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
|
|
|
|
|
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
|
|
|
|
int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; |
|
|
|
|
sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); |
|
|
|
|
// 画字符
|
|
|
|
|
g2d.setPaint(getForeground()); |
|
|
|
|
g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); |
|
|
|
|
int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; |
|
|
|
|
int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; |
|
|
|
|
if (!DesignerMode.isVcsMode()) { |
|
|
|
|
closeIcon.paintIcon(this, g2d, closePosition, closeY); |
|
|
|
|
tabWidth = scale(MINWIDTH); |
|
|
|
|
} |
|
|
|
|
return closePosition; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 画没有选中的tab |
|
|
|
|
* |
|
|
|
|
* @param g2d |
|
|
|
|
* @param sheeticon |
|
|
|
|
* @param templateStartX |
|
|
|
|
* @param sheetName |
|
|
|
|
* @param closeIcon |
|
|
|
|
* @param isLeft |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private int paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, boolean isLeft, int mouseOveredIndex, int selfIndex) { |
|
|
|
|
double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; |
|
|
|
|
double[] y = {-1, getHeight() - 1, getHeight() - 1, -1, -1}; |
|
|
|
|
if (selfIndex == mouseOveredIndex) { |
|
|
|
|
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground())); |
|
|
|
|
} else { |
|
|
|
|
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); |
|
|
|
|
|
|
|
|
|
unSelectedClosedPath(generalPath, isLeft, x, y); |
|
|
|
|
g2d.fill(generalPath); |
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
|
|
|
g2d.setPaint(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND); |
|
|
|
|
//TODO hzzz delete
|
|
|
|
|
// if (isLeft) {
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
|
|
|
|
|
// } else {
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[0] - CORNOR_RADIUS * 2, y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1] + 1));
|
|
|
|
|
// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2]));
|
|
|
|
|
g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS)); |
|
|
|
|
// if (isLeft) {
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[3], y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
|
|
|
|
|
// } else {
|
|
|
|
|
// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
|
|
|
|
int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; |
|
|
|
|
sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); |
|
|
|
|
// 画字符
|
|
|
|
|
g2d.setPaint(getForeground()); |
|
|
|
|
g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); |
|
|
|
|
int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; |
|
|
|
|
int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; |
|
|
|
|
if (!DesignerMode.isVcsMode()) { |
|
|
|
|
closeIcon.paintIcon(this, g2d, closePosition, closeY); |
|
|
|
|
} |
|
|
|
|
return closePosition; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void unSelectedClosedPath(GeneralPath generalPath, boolean isLeft, double[] x, double[] y) { |
|
|
|
|
|
|
|
|
|
if (isLeft) { |
|
|
|
|
generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); |
|
|
|
|
} else { |
|
|
|
|
generalPath.moveTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
generalPath.curveTo(((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int index = 1; index <= 2; index++) { |
|
|
|
|
generalPath.lineTo((float) x[index], (float) y[index]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); |
|
|
|
|
|
|
|
|
|
if (isLeft) { |
|
|
|
|
generalPath.curveTo(((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) y[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (float) x[3] + CORNOR_RADIUS, (float) y[3]); |
|
|
|
|
generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
} else { |
|
|
|
|
generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_2), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); |
|
|
|
|
generalPath.lineTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
generalPath.closePath(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setIsCloseCurrent(boolean isCloseCurrent) { |
|
|
|
|
this.isCloseCurrent = isCloseCurrent; |
|
|
|
|
|
|
|
|
@ -1107,19 +719,21 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 计算下一个可以展示的模板index |
|
|
|
|
* |
|
|
|
|
* @param currentIndex |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public int calNextShowJTemplateIndex(int currentIndex) { |
|
|
|
|
JTemplate jTemplate= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
return MultiTemplateTabUtils.calShowTemplateIndex(currentIndex, openedTemplate, jTemplate.getTemplateTabOperatorType()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isOverCloseIcon(int evtX) { |
|
|
|
|
boolean isOverCloseIcon = false; |
|
|
|
|
// todo
|
|
|
|
|
for (int i = 0; i < startX.length; i++) { |
|
|
|
|
if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) { |
|
|
|
|
if (evtX >= startX[i] && evtX <= startX[i] + clodeIcon.getIconWidth()) { |
|
|
|
|
isOverCloseIcon = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -1129,15 +743,15 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isOverListDown(int evtX) { |
|
|
|
|
int maxWidth = getWidth() - LIST_BUTTON_WIDTH; |
|
|
|
|
int maxWidth = getWidth() - scale(TRAILING_WIDTH) - scale(LEADING_WIDTH); |
|
|
|
|
return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int getTemplateIndex(int evtX) { |
|
|
|
|
int textX = 0; |
|
|
|
|
int textX = scale(LEADING_WIDTH); |
|
|
|
|
for (int i = minPaintIndex; i <= maxPaintIndex; i++) { |
|
|
|
|
int textWidth = showJTemplateTab(openedTemplate.get(i)) ? realWidth : 0; |
|
|
|
|
int textWidth = showJTemplateTab(openedTemplate.get(i)) ? tabWidth : 0; |
|
|
|
|
if (evtX >= textX && evtX < textX + textWidth) { |
|
|
|
|
return i; |
|
|
|
|
} |
|
|
|
@ -1169,35 +783,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class UIListDownItemUI extends BasicMenuItemUI { |
|
|
|
|
@Override |
|
|
|
|
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { |
|
|
|
|
if (menuItem.getIcon() == null) { |
|
|
|
|
super.paintBackground(g, menuItem, bgColor); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ButtonModel model = menuItem.getModel(); |
|
|
|
|
Color oldColor = g.getColor(); |
|
|
|
|
int menuWidth = menuItem.getWidth(); |
|
|
|
|
int menuHeight = menuItem.getHeight(); |
|
|
|
|
g.setColor(getBackground()); |
|
|
|
|
g.fillRect(0, 0, menuWidth, menuHeight); |
|
|
|
|
boolean itemIsSelected = menuItem instanceof JMenu && model.isSelected(); |
|
|
|
|
if (menuItem.isOpaque()) { |
|
|
|
|
if (model.isArmed() || itemIsSelected) { |
|
|
|
|
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); |
|
|
|
|
} else { |
|
|
|
|
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, menuItem.getBackground(), UIConstants.ARC); |
|
|
|
|
} |
|
|
|
|
g.setColor(oldColor); |
|
|
|
|
} else if (model.isArmed() || itemIsSelected) { |
|
|
|
|
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); |
|
|
|
|
g.setColor(oldColor); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class MultiTemplateTabMouseListener implements MouseListener { |
|
|
|
|
private class MultiTemplateTabMouseListener extends MouseAdapter { |
|
|
|
|
|
|
|
|
|
private boolean oldLightWeightPopupEnabled; |
|
|
|
|
|
|
|
|
@ -1222,32 +808,12 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
ToolTipManager.sharedInstance().setEnabled(false); |
|
|
|
|
ToolTipManager.sharedInstance().setEnabled(true); |
|
|
|
|
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(this.oldLightWeightPopupEnabled); |
|
|
|
|
listDownMode = LIST_DOWN; |
|
|
|
|
closeIconIndex = -1; |
|
|
|
|
mouseOveredIndex = -1; |
|
|
|
|
hoverMoreAction = false; |
|
|
|
|
MultiTemplateTabPane.this.repaint(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 鼠标释放 |
|
|
|
|
* |
|
|
|
|
* @param e 鼠标事件 |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void mouseReleased(MouseEvent e) { |
|
|
|
|
// do nothing
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 点击 |
|
|
|
|
* |
|
|
|
|
* @param e 鼠标事件 |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void mouseClicked(MouseEvent e) { |
|
|
|
|
// do nothing
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 按下 |
|
|
|
|
* |
|
|
|
@ -1264,8 +830,9 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
//是否点击关闭按钮 如果点击了关闭按钮,则将点击的模板关闭,不需要切换,如果没有点击关闭按钮,则切换到点击的模板处
|
|
|
|
|
boolean isOverCloseIcon = isOverCloseIcon(evtX); |
|
|
|
|
if (isOverListDown(evtX)) { |
|
|
|
|
listDownMode = isOverListDown(evtX) ? MOUSE_PRESS_LIST_DOWN : LIST_DOWN; |
|
|
|
|
hoverMoreAction = isOverListDown(evtX); |
|
|
|
|
if (hoverMoreAction) { |
|
|
|
|
|
|
|
|
|
if (!isShowList) { |
|
|
|
|
showListDown(); |
|
|
|
|
} |
|
|
|
@ -1274,7 +841,6 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
} else if (isOverCloseIcon) { |
|
|
|
|
//关闭按钮的图标变化
|
|
|
|
|
closeIconIndex = getTemplateIndex(evtX); |
|
|
|
|
clodeMode = MOUSE_PRESS_CLOSE; |
|
|
|
|
//关闭close图标所在的模板{
|
|
|
|
|
JTemplate<?, ?> template = openedTemplate.get(closeIconIndex); |
|
|
|
|
if (template.isOpening()) { |
|
|
|
@ -1298,7 +864,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
} else { |
|
|
|
|
//没有点击关闭和ListDown按钮,则切换到点击的模板处
|
|
|
|
|
closeIconIndex = -1; |
|
|
|
|
clodeMode = CLOSE; |
|
|
|
|
clodeIcon = new LazyIcon("clear"); |
|
|
|
|
switchJTemplate(getTemplateIndex(evtX)); |
|
|
|
|
isShowList = false; |
|
|
|
|
} |
|
|
|
@ -1308,6 +874,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 切换到指定模板 |
|
|
|
|
* |
|
|
|
|
* @param jTemplate |
|
|
|
|
*/ |
|
|
|
|
public void switchJTemplate(JTemplate jTemplate) { |
|
|
|
@ -1319,9 +886,10 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 切换到指定index |
|
|
|
|
* |
|
|
|
|
* @param switchIndex |
|
|
|
|
*/ |
|
|
|
|
private void switchJTemplate(int switchIndex){ |
|
|
|
|
private void switchJTemplate(int switchIndex) { |
|
|
|
|
int tempSelectedIndex = selectedIndex; |
|
|
|
|
if (selectedIndex != switchIndex && switchIndex != -1) { |
|
|
|
|
openedTemplate.get(selectedIndex).stopEditing(); |
|
|
|
@ -1344,17 +912,7 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
return JTemplate.isValid(currentTemplate) && ComparatorUtils.equals(template.getPath(), currentTemplate.getPath()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class MultiTemplateTabMouseMotionListener implements MouseMotionListener { |
|
|
|
|
/** |
|
|
|
|
* 鼠标拖拽 |
|
|
|
|
* |
|
|
|
|
* @param e 鼠标事件 |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void mouseDragged(MouseEvent e) { |
|
|
|
|
// do nothing
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class MultiTemplateTabMouseMotionListener extends MouseMotionAdapter { |
|
|
|
|
/** |
|
|
|
|
* 鼠标移动 |
|
|
|
|
* |
|
|
|
@ -1364,51 +922,106 @@ public class MultiTemplateTabPane extends JComponent {
|
|
|
|
|
public void mouseMoved(MouseEvent e) { |
|
|
|
|
int evtX = e.getX(); |
|
|
|
|
mouseOveredIndex = getTemplateIndex(evtX); |
|
|
|
|
|
|
|
|
|
//看是否需要显示toolTip
|
|
|
|
|
if (mouseOveredIndex != -1 && isNeedToolTips[mouseOveredIndex - minPaintIndex]) { |
|
|
|
|
setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName()); |
|
|
|
|
} else { |
|
|
|
|
setToolTipText(null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
listDownMode = isOverListDown(evtX) ? MOUSE_OVER_LIST_DOWN : LIST_DOWN; |
|
|
|
|
|
|
|
|
|
boolean isOverCloseIcon = isOverCloseIcon(evtX); |
|
|
|
|
clodeMode = isOverCloseIcon ? MOUSE_OVER_CLOSE : CLOSE; |
|
|
|
|
closeIconIndex = isOverCloseIcon ? mouseOveredIndex : -1; |
|
|
|
|
setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName()); |
|
|
|
|
hoverMoreAction = isOverListDown(evtX); |
|
|
|
|
closeIconIndex = isOverCloseIcon(evtX) ? mouseOveredIndex : -1; |
|
|
|
|
MultiTemplateTabPane.this.repaint(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 判断是否显示在tab栏上 |
|
|
|
|
* |
|
|
|
|
* @param jTemplate |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private boolean showJTemplateTab(JTemplate jTemplate){ |
|
|
|
|
private boolean showJTemplateTab(JTemplate jTemplate) { |
|
|
|
|
JTemplate current = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
return ComparatorUtils.equals(current.getTemplateTabOperatorType(), jTemplate.getTemplateTabOperatorType()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取tab操作类型的模板 |
|
|
|
|
* |
|
|
|
|
* @param operator |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public List<JTemplate<?, ?>> getOpenedJTemplatesByOperator(String operator) { |
|
|
|
|
public List<JTemplate<?, ?>> getOpenedJTemplatesByOperator(String operator) { |
|
|
|
|
return openedTemplate.stream().filter((jTemplate) -> ComparatorUtils.equals(jTemplate.getTemplateTabOperatorType(), operator)) |
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 根据tab操作类型进行分类 |
|
|
|
|
* |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Map<String, List<JTemplate<?, ?>>> getOpenedJTemplatesByCategory() { |
|
|
|
|
return openedTemplate.stream() |
|
|
|
|
.collect(Collectors.groupingBy(JTemplate::getTemplateTabOperatorType)); |
|
|
|
|
return openedTemplate.stream() |
|
|
|
|
.collect(Collectors.groupingBy(JTemplate::getTemplateTabOperatorType)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 返回当前tab数量 |
|
|
|
|
* |
|
|
|
|
* @return tab数量 |
|
|
|
|
*/ |
|
|
|
|
public int getTabCount() { |
|
|
|
|
return openedTemplate.size(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取选中的tab索引 |
|
|
|
|
* |
|
|
|
|
* @return tab索引 |
|
|
|
|
*/ |
|
|
|
|
public int getSelectedIndex() { |
|
|
|
|
return selectedIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取每个tab宽度 |
|
|
|
|
* |
|
|
|
|
* @return tab宽度 |
|
|
|
|
*/ |
|
|
|
|
public int getTabWidth() { |
|
|
|
|
return tabWidth; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 是否悬浮在更多按钮上 |
|
|
|
|
* |
|
|
|
|
* @return 是否悬浮 |
|
|
|
|
*/ |
|
|
|
|
public boolean isHoverMoreAction() { |
|
|
|
|
return hoverMoreAction; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 是否悬浮在关闭按钮上0 |
|
|
|
|
* |
|
|
|
|
* @param i 索引 |
|
|
|
|
* @return 是否悬浮在关闭按钮上 |
|
|
|
|
*/ |
|
|
|
|
public boolean isCloseCurrent(int i) { |
|
|
|
|
return i == closeIconIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取悬浮索引 |
|
|
|
|
* |
|
|
|
|
* @return 悬浮在第几个tab |
|
|
|
|
*/ |
|
|
|
|
public int getHoverIndex() { |
|
|
|
|
return mouseOveredIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取可视范围内的标签范围 |
|
|
|
|
* |
|
|
|
|
* @return 标签范围 |
|
|
|
|
*/ |
|
|
|
|
public Pair<Integer, Integer> getViewRange() { |
|
|
|
|
return new Pair<>(minPaintIndex, maxPaintIndex); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|