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.log.FineLoggerFactory; 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.util.List; import java.util.Map; /** * 启动页 * 见设计文档 *

* 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); repaint(); validate(); revalidate(); GUICoreUtils.centerWindow(this); } 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 task = new SwingWorker() { @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> recentFilesMap = pageModel.getRecentFilesMap(); boolean needScroll = false; double itemHeight = 0.0d; if (!CollectionUtils.isEmpty(recentFilesMap)) { String name = workspaceInfo.getName(); List 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) { DesignerEnvManager.getEnvManager().setLastOpenFile(recentFile); pageModel.getOpenLastTemplateRunnable().run(); } }); 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_SCROLL)); 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); } }