JAVA 调用控件开发
最近homoloCzh有个小伙伴接到一个需求说是把一个c# 写的具备扫描、调阅等功能 winfrom 影像控件嵌入到java Swing当中,让小伙伴很苦恼啊,从年前一直研究到年后,期间用了很多种方法。
jcob、comfyj、jawin、jni、jna等等很多方式。(有的是直接调用dll的方法,有的是间接调用 用C包一个壳子,然后再用java调用,甚至直接调用exe 都搞出来啦) 显然当前的需求是要讲winfrom嵌入到swing里面涉及到跨进
程间调用和嵌入式开发,所以还是比较有难度的。小伙伴网上找了很久,也没找到可供参考的资料。最后作罢。
我呢也是出于好奇,虽然现在做java的大部分都是注重于后台服务。服务器性能方面的,很少用java SWING 做CS架构的控件,但是因为和小伙伴聊天知道了这个事情,然后去网上看了看,类似需求的帖子确实少之又少,几乎没有人这么做过, 目前不建议这么做不知道以后会不会,因为从1.4之后 java jdk 就没有更新过 swing这块了,转攻Web这一块了。但是碰巧在和度娘聊天的时候,发现一个帖子说是java SWT中可以显示word文档,然后心想应该有门抱着试一试的心态,没想到真的成功了 哈哈。话不多说 贴上过程和代码
原理: 用SWT显示控件的视频框,然后将SWT放在swing界面上,然后通过SWT调用封装的dll方法实现交互调用
前提: 用到的OCX或dll必须在系统注册表中已经注册,安装控件安装包或者通过regsvr32 xxxx.dll命令
1.首先根据JVM位数(32位或者64位) org.eclipse.swt.xxx.jar 导入对应的到工程里面 如果不知道查看JVM的位数就自行百度,有很多方式的
这里面教大家一种 cmd执行 java -version 即可
2. 将要调用的ocx放入系统环境变量目录下,或jdk的bin目录下,或者自己加载
2.1下面就是界面的实现类的代码
*
* 操作步骤:
* 1. 安装人脸采集控件
* 2. 确认安装的dll或ocx已经在注册表注册 regsvr32 xxx.ocx 或 regsvr 32 xxx.dll
* 3. 运行本软件,确认JVM32或64,32位请加载org.eclipse.swt.x86.jar,64位请加载org.eclipse.swt.x64.jar
* 4. 64位JDK加载64位动态库,32位JDK加载32位动态库
* 5. 直接执行main函数运行人脸采集程序
*
* @author HOMOLOCzh
* @date 20200220
*/
public class JavaSwingDoFaceWinfrom extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel jPanelLogo;
private JPanel jPanelBtn;
private JPanel jPanelCapture;
private JButton jButtonCheck;
private JButton jButtonOpenDev;
private JButton jButtonCloseDev;
private JButton jButtonAutoCap;
private JButton jButtonManualCap;
private JTextArea jTextAreaParam;
private JTextArea jTextAreaResult;
private JScrollPane jscrollPaneParam;
private JScrollPane jscrollPaneResult;
private JLabel jLabelImg;
private static JavadoOcx controlL = null;
private static JavadoOcx controlR = null;
public JavaSwingDoFaceWinfrom()
{
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
if(controlL != null)
{
controlL.closeDevice();
}
}
});
}
/**
* 人脸采集控件的SWT图形控件
*/
private static Canvas swtCanvas = new Canvas() {
private static final long serialVersionUID = 1L;
@Override
public void addNotify() {
super.addNotify();
synchronized (getTreeLock()) {
// 另起线程,以免阻塞
new Thread() {
public void run() {
String tesoClsid = AppConfig.getConfig(AppConfig.TESO_PROGID);
// swt的初始化
Display display = new Display();
Shell _shell = SWT_AWT.new_Shell(display, swtCanvas);
_shell.setLayout(new org.eclipse.swt.layout.RowLayout());
// 加载第一个ocx窗口
OleFrame _frameL = new OleFrame(_shell, SWT.NONE);
// TesoSeeu.CmbcSee : 注册表中已注册的控件PROGID,也就是name
OleControlSite _siteL = new OleControlSite(_frameL, SWT.NONE, tesoClsid);
_siteL.doVerb(OLE.OLEIVERB_SHOW);
_siteL.setSize(400, 300);
// 加载第二个ocx窗口
OleFrame _frameR = new OleFrame(_shell, SWT.NONE);
OleControlSite _siteR = new OleControlSite(_frameR, SWT.NONE, tesoClsid);
_siteR.doVerb(OLE.OLEIVERB_SHOW);
_siteR.setSize(400, 300);
OleAutomation _autoL = new OleAutomation(_siteL);
controlL = new JavadoOcx(_autoL);
OleAutomation _autoR = new OleAutomation(_siteR);
controlR = new JavadoOcx(_autoR);
swtCanvas.setSize(820, 300);
_shell.pack();
while (!_shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}.start();
}
}
};
private void doAble(boolean flag)
{
jButtonCheck.setEnabled(flag);
jButtonOpenDev.setEnabled(flag);
jButtonCloseDev.setEnabled(flag);
jButtonAutoCap.setEnabled(flag);
jButtonManualCap.setEnabled(flag);
}
private void initGUI() {
try {
{
this.setIconImage(new ImageIcon(getClass().getClassLoader().getResource("images/teso_logo.png")).getImage());
setLayout(null);
{
jPanelLogo = new JPanel();
jPanelLogo.setBounds(0, 0, 800, 52);
jPanelLogo.setBackground(new java.awt.Color(255, 255, 200));
jPanelLogo.setLayout(new BorderLayout());
jLabelImg = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("images/techshino.png"))) ;
jPanelLogo.add(jLabelImg, BorderLayout.WEST);
getContentPane().add(jPanelLogo);
}
{
jPanelBtn = new JPanel();
jPanelBtn.setBounds(0, 500, 800, 50);
jPanelBtn.setLayout(new GridLayout(1, 5));
getContentPane().add(jPanelBtn);
}
{
jPanelCapture = new JPanel();
jPanelCapture.setLayout(new GridLayout());
jPanelCapture.setBounds(0, 50, 800, 300);
jPanelCapture.add(swtCanvas);
getContentPane().add(jPanelCapture);
}
{
jTextAreaParam = new JTextArea(TesoFaceConstant.getParam(), 10, 15);
jTextAreaParam.setLineWrap(true);
jPanelBtn.add(jTextAreaParam);
jscrollPaneParam = new JScrollPane(jTextAreaParam);
jscrollPaneParam.setBounds(0, 350, 400, 150);
getContentPane().add(jscrollPaneParam);
}
{
jTextAreaResult = new JTextArea(10, 15);
jTextAreaResult.setLineWrap(true);
jPanelBtn.add(jTextAreaResult);
jscrollPaneResult = new JScrollPane(jTextAreaResult);
jscrollPaneResult.setBounds(400, 350, 400, 150);
getContentPane().add(jscrollPaneResult);
}
{
jButtonCheck = new JButton();
jPanelBtn.add(jButtonCheck);
jButtonCheck.setText("检测摄像头状态");
jButtonCheck.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAble(false);
// 线程打开摄像头,防止卡死
new Thread() {
public void run() {
jTextAreaResult.setText("");
String retXml = controlL.checkDevice(jTextAreaParam.getText());
jTextAreaResult.setText(retXml);
doAble(true);
}
}.start();
}
});
}
{
jButtonOpenDev = new JButton();
jPanelBtn.add(jButtonOpenDev);
jButtonOpenDev.setText("打开摄像头");
jButtonOpenDev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAble(false);
// 线程打开摄像头,防止卡死
new Thread() {
public void run() {
jTextAreaResult.setText("");
String retXml = controlL.openDevice(jTextAreaParam.getText());
jTextAreaResult.setText(retXml);
doAble(true);
}
}.start();
}
});
}
{
jButtonCloseDev = new JButton();
jPanelBtn.add(jButtonCloseDev);
jButtonCloseDev.setText("关闭摄像头");
jButtonCloseDev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jTextAreaResult.setText("");
String retXml = controlL.closeDevice();
jTextAreaResult.setText(retXml);
}
});
}
{
jButtonManualCap = new JButton();
jPanelBtn.add(jButtonManualCap);
jButtonManualCap.setText("手动抓拍人脸");
jButtonManualCap.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jTextAreaResult.setText("");
String retXml = controlL.captureFaceManual(jTextAreaParam.getText(), "123456789012345678", "12345678901234567890123456789012");
controlR.showImg("123456789012345678", "12345678901234567890123456789012", retXml);
jTextAreaResult.setText(retXml);
}
});
}
{
jButtonAutoCap = new JButton();
jPanelBtn.add(jButtonAutoCap);
jButtonAutoCap.setText("自动抓拍人脸");
jButtonAutoCap.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAble(false);
// 线程打开摄像头,防止卡死
new Thread() {
public void run() {
jTextAreaResult.setText("");
String retXml = controlL.captureFaceAuto(jTextAreaParam.getText(), "123456789012345678", "12345678901234567890123456789012");
controlR.showImg("123456789012345678", "12345678901234567890123456789012", retXml);
jTextAreaResult.setText(retXml);
doAble(true);
}
}.start();
}
});
}
}
this.setSize(806, 580);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JavaSwingDoFaceWinfrom frame = new JavaSwingDoFaceWinfrom();
frame.initGUI();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);
}
}
2.2下面是就是调用ocx中方法的实现 仅供参考
package javaDoWinform;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.Variant;
public class JavadoOcx{
private OleAutomation oleAutomation;
public JavadoOcx(OleAutomation oleAutomation)
{
this.oleAutomation = oleAutomation;
}
/**
* 获取ole中的参数编号
* @param name 参数名
* @return 参数序号
*/
private int getID(String name) {
try {
int[] ids = oleAutomation.getIDsOfNames(new String[] { name });
if(ids == null)
{
return -1;
}
if (ids.length >= 0)
return ids[0];
} catch (RuntimeException e) {
e.printStackTrace();
}
return -1;
}
/**
* 执行没有参数的方法
* @param methodName 方法名
* @return 结果集
*/
private Variant execute(String methodName) {
return execute(methodName, null);
}
/**
* 执行有参数的方法
* @param methodName 方法名
* @param args 参数集合
* @return 结果集
*/
private Variant execute(String methodName, Variant[] args) {
int mid = getID(methodName);
if (mid < 0) {
return null;
}
Variant rtnv = null;
if (args == null) {
rtnv = oleAutomation.invoke(mid);
} else {
rtnv = oleAutomation.invoke(mid, args);
}
return rtnv;
}
/**
* 检测摄像头状态
* @param devParam 控制人脸采集的参数xml
* @return 检测设备的结果,xml
*/
public String checkDevice(String devParam)
{
Variant var[] = new Variant[1];
var[0] = new Variant(devParam);
return execute(TesoFaceConstant.TESO_CHECKDEVICE, var).getString();
}
/**
* 打开摄像头
* @param devParam 控制人脸采集的参数xml
* @return 打开设备的结果,xml
*/
public String openDevice(String devParam) {
Variant var[] = new Variant[1];
var[0] = new Variant(devParam);
return execute(TesoFaceConstant.TESO_OPENDEVICE, var).getString();
}
/**
* 关闭摄像头
* @return 关闭设备的结果,xml
*/
public String closeDevice() {
return execute(TesoFaceConstant.TESO_CLOSEDEVICE).getString();
}
/**
* 在控件上显示图像
* @param cardNo 身份证号
* @param serialNo 流水号
* @param retXml 采集时captureFaceAuto或captureFaceManual返回的xml
* @return 显示图像的结果,xml
*/
public String showImg(String cardNo, String serialNo, String retXml)
{
Variant var[] = new Variant[3];
var[0] = new Variant(cardNo);
var[1] = new Variant(serialNo);
var[2] = new Variant(retXml);
return execute(TesoFaceConstant.TESO_SHOWIMGA, var).getString();
}
/**
* 自动抓拍人脸
* @param devParam 人脸采集参数,xml
* @param cardNo 身份证号
* @param serialNo 流水号
* @return 自动抓拍的结果,xml
*/
public String captureFaceAuto(String devParam, String cardNo, String serialNo)
{
Variant var[] = new Variant[3];
var[0] = new Variant(devParam);
var[1] = new Variant(cardNo);
var[2] = new Variant(serialNo);
Variant ret = execute(TesoFaceConstant.TESO_GETFACEB64A, var);
if(ret == null)
{
return "";
}
return ret.getString();
}
/**
* 手动抓拍人脸
* @param devParam 人脸采集参数,xml
* @param cardNo 身份证号
* @param serialNo 流水号
* @return 手动抓拍的结果,xml
*/
public String captureFaceManual(String devParam, String cardNo, String serialNo)
{
Variant var[] = new Variant[3];
var[0] = new Variant(devParam);
var[1] = new Variant(cardNo);
var[2] = new Variant(serialNo);
Variant ret = execute(TesoFaceConstant.TESO_GETFACEB64B, var);
if(ret == null)
{
return "";
}
return ret.getString();
}
}
5. 由于公司机密,对应的OCX没有上传, 大家根据思路调用自己的OCX或其他控件即可,望见谅!
JAVA 调用控件开发的更多相关文章
- JavaScript日历控件开发 C# 读取 appconfig文件配置数据库连接字符串,和配置文件 List<T>.ForEach 调用异步方法的意外 ef 增加或者更新的习惯思维 asp.net core导入excel 一个二级联动
JavaScript日历控件开发 概述 在开篇之前,先附上日历的代码地址和演示地址,代码是本文要分析的代码,演示效果是本文要实现的效果代码地址:https://github.com/aspwebc ...
- 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用
Dixon 原文 用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署 ...
- ActiveX控件开发
VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程 开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是 ...
- kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件
该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...
- C# 跨线程调用控件
在C# 的应用程序开发中, 我们经常要把UI线程和工作线程分开,防止界面停止响应. 同时我们又需要在工作线程中更新UI界面上的控件, 下面介绍几种常用的方法 阅读目录 线程间操作无效 第一种办法:禁 ...
- ASP.NET自定义控件组件开发 第五章 模板控件开发
原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...
- C# Winform开发以及控件开发的需要注意的,被人问怕了,都是基础常识
我是搞控件开发的,经常被人问,所以把一些问题记录了下来!如果有人再问,直接把地址丢给他看. 一. 经常会有人抱怨Winform界面闪烁,下面有几个方法可以尽可能的避免出现闪烁 1.控件的使用尽量以纯色 ...
- 最全的基于MFC的ActiveX控件开发教程
浏览器插件之ActiveX开发(一) 一般的Web应用对于浏览器插件能不使用的建议尽量不使用,因为其涉及到安全问题以及影响用户安装(或自动下载注册安装)体验问题.在有特殊需求(如涉及数据安全的金融业务 ...
随机推荐
- mqtt实现跨平台跨应用通讯
介绍 最近物联网应用一直很火,也打算做一些这方面的尝试,就边学边做在家花了2天时间做了一个简单demo,功能很简单,使用emq x 作为mqtt broker,用python写了一个定时抓取主机CPU ...
- 深夜话题boot2docker还有那些隐藏MENU
马克思的博士论文:自由意识的集中表达 --字体我设为5(18pt),你们懂的 总有人埋汰,终于我想起一个负负得正的话题 为什么放在深夜,因为希望看到的人越少越好,深夜是时差党的乐园 本篇作为之前几篇围 ...
- 如何设计一个优雅的RESTFUL的接口
show me the code and talk to me,做的出来更要说的明白 我是布尔bl,你的支持是我分享的动力! 一 .引入 设计接口是我们开发人员的日常操作.当我们把接口交给前端人员时, ...
- SpringCloud之Feign(五)
Feign简介 Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Fei ...
- “Your build settings specify a provisioning profile with the UUID “”, however, no such provisioning profile was found”
解决方法: 终端命令行输入下面语句,删除所有的Profilescd ~/Library/MobileDevice/Provisioning\ Profiles/rm *.mobileprovision
- 【实战】使用 Kettle 工具将 mysql 数据增量导入到 MongoDB 中
最近有一个将 mysql 数据导入到 MongoDB 中的需求,打算使用 Kettle 工具实现.本文章记录了数据导入从0到1的过程,最终实现了每秒钟快速导入约 1200 条数据.一起来看吧~ 一.K ...
- Installing PyCharm
Installing PyCharm| # ...
- 建立MVC的依赖项注入 Setting up MVC Dependency Injection 精通ASP-NET-MVC-5-弗瑞曼
The result of the three steps I showed you in the previous section is that the knowledge about the i ...
- NOI2.5 1817:城堡问题
描述 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # ...
- C语言—期末小黄衫获奖感言
小黄衫获奖感言 一,感谢环节 非常感谢邹欣,周筠老师给提供的小黄衫,我非常荣幸的能够获得这个奖项,我感到无比自豪.感谢两位老师对教学事业的大力支持,对我们学生的亲切关怀.同时感谢我的C语言老师彭琛(琛 ...