diff --git a/README.md b/README.md index 391ab99..4e02824 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # demo-background-quick-ui-provider -单元格/组件背景接口demo \ No newline at end of file +单元格/组件背景接口demo\ +demo生效后,单元格的样式背景设置和决策报表的组件样式背景设置会增加一个Theme背景\ +选择不同的标签,背景色会不一样。 \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..3d3e2c4 --- /dev/null +++ b/build.gradle @@ -0,0 +1,124 @@ + +apply plugin: 'java' + +[compileJava,compileTestJava]*.options*.encoding = 'UTF-8' + +ext { + /** + * 项目中依赖的jar的路径 + * 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 + * 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 + */ + libPath = "$projectDir/../webroot/WEB-INF/lib" + + /** + * 是否对插件的class进行加密保护,防止反编译 + */ + guard = false + + def pluginInfo = getPluginInfo() + pluginPre = "fine-plugin" + pluginName = pluginInfo.id + pluginVersion = pluginInfo.version + + outputPath = "$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes" +} + +group = 'com.fr.plugin' +version = '10.0' +sourceCompatibility = '8' + +sourceSets { + main { + java.outputDir = file(outputPath) + output.resourcesDir = file(outputPath) + } +} + +ant.importBuild("encrypt.xml") +//定义ant变量 +ant.projectDir = projectDir +ant.references["compile.classpath"] = ant.path { + fileset(dir: libPath, includes: '**/*.jar') + fileset(dir: ".",includes:"**/*.jar" ) +} + +classes.dependsOn('clean') + +task copyFiles(type: Copy,dependsOn: 'classes'){ + from outputPath + into "$projectDir/classes" +} + +task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){ + from "$projectDir/classes" + into "$projectDir/transform-classes" + include "**/*.*" +} +jar.dependsOn("preJar") + +task makeJar(type: Jar,dependsOn: preJar){ + from fileTree(dir: "$projectDir/transform-classes") + baseName pluginPre + appendix pluginName + version pluginVersion + destinationDir = file("$buildDir/libs") + + doLast(){ + delete file("$projectDir/classes") + delete file("$projectDir/transform-classes") + } +} + +task copyFile(type: Copy,dependsOn: ["makeJar"]){ + from "$buildDir/libs" + from("$projectDir/lib") { + include "*.jar" + } + from "$projectDir/plugin.xml" + into file("$buildDir/temp/plugin") +} + +task zip(type:Zip,dependsOn:["copyFile"]){ + from "$buildDir/temp/plugin" + destinationDir file("$buildDir/install") + baseName pluginPre + appendix pluginName + version pluginVersion +} + +//控制build时包含哪些文件,排除哪些文件 +processResources { +// exclude everything +// 用*.css没效果 +// exclude '**/*.css' +// except this file +// include 'xx.xml' +} + +/*读取plugin.xml中的version*/ +def getPluginInfo(){ + def xmlFile = file("plugin.xml") + if (!xmlFile.exists()) { + return ["id":"none", "version":"1.0.0"] + } + def plugin = new XmlParser().parse(xmlFile) + def version = plugin.version[0].text() + def id = plugin.id[0].text() + return ["id":id,"version":version] +} + +repositories { + mavenLocal() + maven { + url = uri('http://mvn.finedevelop.com/repository/maven-public/') + } +} + +dependencies { + //使用本地jar + implementation fileTree(dir: 'lib', include: ['**/*.jar']) + implementation fileTree(dir: libPath, include: ['**/*.jar']) +} + + diff --git a/encrypt.xml b/encrypt.xml new file mode 100644 index 0000000..1401cd1 --- /dev/null +++ b/encrypt.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..6329547 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,16 @@ + + com.tptj.demo.hg.background.quick.ui.v10 + + yes + 1.0 + 10.0 + tptj + 2019-07-18 + + + com.tptj.demo.hg.background.quick.ui + + + + + \ No newline at end of file diff --git a/src/main/java/com/tptj/demo/hg/background/quick/ui/Demo.java b/src/main/java/com/tptj/demo/hg/background/quick/ui/Demo.java new file mode 100644 index 0000000..7d68082 --- /dev/null +++ b/src/main/java/com/tptj/demo/hg/background/quick/ui/Demo.java @@ -0,0 +1,15 @@ +package com.tptj.demo.hg.background.quick.ui; + +import com.fr.design.fun.impl.AbstractBackgroundQuickUIProvider; +import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; +import com.fr.intelli.record.Focus; +import com.fr.record.analyzer.EnableMetrics; + +@EnableMetrics +public class Demo extends AbstractBackgroundQuickUIProvider { + @Override + @Focus(id = "com.tptj.demo.hg.background.quick.ui.v10",text = "单元格背景类型扩展demo") + public BackgroundQuickPane appearanceForBackground() { + return new DemoPane(); + } +} diff --git a/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoBackground.java b/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoBackground.java new file mode 100644 index 0000000..3677319 --- /dev/null +++ b/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoBackground.java @@ -0,0 +1,242 @@ +package com.tptj.demo.hg.background.quick.ui; + +import com.fr.base.background.AbstractBackground; +import com.fr.general.Background; +import com.fr.json.JSONException; +import com.fr.json.JSONObject; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.bridge.ObjectHolder; +import com.fr.stable.web.Repository; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLableReader; +import java.awt.*; + + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2021-02-25 + * 注:因为接口设计的问题,不要直接集成产品内置的背景对象,重新编辑的时候会被转换成他的继承的对象 + * 具体可以参见:BackgroundPane#supportKindsOfBackgroundUI、populateBean + **/ +public class DemoBackground extends AbstractBackground { + + private String theme; + private String tag; + + public String getTheme() { + return theme; + } + + public void setTheme(String theme) { + this.theme = theme; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + private Color getColor() { + return ThemeManager.getInstance().getColor(theme,tag); + } + + @Override + /** + * 根据指定的画图对象和几何图形来画颜色背景 + * + * @param g 画图对象 + * @param shape 几何图形 + */ + public void paint(Graphics g, Shape shape) { + Paint paint = this.getColor(); + if (paint == null) { + return; + } + // shape类型 Rectangle2D + Graphics2D g2d = (Graphics2D) g; + Paint oldPaint = g2d.getPaint(); + g2d.setPaint(paint); + g2d.fill(shape); + g2d.setPaint(oldPaint); + } + + @Override + public void drawWithGradientLine(Graphics g, Shape shape) { + Paint paint = this.getColor(); + if (paint == null) { + return; + } + // shape类型 Rectangle2D + Graphics2D g2d = (Graphics2D) g; + Paint oldPaint = g2d.getPaint(); + g2d.setPaint(paint); + g2d.draw(shape); + g2d.setPaint(oldPaint); + } + + @Override + public String getBackgroundType() { + return "Theme"; + } + + @Override + public void paint(Graphics g, Repository repo, Shape shape) { + paint(g, shape); + } + + /** + * 布局变化 + * + * @param width 背景宽度 + * @param height 背景高度 + */ + @Override + public void layoutDidChange(int width, int height) { + super.layoutDidChange(width, height); + System.out.println(); + } + + /** + * 修正哈希码 + * + * @param code 已经计算好的哈希码 + * @return 哈希码 + */ + @Override + public int fixHashCode(int code) { + return code ^ (theme+tag).hashCode() ; + } + + /** + * 克隆 + * + * @return 克隆生成的对象 + * @throws CloneNotSupportedException + */ + @Override + public Object clone() throws CloneNotSupportedException { + DemoBackground obj = (DemoBackground)super.clone(); + obj.tag = tag; + obj.theme = theme; + return obj; + } + + + /** + * 将背景输出成JSON对象 + * + * @return 表示背景的JSON对象 + * @throws JSONException + */ + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject jo = super.toJSONObject(); + jo.put("color", StableUtils.javaColorToCSSColor(getColor())); + return jo; + } + + @Override + public boolean equals(Object object) { + return object instanceof DemoBackground && + StringUtils.equals(((DemoBackground) object).theme, theme) && + StringUtils.equals(((DemoBackground) object).tag, tag); + } + + @Override + public JSONObject toJSONObject(Repository repo) throws JSONException{ + JSONObject jo = super.toJSONObject(repo); + jo.put("color", StableUtils.javaColorToCSSColor(getColor())); + return jo; + } + @Override + public JSONObject toJSONObject(Repository repo, Dimension size) throws JSONException { + JSONObject jo = super.toJSONObject(repo, size); + jo.put("color", StableUtils.javaColorToCSSColor(getColor())); + return jo; + } + + @Override + public Background readAdditionalAttr(XMLableReader reader) { + DemoBackground item = new DemoBackground(); + item.theme = reader.getAttrAsString("theme",StringUtils.EMPTY); + item.tag = reader.getAttrAsString("tag",StringUtils.EMPTY); + return item; + } + + @Override + public void writeAdditionalAttr(XMLPrintWriter writer) { + writer.attr("name", "Theme").attr("class",DemoBackground.class.getName()); + if ( StringUtils.isNotEmpty(theme) ) { + writer.attr("theme", theme); + } + if ( StringUtils.isNotEmpty(tag) ) { + writer.attr("tag", tag); + } + } + + @Override + /** + * 根据指定的画图对象和尺寸来画背景,并且保存对应的单元格坐标点,背景预处理 + * @param g 画图对象 + * @param repo 模板上下文 + * @param cellPoint 单元格坐标 + * @param width 图片宽 + * @param height 图片高 + */ + public void preDealBackground(Graphics g, Repository repo, Point cellPoint, int width, int height){ + super.preDealBackground(g, repo, cellPoint, width, height); + System.out.println(); + } + + @Override + /** + * 导出的时候更改背景 + * @param operate 导出的操作类型,excel,pdf,word... + * @return 背景 + */ + public Background traverseForExport(ObjectHolder operate) { + return this; + } + + /** + * 控件背景输出json到web端. + * + * @param repo 浏览器上下文 + * @return json格式内容. + */ + @Override + public JSONObject createJSONConfig(Repository repo) throws JSONException { + Color color = getColor(); + if (color == null) { + // 透明色, 不设置{background : ""}. + return JSONObject.EMPTY; + } + String colorStr = StableUtils.javaColorToCSSColor(color); + return JSONObject.create().put("background", colorStr); + } + + @Override + public void readXML(XMLableReader reader) { + //这里实现得好奇怪 + super.readXML(reader); + } + + @Override + public void writeXML(XMLPrintWriter writer) { + //这里实现得好奇怪 + super.writeXML(writer); + } + + @Override + public JSONObject createJSONConfig(Repository repo, int width, int height) throws JSONException{ + JSONObject jo = new JSONObject(); + jo.put("background-color", StableUtils.javaColorToCSSColor((this.getColor()))); + return jo; + } + +} diff --git a/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoPane.java b/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoPane.java new file mode 100644 index 0000000..6295656 --- /dev/null +++ b/src/main/java/com/tptj/demo/hg/background/quick/ui/DemoPane.java @@ -0,0 +1,119 @@ +package com.tptj.demo.hg.background.quick.ui; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; +import com.fr.general.Background; +import com.fr.invoke.Reflect; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; + + +public class DemoPane extends BackgroundQuickPane { + + private UIComboBox w_theme; + private UIComboBox w_tag; + + public DemoPane(){ + w_theme = new UIComboBox( ThemeManager.getInstance().getThemes() ); + w_tag = new UIComboBox( ThemeManager.getInstance().getTags() ); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel pane = TableLayoutHelper.createTableLayoutPane( + new Component[][]{{new UILabel("主题:"),w_theme},{new UILabel("标签:"),w_tag}}, + new double[]{TableLayout.PREFERRED,TableLayout.PREFERRED}, + new double[]{TableLayout.PREFERRED,TableLayout.PREFERRED} + ); + ItemListener listener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + change(w_theme.getSelectedItem().toString(),w_tag.getSelectedItem().toString()); + } + }; + w_theme.addItemListener(listener); + w_tag.addItemListener(listener); + this.add(pane, BorderLayout.NORTH); + } + + @Override + /** + * + * @param background + * @return 传入的background是否是DemoBackground + */ + public boolean accept(Background background) { + return background instanceof DemoBackground; + } + + @Override + public void populateBean(Background background) { + DemoBackground item = (DemoBackground)background; + w_theme.setSelectedItem(item.getTheme()); + w_tag.setSelectedItem(item.getTag()); + } + + @Override + public Background updateBean() { + DemoBackground item = new DemoBackground(); + item.setTheme( w_theme.getSelectedItem().toString() ); + item.setTag( w_tag.getSelectedItem().toString() ); + return item; + } + + @Override + public String title4PopupWindow() { + return "Theme背景"; + } + + @Override + public void reset() { + w_theme.setSelectedIndex(0); + w_tag.setSelectedIndex(0); + } + + private ArrayList listeners = new ArrayList(); + + private void change(String theme,String tag){ + if ( !listeners.isEmpty() ) { + ChangeEvent evn = new ChangeEvent(this); + for( ChangeListener listener : listeners ) { + listener.stateChanged(evn); + } + } + Color color = ThemeManager.getInstance().getColor( theme, tag ); + if( null != color ){ + DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(color); + repaint(); + } + } + + @Override + public void registerChangeListener(UIObserverListener listener) { + listeners.add(new ChangeListenerImpl(listener)); + System.out.println(); + } + + class ChangeListenerImpl implements ChangeListener { + private UIObserverListener listener; + + public ChangeListenerImpl(UIObserverListener listener) { + this.listener = listener; + } + + public void stateChanged(ChangeEvent event) { + Reflect.on(DemoPane.this).set("backgroundChange",true); + this.listener.doChange(); + Reflect.on(DemoPane.this).set("backgroundChange",false); + } + } +} diff --git a/src/main/java/com/tptj/demo/hg/background/quick/ui/ThemeManager.java b/src/main/java/com/tptj/demo/hg/background/quick/ui/ThemeManager.java new file mode 100644 index 0000000..29b62b1 --- /dev/null +++ b/src/main/java/com/tptj/demo/hg/background/quick/ui/ThemeManager.java @@ -0,0 +1,55 @@ +package com.tptj.demo.hg.background.quick.ui; + +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2021-02-26 + **/ +public enum ThemeManager { + INSTANCE; + private Map> tags = new HashMap>(); + + public static ThemeManager getInstance(){ + if( INSTANCE.tags.isEmpty() ){ + synchronized (ThemeManager.class){ + if( INSTANCE.tags.isEmpty() ){ + INSTANCE.init(); + } + } + } + return INSTANCE; + } + + private void init(){ + //Theme1 + Map theme1 = new HashMap(); + theme1.put("Lv1",Color.BLACK); + theme1.put("Lv2",Color.BLUE); + tags.put("Theme1",theme1); + //Theme2 + Map theme2 = new HashMap(); + theme2.put("Lv1",Color.GRAY); + theme2.put("Lv2",Color.CYAN); + tags.put("Theme2",theme2); + } + + public Color getColor( String group, String tag ){ + Map theme = tags.get(group); + if( null == theme ){ + return null; + } + return theme.get(tag); + } + + public String[] getThemes(){ + return tags.keySet().toArray(new String[0]); + } + + public String[] getTags(){ + return tags.get("Theme1").keySet().toArray(new String[0]); + } +}