/* * * 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; } }