|
|
|
package com.fr.startup.ui;
|
|
|
|
|
|
|
|
import com.fr.base.svg.IconUtils;
|
|
|
|
import com.fr.design.DesignerEnvManager;
|
|
|
|
import com.fr.design.components.loading.LoadingPane;
|
|
|
|
import com.fr.design.dialog.UIExpandDialog;
|
|
|
|
import com.fr.design.gui.icontainer.UIScrollPane;
|
|
|
|
import com.fr.design.gui.ilable.UILabel;
|
|
|
|
import com.fr.design.i18n.Toolkit;
|
|
|
|
import com.fr.design.layout.FRGUIPaneFactory;
|
|
|
|
import com.fr.design.layout.VerticalFlowLayout;
|
|
|
|
import com.fr.design.ui.util.UIUtil;
|
|
|
|
import com.fr.design.utils.ColorUtils;
|
|
|
|
import com.fr.design.utils.gui.GUICoreUtils;
|
|
|
|
import com.fr.exit.DesignerExiter;
|
|
|
|
import com.fr.general.GeneralUtils;
|
|
|
|
import com.fr.log.FineLoggerFactory;
|
|
|
|
import com.fr.stable.ProductConstants;
|
|
|
|
import com.fr.stable.collections.CollectionUtils;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
import javax.swing.JComponent;
|
|
|
|
import javax.swing.JFrame;
|
|
|
|
import javax.swing.JLayeredPane;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import javax.swing.JSeparator;
|
|
|
|
import javax.swing.ScrollPaneConstants;
|
|
|
|
import javax.swing.SwingConstants;
|
|
|
|
import javax.swing.SwingWorker;
|
|
|
|
import javax.swing.border.EmptyBorder;
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
import java.awt.Color;
|
|
|
|
import java.awt.Component;
|
|
|
|
import java.awt.Dimension;
|
|
|
|
import java.awt.FlowLayout;
|
|
|
|
import java.awt.Font;
|
|
|
|
import java.awt.Graphics;
|
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.GridLayout;
|
|
|
|
import java.awt.LayoutManager;
|
|
|
|
import java.awt.RenderingHints;
|
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
import java.awt.event.MouseEvent;
|
|
|
|
import java.awt.event.WindowAdapter;
|
|
|
|
import java.awt.event.WindowEvent;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 启动页
|
|
|
|
* 见<a href="https://kms.fineres.com/pages/viewpage.action?pageId=416850313">设计文档</a>
|
|
|
|
* <p>
|
|
|
|
* created by Harrison on 2022/07/06
|
|
|
|
**/
|
|
|
|
public class StartupPageWindow extends JFrame {
|
|
|
|
|
|
|
|
private static final int CONTENT_LAYER = 0;
|
|
|
|
private static final int TRANSPARENT_LAYER = 1;
|
|
|
|
|
|
|
|
private static final Color HOVER_COLOR = new Color(65, 155, 249);
|
|
|
|
private static final Color SEP_COLOR = new Color(224, 224, 225);
|
|
|
|
|
|
|
|
private static final int GROUP_WIDTH = 600;
|
|
|
|
private static final int RECENT_FILE_LIMIT = 6;
|
|
|
|
private static final int RECENT_FILE_SCROLL = RECENT_FILE_LIMIT + 1;
|
|
|
|
private static final int WORKSPACE_PANEL_WIDTH = 180;
|
|
|
|
private static final int TITLE_FONT_SIZE = 24;
|
|
|
|
private static final int ITEM_VERTICAL_GAP = 5;
|
|
|
|
|
|
|
|
private static final Dimension SCREEN_SIZE = new Dimension(1600, 820);
|
|
|
|
|
|
|
|
private StartupPageWorkspacePanel workspacePanel;
|
|
|
|
|
|
|
|
private JPanel recentOpenPanel;
|
|
|
|
|
|
|
|
private JPanel contentPane;
|
|
|
|
|
|
|
|
private JPanel body;
|
|
|
|
|
|
|
|
private LoadingPane loadingPane = new LoadingPane();
|
|
|
|
|
|
|
|
private JLayeredPane layeredPane = new JLayeredPane() {
|
|
|
|
@Override
|
|
|
|
public void doLayout() {
|
|
|
|
for (Component comp : getComponents()) {
|
|
|
|
comp.setBounds(0, 0, getWidth(), getHeight());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
public StartupPageWindow(StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
patchUIAction(pageModel);
|
|
|
|
|
|
|
|
setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
this.body = FRGUIPaneFactory.createBorderLayout_S_Pane();
|
|
|
|
// Header
|
|
|
|
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Select_Workspace"));
|
|
|
|
Font font = label.getFont();
|
|
|
|
Font titleFont = font.deriveFont(font.getStyle(), TITLE_FONT_SIZE);
|
|
|
|
label.setFont(titleFont);
|
|
|
|
JPanel headerPanel = new JPanel();
|
|
|
|
LayoutManager centerFlowLayout = FRGUIPaneFactory.createCenterFlowLayout();
|
|
|
|
headerPanel.setLayout(centerFlowLayout);
|
|
|
|
headerPanel.add(label);
|
|
|
|
this.body.add(headerPanel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
// Workspace-description
|
|
|
|
this.workspacePanel = generateWorkspacePanel(pageModel);
|
|
|
|
this.body.add(workspacePanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
workspacePanel.setSelectWorkspaceRunnable(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
JPanel newPanel = generateRecentOpenPanel(pageModel);
|
|
|
|
|
|
|
|
body.remove(recentOpenPanel);
|
|
|
|
recentOpenPanel = newPanel;
|
|
|
|
body.add(recentOpenPanel, BorderLayout.SOUTH);
|
|
|
|
validate();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.recentOpenPanel = generateRecentOpenPanel(pageModel);
|
|
|
|
this.body.add(recentOpenPanel, BorderLayout.SOUTH);
|
|
|
|
this.contentPane = new JPanel();
|
|
|
|
this.contentPane.setLayout(getCenterLayout(body));
|
|
|
|
this.contentPane.add(this.body, BorderLayout.CENTER);
|
|
|
|
this.contentPane.setPreferredSize(this.body.getPreferredSize());
|
|
|
|
|
|
|
|
this.layeredPane.setName("layered-pane");
|
|
|
|
this.layeredPane.add(this.contentPane, CONTENT_LAYER);
|
|
|
|
this.layeredPane.add(this.loadingPane, TRANSPARENT_LAYER);
|
|
|
|
this.layeredPane.moveToFront(this.contentPane);
|
|
|
|
|
|
|
|
add(this.layeredPane, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
// Workspace-detail
|
|
|
|
setSize(SCREEN_SIZE);
|
|
|
|
setDefaultTitle();
|
|
|
|
addDefaultListeners();
|
|
|
|
|
|
|
|
repaint();
|
|
|
|
validate();
|
|
|
|
revalidate();
|
|
|
|
|
|
|
|
GUICoreUtils.centerWindow(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addDefaultListeners() {
|
|
|
|
|
|
|
|
addWindowListener(new WindowAdapter() {
|
|
|
|
@Override
|
|
|
|
public void windowClosing(WindowEvent e) {
|
|
|
|
DesignerExiter.getInstance().execute();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setDefaultTitle() {
|
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append(ProductConstants.APP_NAME);
|
|
|
|
sb.append(" ");
|
|
|
|
sb.append(GeneralUtils.getVersion());
|
|
|
|
sb.append(" ");
|
|
|
|
sb.append(ProductConstants.BRANCH);
|
|
|
|
sb.append(" ");
|
|
|
|
sb.append(Toolkit.i18nText("Fine-Design_Startup_Page_Title"));
|
|
|
|
setTitle(sb.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
private void patchUIAction(StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
Runnable selectAndOpenLastTemplateRunnable = pageModel.getOpenLastTemplateRunnable();
|
|
|
|
pageModel.setOpenLastTemplateRunnable(() -> {
|
|
|
|
enterWorkspace(selectAndOpenLastTemplateRunnable);
|
|
|
|
});
|
|
|
|
|
|
|
|
Runnable createNewTemplateRunnable = pageModel.getCreateNewTemplateRunnable();
|
|
|
|
pageModel.setCreateNewTemplateRunnable(() -> {
|
|
|
|
enterWorkspace(createNewTemplateRunnable);
|
|
|
|
});
|
|
|
|
|
|
|
|
Runnable openEmptyTemplateRunnable = pageModel.getOpenEmptyTemplateRunnable();
|
|
|
|
pageModel.setOpenEmptyTemplateRunnable(() -> {
|
|
|
|
enterWorkspace(openEmptyTemplateRunnable);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void enterWorkspace(Runnable action) {
|
|
|
|
|
|
|
|
loadingPane.start();
|
|
|
|
layeredPane.moveToFront(loadingPane);
|
|
|
|
SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() {
|
|
|
|
@Override
|
|
|
|
protected Void doInBackground() throws Exception {
|
|
|
|
action.run();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void done() {
|
|
|
|
|
|
|
|
try {
|
|
|
|
Void result = get();
|
|
|
|
setVisible(false);
|
|
|
|
} catch (Exception e) {
|
|
|
|
// 处理错误
|
|
|
|
UIUtil.invokeLaterIfNeeded(() -> {
|
|
|
|
UIExpandDialog.Builder()
|
|
|
|
.owner(StartupPageWindow.this)
|
|
|
|
.title(Toolkit.i18nText("Fine-Design_Basic_Remote_Env_Try"))
|
|
|
|
.message(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed"))
|
|
|
|
.messageType(UIExpandDialog.WARNING_MESSAGE)
|
|
|
|
.detail(e.getMessage())
|
|
|
|
.expand(true)
|
|
|
|
.modal(false)
|
|
|
|
.build()
|
|
|
|
.setVisible(true);
|
|
|
|
});
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
|
|
|
layeredPane.moveToFront(contentPane);
|
|
|
|
} finally {
|
|
|
|
loadingPane.stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
task.execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
private JPanel generateRecentOpenPanel(StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
JPanel recentOpenPanel = new JPanel() {
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
g2d.setColor(Color.WHITE);
|
|
|
|
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), StartupPageConstants.ARC_DIAMETER, StartupPageConstants.ARC_DIAMETER);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
recentOpenPanel.setLayout(new BorderLayout());
|
|
|
|
recentOpenPanel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 6));
|
|
|
|
|
|
|
|
StartupWorkspaceBean workspaceInfo = pageModel.getSelectWorkspaceInfo();
|
|
|
|
JPanel workspaceWrapperYPanel = new JPanel();
|
|
|
|
workspaceWrapperYPanel.setName("workspace-wrapper");
|
|
|
|
{
|
|
|
|
workspaceWrapperYPanel.setLayout(new VerticalFlowLayout());
|
|
|
|
|
|
|
|
JPanel workspaceWrapperXPanel = new JPanel();
|
|
|
|
workspaceWrapperXPanel.setLayout(new FlowLayout());
|
|
|
|
workspaceWrapperXPanel.setBorder(BorderFactory.createEmptyBorder());
|
|
|
|
|
|
|
|
JPanel workspacePanel = new JPanel();
|
|
|
|
workspacePanel.setLayout(new BorderLayout(0, 15));
|
|
|
|
|
|
|
|
UILabel workspaceIcon = new UILabel(StartupPageUtil.getIcon4RecentAreaByWorkspace(workspaceInfo));
|
|
|
|
workspacePanel.add(workspaceIcon, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
UILabel nameLabel = new UILabel(workspaceInfo.getName());
|
|
|
|
nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
|
workspacePanel.add(nameLabel, BorderLayout.SOUTH);
|
|
|
|
workspaceWrapperXPanel.add(workspacePanel);
|
|
|
|
Dimension preferredSize = workspaceWrapperXPanel.getPreferredSize();
|
|
|
|
workspaceWrapperXPanel.setPreferredSize(new Dimension(WORKSPACE_PANEL_WIDTH, (int) preferredSize.getHeight()));
|
|
|
|
|
|
|
|
workspaceWrapperYPanel.add(workspaceWrapperXPanel);
|
|
|
|
}
|
|
|
|
recentOpenPanel.add(workspaceWrapperYPanel, BorderLayout.WEST);
|
|
|
|
|
|
|
|
JPanel separatorPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
|
|
|
|
{
|
|
|
|
JSeparator sep = new JSeparator();
|
|
|
|
sep.setOrientation(JSeparator.VERTICAL);
|
|
|
|
sep.setForeground(SEP_COLOR);
|
|
|
|
separatorPanel.add(sep, BorderLayout.CENTER);
|
|
|
|
}
|
|
|
|
recentOpenPanel.add(separatorPanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
JComponent recentOpenGroupPanel = generateRecentOpenGroupPanel(pageModel, workspaceInfo);
|
|
|
|
recentOpenPanel.add(recentOpenGroupPanel, BorderLayout.EAST);
|
|
|
|
|
|
|
|
ColorUtils.syncBackground(recentOpenPanel, Color.WHITE);
|
|
|
|
|
|
|
|
Dimension preferredSize = recentOpenPanel.getPreferredSize();
|
|
|
|
recentOpenPanel.setPreferredSize(new Dimension(StartupPageConstants.CONTENT_WIDTH, (int) preferredSize.getHeight()));
|
|
|
|
|
|
|
|
JPanel recentOpenWrapperPanel = new JPanel();
|
|
|
|
recentOpenWrapperPanel.setName("recentOpenWrapper");
|
|
|
|
recentOpenWrapperPanel.setLayout(new BorderLayout(0, 0));
|
|
|
|
recentOpenWrapperPanel.setBorder(new EmptyBorder(0, 0, 0, 20));
|
|
|
|
recentOpenWrapperPanel.add(recentOpenPanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
return recentOpenWrapperPanel;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private JComponent generateRecentOpenGroupPanel(StartupPageModel pageModel, StartupWorkspaceBean workspaceInfo) {
|
|
|
|
|
|
|
|
JPanel recentOpenGroupPanel = new JPanel();
|
|
|
|
Map<String, List<String>> recentFilesMap = pageModel.getRecentFilesMap();
|
|
|
|
|
|
|
|
boolean needScroll = false;
|
|
|
|
double itemHeight = 0.0d;
|
|
|
|
if (!CollectionUtils.isEmpty(recentFilesMap)) {
|
|
|
|
String name = workspaceInfo.getName();
|
|
|
|
List<String> recentFiles = recentFilesMap.get(name);
|
|
|
|
if (!CollectionUtils.isEmpty(recentFiles)) {
|
|
|
|
recentOpenGroupPanel.setLayout(new GridLayout(recentFiles.size(), 1, 50, 5));
|
|
|
|
needScroll = recentFiles.size() > RECENT_FILE_LIMIT;
|
|
|
|
for (String recentFile : recentFiles) {
|
|
|
|
JPanel recentItemPanel = new JPanel();
|
|
|
|
recentItemPanel.setLayout(new FlowLayout(FlowLayout.LEFT, ITEM_VERTICAL_GAP, 0));
|
|
|
|
recentItemPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/system/cpt.svg")));
|
|
|
|
UILabel recentFileLabel = new UILabel(recentFile);
|
|
|
|
Color recentFileLabelForeground = recentFileLabel.getForeground();
|
|
|
|
recentItemPanel.add(recentFileLabel);
|
|
|
|
recentItemPanel.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
recentFileLabel.setForeground(HOVER_COLOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
recentFileLabel.setForeground(recentFileLabelForeground);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
|
|
doOpenLastTemplateAction(recentFile, pageModel);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Dimension preferredSize = recentItemPanel.getPreferredSize();
|
|
|
|
itemHeight = preferredSize.getHeight();
|
|
|
|
recentOpenGroupPanel.add(recentItemPanel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Dimension preferredSize = recentOpenGroupPanel.getPreferredSize();
|
|
|
|
recentOpenGroupPanel.setPreferredSize(new Dimension(GROUP_WIDTH, (int) preferredSize.getHeight()));
|
|
|
|
|
|
|
|
if (needScroll) {
|
|
|
|
int scrollHeight = (int) Math.round(itemHeight * RECENT_FILE_LIMIT + ITEM_VERTICAL_GAP * (RECENT_FILE_LIMIT));
|
|
|
|
UIScrollPane scrollPane = new UIScrollPane(recentOpenGroupPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
|
|
|
scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
|
|
|
|
scrollPane.setPreferredSize(new Dimension(GROUP_WIDTH, scrollHeight));
|
|
|
|
return scrollPane;
|
|
|
|
}
|
|
|
|
return recentOpenGroupPanel;
|
|
|
|
}
|
|
|
|
|
|
|
|
private StartupPageWorkspacePanel generateWorkspacePanel(StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
return new StartupPageWorkspacePanel(pageModel);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected LayoutManager getCenterLayout(JComponent centerBody) {
|
|
|
|
|
|
|
|
return FRGUIPaneFactory.createCenterLayout(centerBody);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doOpenLastTemplateAction(String recentFile, StartupPageModel pageModel) {
|
|
|
|
|
|
|
|
DesignerEnvManager.getEnvManager().setLastOpenFile(recentFile);
|
|
|
|
pageModel.getOpenLastTemplateRunnable().run();
|
|
|
|
}
|
|
|
|
}
|