最近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. Spring Boot2 系列教程 (八) | 配置日志

    前言 如题,今天介绍 springboot 默认日志的配置. 默认日志 Logback 默认情况下,Spring Boot 用 Logback 来记录日志,并用 INFO 级别输出到控制台.如果你在平 ...

  2. 单调队列优化 dp

    The only difference between easy and hard versions is the constraints. Vova likes pictures with kitt ...

  3. 线段树 or 并查集 (多一个时间截点)

    There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...

  4. Jenkins Job构建

    Jenkins job介绍 ​ Jenkins Freestyle与Pipeline Job区别 ​ ​ Jenkins Job构建配置 一 .环境准备 1.配置Jenkins server本地Git ...

  5. java 类初识

    一.定义 成员变量 成员方法 注意: 1.成员变量有默认值,是全局变量 2.成员方法,不需要使用static 3.成员变量的默认值 整型 0 浮点型 0.0 引用数据类型 null 二.使用 1.导包 ...

  6. 【红外DDE算法】数字细节增强算法的缘由与效果(我对FLIR文档详解)

    [红外DDE算法]数字细节增强算法的缘由与效果(我对FLIR文档详解) 1. 为什么红外系统中图像大多是14bit(甚至更高)?一个红外系统的性能经常以其探测的范围来区别,以及其对最小等效温差指标.首 ...

  7. ELK实战-elasticsearch安装

    操作系统: centos版本 7.4 防火墙 关闭 selinux 关闭 elasticsearch版本 6.3.2 java版本 1.8 server1 192.168.10.126 server2 ...

  8. 使用requests模块的网络编程

    python操作网络,也就是打开一个网站,或者请求一个http接口,本篇是介绍使用request模块的使用方式. 在使用requests模块之前需要先安装,在cmd中输入:pip install re ...

  9. 剑指offer--二维数组中查找

    剑指offer--二维数组中查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序, 每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组 ...

  10. Spring博客专栏

    1. IOC和DI的理解 2. IOC的实现原理-反射与工厂模式 3. Spring进阶之路 4. SpringBoot配置类的使用 5. @ModelAttribute详解 6. @RequestP ...