JAVA 调用控件开发

时间:2024-01-26 10:57:15

最近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或其他控件即可,望见谅!