/*
*
* Copyright 2014 http://Bither.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/
package net.bither.qrcode;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import com.github.sarxos.webcam.WebcamResolution;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import net.bither.utils.LocaliserUtils;
import net.bither.viewsystem.dialogs.BitherDialog;
import net.bither.viewsystem.dialogs.MessageDialog;
import javax.swing.*;
import java.awt.*;
import java.awt.Dimension;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ResourceBundle;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class ScanQRCodeDialog extends BitherDialog implements Runnable, ThreadFactory, IReadQRCode {
private JPanel contentPane;
private JButton buttonCancel;
private JPanel scanPanel;
private JLabel labMsg;
private Executor executor = Executors.newSingleThreadExecutor(this);
private Webcam webcam = null;
private WebcamPanel panel = null;
protected IScanQRCode scanQRCode;
private boolean isRunning = true;
public ScanQRCodeDialog(IScanQRCode scanQRCode) {
this.scanQRCode = scanQRCode;
setContentPane(contentPane);
setModal(true);
getRootPane().setDefaultButton(buttonCancel);
createUIComponents();
initDialog();
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
onCancel();
}
});
contentPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
buttonCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
onCancel();
}
});
executor.execute(this);
clearMessage();
}
@Override
public void run() {
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Result result = null;
BufferedImage image = null;
if (webcam.isOpen()) {
if ((image = webcam.getImage()) == null) {
continue;
}
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
result = new MultiFormatReader().decode(bitmap);
} catch (NotFoundException e) {
// fall thru, it means there is no QR code in image
}
}
if (result != null && result.getText() != null) {
handleResult(result.getText());
}
} while (isRunning);
}
public void handleResult(final String result) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
scanQRCode.handleResult(result, ScanQRCodeDialog.this);
}
});
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "example-runner");
t.setDaemon(true);
return t;
}
public void onCancel() {
if (webcam.isOpen()) {
webcam.close();
}
isRunning = false;
dispose();
}
@Override
public void close() {
onCancel();
}
@Override
public void reTry(String msg) {
setMessage(msg);
}
protected void clearMessage() {
labMsg.setText("");
}
protected void setMessage(String text) {
labMsg.setText(text);
}
private void createUIComponents() {
Dimension size = WebcamResolution.QVGA.getSize();
java.util.List<Webcam> webcams = Webcam.getWebcams();
if (webcams.size() > 0) {
webcam = webcams.get(0);
webcam.setViewSize(size);
panel = new WebcamPanel(webcam);
panel.setPreferredSize(size);
scanPanel.add(panel);
} else {
onCancel();
new MessageDialog(LocaliserUtils.getString("camer_is_not_available")).showMsg();
}
}
{
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
$$$setupUI$$$();
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* @noinspection ALL
*/
private void $$$setupUI$$$() {
contentPane = new JPanel();
contentPane.setLayout(new GridLayoutManager(2, 1, new Insets(10, 10, 10, 10), -1, -1));
contentPane.setBackground(new Color(-328966));
final JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayoutManager(1, 3, new Insets(0, 0, 0, 0), -1, -1));
panel1.setOpaque(false);
contentPane.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, 1, null, null, null, 0, false));
final Spacer spacer1 = new Spacer();
panel1.add(spacer1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
final JPanel panel2 = new JPanel();
panel2.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
panel2.setOpaque(false);
panel1.add(panel2, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
buttonCancel = new JButton();
this.$$$loadButtonText$$$(buttonCancel, ResourceBundle.getBundle("viewer").getString("cancel"));
panel2.add(buttonCancel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
labMsg = new JLabel();
labMsg.setText("Label");
panel1.add(labMsg, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
scanPanel = new JPanel();
scanPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
scanPanel.setOpaque(false);
contentPane.add(scanPanel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
}
/**
* @noinspection ALL
*/
private void $$$loadButtonText$$$(AbstractButton component, String text) {
StringBuffer result = new StringBuffer();
boolean haveMnemonic = false;
char mnemonic = '\0';
int mnemonicIndex = -1;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '&') {
i++;
if (i == text.length()) break;
if (!haveMnemonic && text.charAt(i) != '&') {
haveMnemonic = true;
mnemonic = text.charAt(i);
mnemonicIndex = result.length();
}
}
result.append(text.charAt(i));
}
component.setText(result.toString());
if (haveMnemonic) {
component.setMnemonic(mnemonic);
component.setDisplayedMnemonicIndex(mnemonicIndex);
}
}
/**
* @noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return contentPane;
}
}