需要jar包
DJNativeSwing-SWT.jar,DJNativeSwing.jar,
org.eclipse.swt.win32.win32.x86_64_3.106.2.v20171129-0543.jar,MozillaInterfaces-1.8.1.3.jar
其中DJNativeSwing地址
github:https://github.com/Chrriis/DJ-Native-Swing
http://mvnrepository.com/tags/maven中也可以搜索到
运行环境
tomcat中间件
说明
本人是使用java的定时任务定时把一个列表对象中的属性url(即h5)进行循环,然后把h5转成图片
遇到问题
1,h5中有ajax请求,使用JWebBrowser的getLoadingProgress方法判断网页的加载状态,进而输出图片时,图片的内容有误
解决思路ajax请求结束后定会改变视图,可以往JWebBrowser中注入js代码,获取视图的状态,我这里是通过获取jiaz加载条的display属性来判断ajax是否加载完整,具体是java获取js代码返回的值进行递归判断,如果ajax不改变视图,则无需担心。
2,循环列表对象时,报错,能力有限,真正的原因我也不清楚
解决办法是把循环操作放在NativeInterface.open()之后,NativeInterface.runEventPump()之前
如果每次循环都进行open和runEventPump操作会报错的,好像是open和runEventPump是单线程的
别人的答案(http://topic.csdn.net/u/20110113/11/da8eca94-add0-490d-ab64-f76bd8ba46fa.html):
因为NativeInterface.open();和NativeInterface.runEventPump();是静态方法,
猜想只有在程序的开始和结束调用这两个方法,不应该在循环里调用这两个方法
3,如果h5页面大小不一致,可以通过jWebBrowser.setBounds(0, 0, 470, 340)来进行修改,这是jWebBrowser的尺寸,Jframe的chix尺寸要比jWebBrowser的尺寸略多一点
代码
1,列表对象循环的代码
public static void initMainView2(List list) {
UIUtils.setPreferredLookAndFeel();
NativeInterface.open();
ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
for (PadFinanceIndexMenu padFinanceIndexMenu : list) {
final String classify = padFinanceIndexMenu.getClassify();
final String type = padFinanceIndexMenu.getType();
final String url = padFinanceIndexMenu.getUrl();
final String id = padFinanceIndexMenu.getId();
cacheThreadPool.execute(new Runnable() {
@Override
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
if("市值管理".equals(classify)){
MainViewSZGL frame = new MainViewSZGL(url, id);
frame.setVisible(true);
} else if("组织人事".equals(classify)){
MainViewZZRS frame = new MainViewZZRS(url, id);
frame.setVisible(true);
} else {
if(type.equals("1")){
MainViewCHH1 frame = new MainViewCHH1(url, id);
frame.setVisible(true);
} else if(type.equals("2")){
MainViewCHH2 frame = new MainViewCHH2(url, id);
frame.setVisible(true);
} else if(type.equals("3")){
MainViewCHH3 frame = new MainViewCHH3(url, id);
frame.setVisible(true);
}
}
} catch (Exception e) {}
}
});
}
});
try {Thread.sleep(10000);} catch (InterruptedException e) {}
}
NativeInterface.runEventPump();
}
注释:MainView**对象是不同的JFrame类,因为我这边的h5尺寸很多都不一样;其中cacheThreadPool.execute不知道是不是 多余的,对多线程不熟悉;Thread.sleep(10000)是当前JFrame从加载h5到转图片成功需要的时间预估值,如果不加,会瞬间出现N个JFrame,你懂的;
2,JFrame类代码,只展示一个,即MainViewCHH1类
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import chrriis.dj.nativeswing.swtimpl.NativeComponent;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserEvent;
import com.aliyun.oss.utils.OSSUploadUtils;
import com.thinkgem.jeesite.common.config.Global;
public class MainViewCHH1 extends JFrame{
private JPanel contentPane;
final static public String LS = System.getProperty("line.separator", "/n"); // 行分隔符
final static public String FS = System.getProperty("file.separator", "//"); // 文件分割符
static StringBuffer jsDimension = new StringBuffer(); // 以javascript脚本获得网页全屏后大小
static StringBuffer jsDimension2 = new StringBuffer(); // 以javascript脚本获得网页全屏后大小
private static final long serialVersionUID = 4859858380825456963L;
static {
jsDimension = new StringBuffer();
jsDimension.append("var width = 0;").append(LS);
jsDimension.append("var height = 0;").append(LS);
jsDimension.append("if(document.documentElement) {").append(LS);
jsDimension.append(" width = Math.max(width, document.documentElement.scrollWidth);").append(LS);
jsDimension.append(" height = Math.max(height, document.documentElement.scrollHeight);").append(LS);
jsDimension.append("}").append(LS);
jsDimension.append("if(self.innerWidth) {").append(LS);
jsDimension.append(" width = Math.max(width, self.innerWidth);").append(LS);
jsDimension.append(" height = Math.max(height, self.innerHeight);").append(LS);
jsDimension.append("}").append(LS);
jsDimension.append("if(document.body.scrollWidth) {").append(LS);
jsDimension.append(" width = Math.max(width, document.body.scrollWidth);").append(LS);
jsDimension.append(" height = Math.max(height, document.body.scrollHeight);").append(LS);
jsDimension.append("}").append(LS);
jsDimension.append("return width + ':' + height;");
jsDimension2 = new StringBuffer();
jsDimension2.append("var loadingSpinner = document.getElementById('loadingSpinner');").append(LS);
jsDimension2.append("var computedStyle = document.defaultView.getComputedStyle(loadingSpinner, null);").append(LS);
jsDimension2.append("return computedStyle.display;");
}
private boolean display(JWebBrowser jWebBrowser){
String display = (String) jWebBrowser.executeJavascriptWithResult(jsDimension2.toString());
if(display.equals("block")) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
display(jWebBrowser);
}
return true;
}
public MainViewCHH1(String url, final String id) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(200, 100, 960, 380);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JWebBrowser jWebBrowser = new JWebBrowser();
jWebBrowser.setBounds(0, 0, 940, 340);
jWebBrowser.navigate(url);
jWebBrowser.setButtonBarVisible(false);
jWebBrowser.setMenuBarVisible(false);
jWebBrowser.setBarsVisible(false);
jWebBrowser.setStatusBarVisible(false);
jWebBrowser.addWebBrowserListener(new WebBrowserAdapter() {
@Override
public void loadingProgressChanged(WebBrowserEvent e) {
if (e.getWebBrowser().getLoadingProgress() == 100) {
if(display(jWebBrowser)) {
NativeComponent nativeComponent = jWebBrowser.getNativeComponent();
nativeComponent.setBackground(Color.blue);
Dimension originalSize = nativeComponent.getSize();
BufferedImage image = new BufferedImage(originalSize.width, originalSize.height, BufferedImage.TYPE_INT_RGB);
nativeComponent.paintComponent(image);
nativeComponent.setSize(originalSize);
try {
String path = Global.getConfig("window.path") + "/finance_chh/" + id + ".png";
ImageIO.write(image, "png", new File(path));
OSSUploadUtils.uploadByInputStream(new FileInputStream(new File(path)), "ggkb/cwdhsy/" + id + ".png");
} catch (IOException ex) {
ex.printStackTrace();
}
dispose();
}
}
}
});
contentPane.add(jWebBrowser);
}
}
注释:其中80%的代码是前人的,一小部分是自己的;jsDimension2 变量是需要注入的js代码,用于获取id为loadingSpinner的元素的css的display值;display方法是递归操作,判断display的值是否不为block;dispose方法用于关闭JFrame