You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
13 KiB
329 lines
13 KiB
package com.fr.design.mainframe.theme; |
|
|
|
import com.fr.base.theme.FormTheme; |
|
import com.fr.base.theme.FormThemeConfig; |
|
import com.fr.base.theme.ReportTheme; |
|
import com.fr.base.theme.ReportThemeConfig; |
|
import com.fr.base.theme.TemplateTheme; |
|
import com.fr.base.theme.TemplateThemeConfig; |
|
import com.fr.design.actions.UpdateAction; |
|
import com.fr.design.dialog.BasicPane; |
|
import com.fr.design.dialog.FineJOptionPane; |
|
import com.fr.design.event.ChangeEvent; |
|
import com.fr.design.event.ChangeListener; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.gui.itoolbar.UIToolbar; |
|
import com.fr.design.i18n.Toolkit; |
|
import com.fr.design.icon.IconPathConstants; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; |
|
import com.fr.design.menu.MenuDef; |
|
import com.fr.design.menu.ToolBarDef; |
|
import com.fr.general.IOUtils; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.stable.StringUtils; |
|
import com.fr.third.javax.annotation.Nullable; |
|
import com.fr.transaction.CallBackAdaptor; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.JOptionPane; |
|
import javax.swing.JPanel; |
|
import javax.swing.JSeparator; |
|
import javax.swing.SwingUtilities; |
|
import javax.swing.border.LineBorder; |
|
import java.awt.BasicStroke; |
|
import java.awt.BorderLayout; |
|
import java.awt.Color; |
|
import java.awt.Component; |
|
import java.awt.Dimension; |
|
import java.awt.FlowLayout; |
|
import java.awt.Graphics; |
|
import java.awt.Graphics2D; |
|
import java.awt.RenderingHints; |
|
import java.awt.Stroke; |
|
import java.awt.Window; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.WindowAdapter; |
|
import java.awt.event.WindowEvent; |
|
|
|
import static com.fr.design.i18n.Toolkit.i18nText; |
|
|
|
/** |
|
* @author Starryi |
|
* @version 1.0 |
|
* Created by Starryi on 2021/8/13 |
|
*/ |
|
public class TemplateThemeGridControlPane<T extends TemplateTheme> extends BasicPane { |
|
public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 20; |
|
public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; |
|
private final RemoveThemeAction removeAction; |
|
private final UIButton setTheme4NewTemplateButton; |
|
|
|
private final TemplateThemeConfig<T> config; |
|
private final TemplateThemeGridPane<T> themeListPane; |
|
private final TemplateThemeProfilePane<T> profilePane; |
|
|
|
private final AsyncThemeFetcher<T> asyncThemeFetcher; |
|
|
|
private final Window window; |
|
|
|
public static TemplateThemeGridControlPane<FormTheme> createFormThemesManagerPane(@Nullable Window window) { |
|
FormThemeConfig config = FormThemeConfig.getInstance(); |
|
FormThemeProfilePane editPane = new FormThemeProfilePane(config); |
|
return new TemplateThemeGridControlPane<>(window, config, editPane); |
|
} |
|
|
|
public static TemplateThemeGridControlPane<ReportTheme> createReportThemesManagerPane(@Nullable Window window) { |
|
ReportThemeConfig config = ReportThemeConfig.getInstance(); |
|
ReportThemeProfilePane editPane = new ReportThemeProfilePane(config); |
|
return new TemplateThemeGridControlPane<>(window, config, editPane); |
|
} |
|
|
|
public TemplateThemeGridControlPane(@Nullable Window window, TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) { |
|
this.window = window; |
|
this.config = config; |
|
this.profilePane = profilePane; |
|
this.themeListPane = new TemplateThemeGridPane<>(window, true, config, profilePane); |
|
this.removeAction = new RemoveThemeAction(false); |
|
this.setTheme4NewTemplateButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Default_Setting")); |
|
this.asyncThemeFetcher = new AsyncThemeFetcher<>(1, config); |
|
|
|
initializePane(); |
|
registerWindowListener(); |
|
} |
|
|
|
public TemplateThemeConfig<T> getConfig() { |
|
return config; |
|
} |
|
|
|
private void initializePane() { |
|
setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10)); |
|
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); |
|
|
|
add(createActionsContainer(), BorderLayout.NORTH); |
|
|
|
JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
add(nextContainer, BorderLayout.CENTER); |
|
|
|
nextContainer.add(new JSeparator(), BorderLayout.NORTH); |
|
|
|
themeListPane.setSelectedChangeListener(new ChangeListener() { |
|
@Override |
|
public void fireChanged(ChangeEvent event) { |
|
resetEnableRemoveAction(themeListPane.getSelectedTheme(), removeAction); |
|
resetEnableSetTheme4NewTemplateButton(themeListPane.getSelectedTheme(), setTheme4NewTemplateButton); |
|
} |
|
}); |
|
nextContainer.add(themeListPane, BorderLayout.CENTER); |
|
|
|
resetEnableRemoveAction(themeListPane.getSelectedTheme(), removeAction); |
|
resetEnableSetTheme4NewTemplateButton(themeListPane.getSelectedTheme(), setTheme4NewTemplateButton); |
|
|
|
repaint(); |
|
} |
|
|
|
private void registerWindowListener() { |
|
if (window != null) { |
|
window.addWindowListener(new WindowAdapter() { |
|
@Override |
|
public void windowClosed(WindowEvent e) { |
|
super.windowClosed(e); |
|
asyncThemeFetcher.shutdown(); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
private void resetEnableRemoveAction(T selectedTheme, RemoveThemeAction removeAction) { |
|
if (selectedTheme == null) { |
|
removeAction.setEnabled(false); |
|
return; |
|
} |
|
String selectedThemeName = selectedTheme.getName(); |
|
if (StringUtils.isEmpty(selectedThemeName)) { |
|
removeAction.setEnabled(false); |
|
return; |
|
} |
|
|
|
removeAction.setEnabled(selectedTheme.isRemovable()); |
|
} |
|
|
|
private void resetEnableSetTheme4NewTemplateButton(T selectedTheme, UIButton setTheme4NewTemplateButton) { |
|
if (selectedTheme == null) { |
|
setTheme4NewTemplateButton.setEnabled(false); |
|
return; |
|
} |
|
String selectedThemeName = selectedTheme.getName(); |
|
if (StringUtils.isEmpty(selectedThemeName)) { |
|
setTheme4NewTemplateButton.setEnabled(false); |
|
return; |
|
} |
|
|
|
T currentTheme4NewTemplate = config.cachedFetchTheme4NewTemplate(); |
|
if (currentTheme4NewTemplate == null) { |
|
setTheme4NewTemplateButton.setEnabled(true); |
|
return; |
|
} |
|
String currentThemeName4NewTemplate = currentTheme4NewTemplate.getName(); |
|
if (StringUtils.isEmpty(currentThemeName4NewTemplate)) { |
|
setTheme4NewTemplateButton.setEnabled(true); |
|
return; |
|
} |
|
|
|
setTheme4NewTemplateButton.setEnabled(!StringUtils.equals(currentThemeName4NewTemplate, selectedTheme.getName())); |
|
} |
|
|
|
private JPanel createActionsContainer() { |
|
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
content.setPreferredSize(new Dimension(content.getPreferredSize().width, 20)); |
|
|
|
UIToolbar toolBar = ToolBarDef.createJToolBar(); |
|
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
|
content.add(toolBar, BorderLayout.CENTER); |
|
|
|
MenuDef addMenuDef = createAddMenuDef(); |
|
|
|
ToolBarDef toolbarDef = new ToolBarDef(); |
|
toolbarDef.addShortCut(addMenuDef, removeAction); |
|
toolbarDef.updateToolBar(toolBar); |
|
|
|
setTheme4NewTemplateButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
T theme = themeListPane.getSelectedTheme(); |
|
if (theme != null) { |
|
config.setThemeName4NewTemplate(theme.getName(), new CallBackAdaptor() { |
|
@Override |
|
public void afterRollback() { |
|
super.afterRollback(); |
|
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), |
|
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), |
|
i18nText("Fine-Design_Basic_Alert"), |
|
JOptionPane.WARNING_MESSAGE); |
|
} |
|
}); |
|
} |
|
} |
|
}); |
|
content.add(setTheme4NewTemplateButton, BorderLayout.EAST); |
|
|
|
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
container.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); |
|
container.add(content, BorderLayout.CENTER); |
|
|
|
container.setPreferredSize(new Dimension(container.getPreferredSize().width, 30)); |
|
|
|
return container; |
|
} |
|
|
|
private MenuDef createAddMenuDef() { |
|
MenuDef menuDef = new MenuDef(Toolkit.i18nText("Fine-Design_Basic_Action_Add")); |
|
menuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH); |
|
menuDef.setRePaint(true); |
|
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Create_Light_Theme"), config.getDefaultLightThemeName())); |
|
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Create_Dark_Theme"), config.getDefaultDarkThemeName())); |
|
|
|
return menuDef; |
|
} |
|
|
|
@Override |
|
protected String title4PopupWindow() { |
|
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"); |
|
} |
|
|
|
private class RemoveThemeAction extends UpdateAction { |
|
|
|
public RemoveThemeAction(boolean initialEnabled) { |
|
setEnabled(initialEnabled); |
|
setName(Toolkit.i18nText("Fine-Design_Basic_Remove")); |
|
setMnemonic('R'); |
|
setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_REMOVE_ICON_PATH)); |
|
} |
|
|
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
T theme = TemplateThemeGridControlPane.this.themeListPane.getSelectedTheme(); |
|
if (theme == null) { |
|
return; |
|
} |
|
int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), |
|
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Delete_Tip", theme.getName()), |
|
Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); |
|
if (result == JOptionPane.YES_OPTION) { |
|
config.removeTheme(theme.getName(), new CallBackAdaptor() { |
|
@Override |
|
public void afterRollback() { |
|
super.afterRollback(); |
|
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), |
|
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), |
|
i18nText("Fine-Design_Basic_Alert"), |
|
JOptionPane.WARNING_MESSAGE); |
|
} |
|
}); |
|
} |
|
} |
|
} |
|
|
|
private class AddThemeAction extends UpdateAction { |
|
private final String prototypeThemeName; |
|
|
|
public AddThemeAction(String name, String prototypeThemeName) { |
|
setName(name); |
|
setMnemonic('R'); |
|
this.prototypeThemeName = prototypeThemeName; |
|
} |
|
|
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
asyncThemeFetcher.submit(prototypeThemeName, new AsyncThemeFetcher.AsyncThemeFetchCallbackAdapter<T>() { |
|
@Override |
|
public void afterCachedFetch(T theme) { |
|
super.afterCachedFetch(theme); |
|
createNewTheme(theme); |
|
} |
|
}); |
|
} |
|
|
|
private void createNewTheme(T prototypeTheme) { |
|
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this); |
|
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane); |
|
try { |
|
T theme = (T) prototypeTheme.clone(); |
|
theme.setName(StringUtils.EMPTY); |
|
theme.setMutable(true); |
|
theme.setRemovable(true); |
|
profilePane.populateBean(theme); |
|
profileDialog.setVisible(true); |
|
} catch (CloneNotSupportedException ex) { |
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
|
} |
|
} |
|
} |
|
|
|
public static class BottomLineBorder extends LineBorder { |
|
|
|
private BottomLineBorder(Color color, int thickness) { |
|
super(color, thickness); |
|
} |
|
|
|
@Override |
|
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
|
Graphics2D g2d = (Graphics2D)g; |
|
|
|
Color oldColor = g2d.getColor(); |
|
Stroke oldStroke = g2d.getStroke(); |
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
|
|
g2d.setColor(getLineColor()); |
|
g2d.setStroke(new BasicStroke(getThickness() * 2)); |
|
g2d.drawLine(0, height, width, height + getThickness() * 2); |
|
|
|
g2d.setStroke(oldStroke); |
|
g2d.setColor(oldColor); |
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
|
} |
|
} |
|
} |