forked from fanruan/design
185 changed files with 2320 additions and 874 deletions
@ -0,0 +1,70 @@
|
||||
package com.fr.design.actions.help; |
||||
|
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.ui.ModernUIPane; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.fr.web.struct.Atom; |
||||
import com.fr.web.struct.browser.RequestClient; |
||||
import com.fr.web.struct.category.ScriptPath; |
||||
import com.fr.web.struct.impl.FineUI; |
||||
import com.teamdev.jxbrowser.chromium.JSValue; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; |
||||
|
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-08 |
||||
*/ |
||||
public class FineUIAction extends UpdateAction { |
||||
|
||||
public FineUIAction() { |
||||
setName("FineUI"); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(final ActionEvent e) { |
||||
ModernUIPane<?> pane = new ModernUIPane.Builder<>() |
||||
.prepare(new ScriptContextAdapter() { |
||||
@Override |
||||
public void onScriptContextCreated(ScriptContextEvent event) { |
||||
JSValue pool = event.getBrowser().executeJavaScriptAndReturnValue("window.Pool"); |
||||
pool.asObject().setProperty("i18n", new I18n()); |
||||
} |
||||
}) |
||||
.withComponent(new AssembleComponent() { |
||||
|
||||
@Override |
||||
public ScriptPath script(RequestClient req) { |
||||
return ScriptPath.build("/com/fr/design/ui/help/demo.js"); |
||||
} |
||||
|
||||
@Override |
||||
public Atom[] refer() { |
||||
return new Atom[] {FineUI.KEY}; |
||||
} |
||||
}) |
||||
.build(); |
||||
BasicDialog dialog = pane.showLargeWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
|
||||
} |
||||
}); |
||||
dialog.setVisible(true); |
||||
|
||||
} |
||||
|
||||
public static class I18n { |
||||
|
||||
public String i18nText(String key) { |
||||
return InterProviderFactory.getProvider().getLocText(key); |
||||
} |
||||
} |
||||
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,11 @@
|
||||
package com.fr.design.mainframe; |
||||
|
||||
import com.fr.event.Event; |
||||
|
||||
public enum DesignAuthorityEventType implements Event<DesignerFrame> { |
||||
|
||||
// 退出权限编辑
|
||||
StartEdit, |
||||
// 进入权限编辑
|
||||
StopEdit; |
||||
} |
@ -0,0 +1,53 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.stable.StringUtils; |
||||
import com.teamdev.jxbrowser.chromium.Browser; |
||||
import com.teamdev.jxbrowser.chromium.BrowserContext; |
||||
import com.teamdev.jxbrowser.chromium.ProtocolService; |
||||
import com.teamdev.jxbrowser.chromium.URLResponse; |
||||
|
||||
import java.io.DataInputStream; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-07 |
||||
*/ |
||||
public class Assistant { |
||||
|
||||
public static URLResponse inputStream2Response(InputStream inputStream, String filePath) throws Exception { |
||||
URLResponse response = new URLResponse(); |
||||
DataInputStream stream = new DataInputStream(inputStream); |
||||
byte[] data = new byte[stream.available()]; |
||||
stream.readFully(data); |
||||
response.setData(data); |
||||
String mimeType = getMimeType(filePath); |
||||
response.getHeaders().setHeader("Content-Type", mimeType); |
||||
return response; |
||||
} |
||||
|
||||
|
||||
private static String getMimeType(String path) { |
||||
if (StringUtils.isBlank(path)) { |
||||
return "text/html"; |
||||
} |
||||
if (path.endsWith(".html")) { |
||||
return "text/html"; |
||||
} |
||||
if (path.endsWith(".css")) { |
||||
return "text/css"; |
||||
} |
||||
if (path.endsWith(".js")) { |
||||
return "text/javascript"; |
||||
} |
||||
return "text/html"; |
||||
} |
||||
|
||||
public static void setEmbProtocolHandler(Browser browser, EmbProtocolHandler handler) { |
||||
BrowserContext browserContext = browser.getContext(); |
||||
ProtocolService protocolService = browserContext.getProtocolService(); |
||||
// 支持读取jar包中文件的自定义协议————emb:/com/fr/design/images/bbs.png
|
||||
protocolService.setProtocolHandler("emb", handler); |
||||
} |
||||
} |
@ -0,0 +1,83 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.general.IOUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.fr.web.struct.AtomBuilder; |
||||
import com.fr.web.struct.PathGroup; |
||||
import com.fr.web.struct.category.ScriptPath; |
||||
import com.fr.web.struct.category.StylePath; |
||||
import com.teamdev.jxbrowser.chromium.ProtocolHandler; |
||||
import com.teamdev.jxbrowser.chromium.URLRequest; |
||||
import com.teamdev.jxbrowser.chromium.URLResponse; |
||||
|
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-07 |
||||
*/ |
||||
public class EmbProtocolHandler implements ProtocolHandler { |
||||
|
||||
private AssembleComponent component; |
||||
|
||||
public EmbProtocolHandler() { |
||||
|
||||
} |
||||
|
||||
public EmbProtocolHandler(AssembleComponent component) { |
||||
this.component = component; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public URLResponse onRequest(URLRequest req) { |
||||
try { |
||||
String path = req.getURL(); |
||||
if (path.startsWith("emb:dynamic")) { |
||||
URLResponse response = new URLResponse(); |
||||
response.setData(htmlText().getBytes()); |
||||
response.getHeaders().setHeader("Content-Type", "text/html"); |
||||
return response; |
||||
} else { |
||||
int index = path.indexOf("="); |
||||
if (index > 0) { |
||||
path = path.substring(index + 1); |
||||
} else { |
||||
path = path.substring(4); |
||||
} |
||||
InputStream inputStream = IOUtils.readResource(path); |
||||
return Assistant.inputStream2Response(inputStream, path); |
||||
} |
||||
} catch (Exception ignore) { |
||||
|
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private String htmlText() { |
||||
PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component); |
||||
StylePath[] stylePaths = pathGroup.toStylePathGroup(); |
||||
StringBuilder styleText = new StringBuilder(); |
||||
for (StylePath path : stylePaths) { |
||||
if (StringUtils.isNotBlank(path.toFilePath())) { |
||||
styleText.append("<link rel=\"stylesheet\" href=\"emb:"); |
||||
styleText.append(path.toFilePath()); |
||||
styleText.append("\"/>"); |
||||
} |
||||
} |
||||
String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString()); |
||||
ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup(); |
||||
StringBuilder scriptText = new StringBuilder(); |
||||
for (ScriptPath path : scriptPaths) { |
||||
if (StringUtils.isNotBlank(path.toFilePath())) { |
||||
scriptText.append("<script src=\"emb:"); |
||||
scriptText.append(path.toFilePath()); |
||||
scriptText.append("\"></script>"); |
||||
} |
||||
} |
||||
result = result.replaceAll("##script##", scriptText.toString()); |
||||
return result; |
||||
} |
||||
} |
@ -0,0 +1,22 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.web.struct.browser.RequestClient; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-07 |
||||
*/ |
||||
public enum ModernRequestClient implements RequestClient { |
||||
|
||||
KEY; |
||||
|
||||
@Override |
||||
public boolean isIE() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isLowIEVersion() { |
||||
return false; |
||||
}} |
@ -0,0 +1,15 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.general.IOUtils; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-05 |
||||
*/ |
||||
class ModernUIConstants { |
||||
|
||||
static final String SCRIPT_INIT_NAME_SPACE = IOUtils.readResourceAsString("/com/fr/design/ui/InitNameSpace.js"); |
||||
|
||||
static final String HTML_TPL = IOUtils.readResourceAsString("/com/fr/design/ui/tpl.html"); |
||||
} |
@ -0,0 +1,182 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.teamdev.jxbrowser.chromium.Browser; |
||||
import com.teamdev.jxbrowser.chromium.BrowserPreferences; |
||||
import com.teamdev.jxbrowser.chromium.JSValue; |
||||
import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent; |
||||
import com.teamdev.jxbrowser.chromium.events.LoadAdapter; |
||||
import com.teamdev.jxbrowser.chromium.events.LoadListener; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; |
||||
import com.teamdev.jxbrowser.chromium.swing.BrowserView; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-04 |
||||
* 用于加载html5的Swing容器,可以在设计选项设置中打开调试窗口,示例可查看:com.fr.design.ui.ModernUIPaneTest |
||||
*/ |
||||
public class ModernUIPane<T> extends BasicPane { |
||||
|
||||
private Browser browser; |
||||
private String namespace = "Pool"; |
||||
private String variable = "data"; |
||||
private String expression = "update()"; |
||||
|
||||
private ModernUIPane() { |
||||
initialize(); |
||||
} |
||||
|
||||
private void initialize() { |
||||
if (browser == null) { |
||||
setLayout(new BorderLayout()); |
||||
BrowserPreferences.setChromiumSwitches("--disable-google-traffic"); |
||||
if (DesignerEnvManager.getEnvManager().isOpenDebug()) { |
||||
JSplitPane splitPane = new JSplitPane(); |
||||
add(splitPane, BorderLayout.CENTER); |
||||
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); |
||||
splitPane.setDividerLocation(500); |
||||
BrowserPreferences.setChromiumSwitches("--remote-debugging-port=9222"); |
||||
initializeBrowser(); |
||||
splitPane.setLeftComponent(new BrowserView(browser)); |
||||
Browser debugger = new Browser(); |
||||
debugger.loadURL(browser.getRemoteDebuggingURL()); |
||||
BrowserView debuggerView = new BrowserView(debugger); |
||||
splitPane.setRightComponent(debuggerView); |
||||
} else { |
||||
initializeBrowser(); |
||||
add(new BrowserView(browser), BorderLayout.CENTER); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void initializeBrowser() { |
||||
browser = new Browser(); |
||||
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
|
||||
browser.addScriptContextListener(new ScriptContextAdapter() { |
||||
@Override |
||||
public void onScriptContextCreated(ScriptContextEvent event) { |
||||
event.getBrowser().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace)); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return "Modern"; |
||||
} |
||||
|
||||
|
||||
public void populate(final T t) { |
||||
browser.addLoadListener(new LoadAdapter() { |
||||
@Override |
||||
public void onFinishLoadingFrame(FinishLoadingEvent event) { |
||||
if (event.isMainFrame()) { |
||||
JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace); |
||||
ns.asObject().setProperty(variable, t); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public T update() { |
||||
JSValue jsValue = browser.executeJavaScriptAndReturnValue("window." + namespace + "." + expression); |
||||
if (jsValue.isObject()) { |
||||
return (T)jsValue.asJavaObject(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static class Builder<T> { |
||||
|
||||
private ModernUIPane<T> pane = new ModernUIPane<>(); |
||||
|
||||
public Builder<T> prepare(ScriptContextListener contextListener) { |
||||
pane.browser.addScriptContextListener(contextListener); |
||||
return this; |
||||
} |
||||
|
||||
public Builder<T> prepare(LoadListener loadListener) { |
||||
pane.browser.addLoadListener(loadListener); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 加载jar包中的资源 |
||||
* @param path 资源路径 |
||||
*/ |
||||
public Builder<T> withEMB(final String path) { |
||||
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); |
||||
pane.browser.loadURL("emb:" + path); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 加载url指向的资源 |
||||
* @param url 文件的地址 |
||||
*/ |
||||
public Builder<T> withURL(final String url) { |
||||
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); |
||||
pane.browser.loadURL(url); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 加载Atom组件 |
||||
* @param component Atom组件 |
||||
*/ |
||||
public Builder<T> withComponent(AssembleComponent component) { |
||||
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component)); |
||||
pane.browser.loadURL("emb:dynamic"); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 加载html文本内容 |
||||
* @param html 要加载html文本内容 |
||||
*/ |
||||
public Builder<T> withHTML(String html) { |
||||
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); |
||||
pane.browser.loadHTML(html); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置该前端页面做数据交换所使用的对象 |
||||
* @param namespace 对象名 |
||||
*/ |
||||
public Builder<T> namespace(String namespace) { |
||||
pane.namespace = namespace; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* java端往js端传数据时使用的变量名字 |
||||
* @param name 变量的名字 |
||||
*/ |
||||
public Builder<T> variable(String name) { |
||||
pane.variable = name; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* js端往java端传数据时执行的函数表达式 |
||||
* @param expression 函数表达式 |
||||
*/ |
||||
public Builder<T> expression(String expression) { |
||||
pane.expression = expression; |
||||
return this; |
||||
} |
||||
|
||||
public ModernUIPane<T> build() { |
||||
return pane; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,93 @@
|
||||
package com.fr.file; |
||||
|
||||
import javax.swing.Icon; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
public abstract class AbstractFILE implements FILE { |
||||
|
||||
@Override |
||||
public String prefix() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isDirectory() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public Icon getIcon() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public void setPath(String path) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public FILE getParent() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public FILE[] listFiles() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean createFolder(String name) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean mkfile() throws Exception { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean exists() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public void closeTemplate() throws Exception { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public InputStream asInputStream() throws Exception { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public OutputStream asOutputStream() throws Exception { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public String getEnvFullName() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isMemFile() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isEnvFile() { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
package com.fr.file; |
||||
|
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.commons.io.FileUtils; |
||||
import com.fr.web.session.SessionLocalManager; |
||||
|
||||
import javax.swing.Icon; |
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.OutputStream; |
||||
|
||||
public class RenameExportFILE extends AbstractFILE { |
||||
|
||||
private static final String EXPORT_SUFFIX = ".FRExportTmp"; |
||||
|
||||
private FILE file; |
||||
|
||||
private RenameExportFILE(FILE file) { |
||||
this.file = new FileFILE(new File(file.getPath() + EXPORT_SUFFIX)); |
||||
} |
||||
|
||||
public static RenameExportFILE create(FILE file) { |
||||
return new RenameExportFILE(file); |
||||
} |
||||
|
||||
public static String recoverFileName(String fileName) { |
||||
if (StringUtils.isEmpty(fileName) || !fileName.endsWith(EXPORT_SUFFIX)) { |
||||
return fileName; |
||||
} |
||||
return fileName.substring(0, fileName.lastIndexOf(EXPORT_SUFFIX)); |
||||
} |
||||
|
||||
@Override |
||||
public String prefix() { |
||||
return file.prefix(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isDirectory() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return file.getName(); |
||||
} |
||||
|
||||
@Override |
||||
public Icon getIcon() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return file.getPath(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public FILE getParent() { |
||||
return file.getParent(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public boolean mkfile() throws Exception { |
||||
return file.mkfile(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean exists() { |
||||
return file.exists(); |
||||
} |
||||
|
||||
@Override |
||||
public OutputStream asOutputStream() throws Exception { |
||||
|
||||
final File localeFile = new File(file.getPath()); |
||||
OutputStream out; |
||||
try { |
||||
StableUtils.makesureFileExist(localeFile); |
||||
out = new FileOutputStream(localeFile, false) { |
||||
@Override |
||||
public void close() throws IOException { |
||||
super.close(); |
||||
String path = file.getPath(); |
||||
if (localeFile.exists()) { |
||||
FileUtils.copyFile(localeFile, new File(recoverFileName(path))); |
||||
if (localeFile.getPath().endsWith(EXPORT_SUFFIX)) { |
||||
FileUtils.forceDelete(localeFile); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
} catch (Exception e) { |
||||
throw SessionLocalManager.createLogPackedException(e); |
||||
} |
||||
return out; |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
var arr ="%s".split(".").reverse(); |
||||
var create = function (obj, names) { |
||||
var name = names.pop(); |
||||
if (!name) { |
||||
return; |
||||
} |
||||
if (!obj[name]) { |
||||
obj[name] = {}; |
||||
} |
||||
create(obj[name], names); |
||||
}; |
||||
create(window, arr); |
@ -0,0 +1,8 @@
|
||||
var arr = "%s".split(","); |
||||
var header = document.getElementsByTagName("head")[0]; |
||||
arr.forEach(function(el) { |
||||
var script = document.createElement("script") |
||||
script.type = "text/javascript"; |
||||
script.src = "emb:" + el; |
||||
header.appendChild(script); |
||||
}); |
@ -0,0 +1,9 @@
|
||||
var arr = "%s".split(","); |
||||
var header = document.getElementsByTagName("head")[0]; |
||||
arr.forEach(function(el) { |
||||
var css = document.createElement("link"); |
||||
css.type = "text/css"; |
||||
css.rel = "stylesheet"; |
||||
css.href = "emb:" + el; |
||||
header.appendChild(css); |
||||
}); |
@ -0,0 +1,220 @@
|
||||
window.addEventListener("load", function (ev) { |
||||
window.BI.i18nText = function(key) {return window.Pool.i18n.i18nText(key);} |
||||
var combo1 = BI.createWidget({ |
||||
type: "bi.vertical", |
||||
items: [ |
||||
{ |
||||
type: "bi.text_value_combo", |
||||
text: "选项1", |
||||
width: 300, |
||||
items: [ |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项1", |
||||
value: 1 |
||||
}, |
||||
text: "选项1", |
||||
value: 1, |
||||
lgap: 10 |
||||
}, |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项2", |
||||
value: 2 |
||||
}, |
||||
lgap: 10, |
||||
text: "选项2", |
||||
value: 2 |
||||
}, |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项3", |
||||
value: 3 |
||||
}, |
||||
lgap: 10, |
||||
text: "选项3", |
||||
value: 3 |
||||
} |
||||
] |
||||
} |
||||
] |
||||
}); |
||||
|
||||
var date = BI.createWidget({ |
||||
type: "bi.left", |
||||
items: [{ |
||||
el: { |
||||
type: "bi.date_time_combo", |
||||
value: { |
||||
year: 2018, |
||||
month: 9, |
||||
day: 28, |
||||
hour: 13, |
||||
minute: 31, |
||||
second: 1 |
||||
} |
||||
} |
||||
}] |
||||
}); |
||||
|
||||
var comboTree = BI.createWidget({ |
||||
type: "bi.vertical", |
||||
items: [ |
||||
{ |
||||
type: "bi.tree_value_chooser_combo", |
||||
width: 300, |
||||
itemsCreator: function(op, callback) { |
||||
callback([ |
||||
{ |
||||
id: 1, |
||||
text: "第1项", |
||||
value: "1" |
||||
}, |
||||
{ |
||||
id: 2, |
||||
text: "第2项", |
||||
value: "2" |
||||
}, |
||||
{ |
||||
id: 3, |
||||
text: "第3项", |
||||
value: "3", |
||||
open: true |
||||
}, |
||||
{ |
||||
id: 11, |
||||
pId: 1, |
||||
text: "子项1", |
||||
value: "11" |
||||
}, |
||||
{ |
||||
id: 12, |
||||
pId: 1, |
||||
text: "子项2", |
||||
value: "12" |
||||
}, |
||||
{ |
||||
id: 13, |
||||
pId: 1, |
||||
text: "子项3", |
||||
value: "13" |
||||
}, |
||||
{ |
||||
id: 31, |
||||
pId: 3, |
||||
text: "子项1", |
||||
value: "31" |
||||
}, |
||||
{ |
||||
id: 32, |
||||
pId: 3, |
||||
text: "子项2", |
||||
value: "32" |
||||
}, |
||||
{ |
||||
id: 33, |
||||
pId: 3, |
||||
text: "子项3", |
||||
value: "33" |
||||
} |
||||
]); |
||||
} |
||||
} |
||||
] |
||||
}); |
||||
|
||||
var color = BI.createWidget({ |
||||
type: "bi.left", |
||||
items: [{ |
||||
type: "bi.simple_color_chooser", |
||||
width: 24, |
||||
height: 24 |
||||
}, { |
||||
el: { |
||||
type: "bi.color_chooser", |
||||
width: 230, |
||||
height: 24 |
||||
}, |
||||
lgap: 10 |
||||
}] |
||||
}); |
||||
|
||||
var Slider = BI.inherit(BI.Widget, { |
||||
props: { |
||||
width: 300, |
||||
height: 50, |
||||
min: 0, |
||||
max: 100 |
||||
}, |
||||
|
||||
mounted: function() { |
||||
var o = this.options; |
||||
this.singleSliderInterval.setMinAndMax({ |
||||
min: o.min, |
||||
max: o.max |
||||
}); |
||||
|
||||
this.singleSliderInterval.setValue({ |
||||
min: 10, |
||||
max: 80 |
||||
}); |
||||
this.singleSliderInterval.populate(); |
||||
}, |
||||
|
||||
render: function() { |
||||
var self = this, |
||||
o = this.options; |
||||
return { |
||||
type: "bi.vertical", |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
type: "bi.interval_slider", |
||||
digit: 0, |
||||
width: o.width, |
||||
height: o.height, |
||||
ref: function(_ref) { |
||||
self.singleSliderInterval = _ref; |
||||
} |
||||
} |
||||
] |
||||
}; |
||||
} |
||||
}); |
||||
BI.shortcut("demo.slider_interval", Slider); |
||||
var slider = BI.createWidget({ |
||||
type: "demo.slider_interval" |
||||
}); |
||||
|
||||
BI.createWidget({ |
||||
type:"bi.absolute", |
||||
element: "body", |
||||
items: [{ |
||||
el: combo1, |
||||
left: 100, |
||||
top: 100 |
||||
}, { |
||||
el : date, |
||||
left: 100, |
||||
top : 150 |
||||
}, { |
||||
el : comboTree, |
||||
left : 100, |
||||
top : 200 |
||||
}, { |
||||
el : color, |
||||
left : 100, |
||||
top : 250 |
||||
}, { |
||||
el : slider, |
||||
left : 400, |
||||
top : 100 |
||||
}] |
||||
}); |
||||
}); |
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Title</title> |
||||
##style## |
||||
##script## |
||||
</head> |
||||
<body> |
||||
</body> |
||||
|
||||
</html> |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-07 |
||||
*/ |
||||
public class FineUIDemo { |
||||
|
||||
public static void main(String... args) { |
||||
final JFrame frame = new JFrame(); |
||||
frame.setSize(1200, 800); |
||||
JPanel contentPane = (JPanel) frame.getContentPane(); |
||||
// 是否需要开启调试窗口
|
||||
DesignerEnvManager.getEnvManager().setOpenDebug(true); |
||||
|
||||
final ModernUIPane<ModernUIPaneTest.Model> pane = new ModernUIPane.Builder<ModernUIPaneTest.Model>() |
||||
.withComponent(StartComponent.KEY).build(); |
||||
contentPane.add(pane, BorderLayout.CENTER); |
||||
frame.setVisible(true); |
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); |
||||
} |
||||
} |
@ -0,0 +1,75 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-05 |
||||
*/ |
||||
public class ModernUIPaneTest { |
||||
|
||||
public static void main(String... args) { |
||||
final JFrame frame = new JFrame(); |
||||
frame.setSize(1200, 800); |
||||
JPanel contentPane = (JPanel) frame.getContentPane(); |
||||
// 是否需要开启调试窗口
|
||||
DesignerEnvManager.getEnvManager().setOpenDebug(true); |
||||
final ModernUIPane<Model> pane = new ModernUIPane.Builder<Model>() |
||||
.withEMB("/com/fr/design/ui/demo.html").namespace("Pool").build(); |
||||
contentPane.add(pane, BorderLayout.CENTER); |
||||
|
||||
Model model = new Model(); |
||||
model.setAge(20); |
||||
model.setName("Pick"); |
||||
pane.populate(model); |
||||
|
||||
JPanel panel = new JPanel(new FlowLayout()); |
||||
contentPane.add(panel, BorderLayout.SOUTH); |
||||
JButton button = new JButton("点击我可以看到Swing的弹框,输出填写的信息"); |
||||
panel.add(button); |
||||
button.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
Model returnValue = pane.update(); |
||||
if (returnValue != null) { |
||||
JOptionPane.showMessageDialog(frame, String.format("姓名为:%s,年龄为:%d", returnValue.getName(), returnValue.getAge())); |
||||
} |
||||
} |
||||
}); |
||||
frame.setVisible(true); |
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); |
||||
} |
||||
|
||||
public static class Model { |
||||
private String name; |
||||
private int age; |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public int getAge() { |
||||
return age; |
||||
} |
||||
|
||||
public void setAge(int age) { |
||||
this.age = age; |
||||
} |
||||
|
||||
public void print(String message) { |
||||
System.out.println(message); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.fr.design.ui; |
||||
|
||||
import com.fr.web.struct.AssembleComponent; |
||||
import com.fr.web.struct.Atom; |
||||
import com.fr.web.struct.browser.RequestClient; |
||||
import com.fr.web.struct.category.ScriptPath; |
||||
import com.fr.web.struct.impl.FineUI; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-08 |
||||
*/ |
||||
public class StartComponent extends AssembleComponent { |
||||
|
||||
public static final StartComponent KEY = new StartComponent(); |
||||
|
||||
private StartComponent() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public ScriptPath script(RequestClient req) { |
||||
return ScriptPath.build("/com/fr/design/ui/script/start.js"); |
||||
} |
||||
|
||||
@Override |
||||
public Atom[] refer() { |
||||
return new Atom[] {FineUI.KEY}; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Title</title> |
||||
<script type="text/javascript"> |
||||
Pool.update = function () { |
||||
Pool.data.setAge(parseInt(document.getElementById("age").value)); |
||||
Pool.data.setName(document.getElementById("name").value); |
||||
return Pool.data; |
||||
}; |
||||
</script> |
||||
</head> |
||||
<body> |
||||
<div>测试页面,请点击最下面的按钮</div> |
||||
<input id="name" type="text" placeholder="请输入名字"/> |
||||
<input id="age" type="number" placeholder="请输入年龄"/> |
||||
<img src="emb:/com/fr/design/images/splash_10.gif"> |
||||
</body> |
||||
</html> |
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Title</title> |
||||
<link rel="stylesheet" href="emb:/com/fr/web/ui/fineui.min.css"/> |
||||
<script src="emb:/com/fr/web/ui/fineui.min.js"/> |
||||
</head> |
||||
<body> |
||||
</body> |
||||
</html> |
@ -0,0 +1,57 @@
|
||||
window.addEventListener("load", function (ev) { |
||||
var combo1 = BI.createWidget({ |
||||
type: "bi.vertical", |
||||
items: [ |
||||
{ |
||||
type: "bi.text_value_combo", |
||||
text: "选项1", |
||||
width: 300, |
||||
items: [ |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项1", |
||||
value: 1 |
||||
}, |
||||
text: "选项1", |
||||
value: 1, |
||||
lgap: 10 |
||||
}, |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项2", |
||||
value: 2 |
||||
}, |
||||
lgap: 10, |
||||
text: "选项2", |
||||
value: 2 |
||||
}, |
||||
{ |
||||
el: { |
||||
type: "bi.single_select_radio_item", |
||||
width: 290, |
||||
text: "选项3", |
||||
value: 3 |
||||
}, |
||||
lgap: 10, |
||||
text: "选项3", |
||||
value: 3 |
||||
} |
||||
] |
||||
} |
||||
] |
||||
}); |
||||
|
||||
BI.createWidget({ |
||||
type:"bi.absolute", |
||||
element: "body", |
||||
items: [{ |
||||
el: combo1, |
||||
left: 100, |
||||
top: 100 |
||||
}] |
||||
}); |
||||
}); |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue