最近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 调用控件开发的更多相关文章

  1. JavaScript日历控件开发 C# 读取 appconfig文件配置数据库连接字符串,和配置文件 List<T>.ForEach 调用异步方法的意外 ef 增加或者更新的习惯思维 asp.net core导入excel 一个二级联动

    JavaScript日历控件开发   概述 在开篇之前,先附上日历的代码地址和演示地址,代码是本文要分析的代码,演示效果是本文要实现的效果代码地址:https://github.com/aspwebc ...

  2. 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

    Dixon 原文  用ArcGIS Engine.VS .NET和Windows控件开发GIS应用     此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署 ...

  3. ActiveX控件开发

    VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程 开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是 ...

  4. kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件

    该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...

  5. C# 跨线程调用控件

    在C# 的应用程序开发中, 我们经常要把UI线程和工作线程分开,防止界面停止响应.  同时我们又需要在工作线程中更新UI界面上的控件, 下面介绍几种常用的方法 阅读目录 线程间操作无效 第一种办法:禁 ...

  6. ASP.NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  7. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...

  8. C# Winform开发以及控件开发的需要注意的,被人问怕了,都是基础常识

    我是搞控件开发的,经常被人问,所以把一些问题记录了下来!如果有人再问,直接把地址丢给他看. 一. 经常会有人抱怨Winform界面闪烁,下面有几个方法可以尽可能的避免出现闪烁 1.控件的使用尽量以纯色 ...

  9. 最全的基于MFC的ActiveX控件开发教程

    浏览器插件之ActiveX开发(一) 一般的Web应用对于浏览器插件能不使用的建议尽量不使用,因为其涉及到安全问题以及影响用户安装(或自动下载注册安装)体验问题.在有特殊需求(如涉及数据安全的金融业务 ...

随机推荐

  1. GDAL集成GEOS

    因为要用到缓冲区分析,在使用Buffer的时候提示:ERROR 6: GEOS support not enabled,查了一下资料需要集成GEOS库.因为GDLA默认编译是没有集成GEOS库的. 现 ...

  2. 迭代器使用过程中为什么抛出ConcurrentModificationException

    出现的场景:在迭代器对集合进行遍历的同时,集合本身进行变更操作(add(), remove(), set()). 当正常调用时: import java.util.ArrayList; import ...

  3. echarts更改轴线颜色

    xAxis : [ { type : 'category', data : ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月 ...

  4. 如何编写Robot Framework测试用例1---(基本格式篇)

    引子 我们使用符合Robot Framework规范的一种表格语法来编写测试用例.用例一般会是下面这个样子 这样的表格存储到一个文件中,就是一组测试用例.RF支持多种格式,如HTML,TSV,纯文本等 ...

  5. docker安装的gitlab的备份与恢复

    1.对docker容器安装gitlab备份 1) 查看容器id docker ps 2) 将容器备份成镜像文件 docker commit -a 'James' -m 'gitlab_backup' ...

  6. 有关lightning页面中页面加载时间计数器颜色分别表示的时间范围的问题

    之所以要转载这篇文章的原因是,有一次调查lightning中右上角有个页面加载时间控件颜色分别代表多少时间范围的问题,搜索查阅了很多资料和文件,最终在一篇有关Lighthouse前端性能优化测试工具的 ...

  7. cocoa pods最新安装说明和使用方法

    最新版 CocoaPods 的安装流程 1.移除现有Ruby默认源 $gem sources --remove https://rubygems.org/ 2.使用新的源 $gem sources - ...

  8. 8.JavaSE之变量、常量、作用域

    变量variable: 变量是什么:就是内存中开辟的可以变化的量! Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型,作用域   ...

  9. Java入门 - 语言基础 - 08.运算符

    原文地址:http://www.work100.net/training/java-operator.html 更多教程:光束云 - 免费课程 运算符 序号 文内章节 视频 1 概述 2 算术运算符 ...

  10. python读取json文件

    比如下图json数据,场景需要读取出wxid这项数据,然后传给后面的函数去使用 具体的脚本为 import json f =open('d:\\1024.json',encoding='utf-8') ...