[英]Java Program is not Calling Method
public void startScanning() {
// Check if there is a webcam available
if (cameraView.getWebcamPanel() == null) {
return;
}
// Make sure the webcam is not null
if (cameraView.getWebcam() == null) {
return;
}
if (!cameraView.getWebcam().isOpen()) {
cameraView.getWebcam().open();
}
// Make sure the webcam is open
if (cameraView.getWebcam().isOpen()) {
// Create a SwingWorker thread to run in the background
worker = new SwingWorker<Void, Void>() {
try {
qrResult = new MultiFormatReader().decode(bitmap);
//System.out.println("qrResults: " + qrResult);
try {
// new error handling
int length = qrResult.getText().length();
if(length != 23){
JOptionPane.showMessageDialog(null, "Username and password is correct");
startScanning();
}
// end of error handling
I omitted some of the syntax, but for some reason the startScanning() method is not called at the very end. 我省略了一些语法,但是由于某种原因,并未在最后调用startScanning()方法。 The dialog box is shown, but the method isn't called.
显示对话框,但未调用该方法。 Can someone please explain why?
有人可以解释为什么吗?
I suppose, it's related to JOptionPane.showMessageDialog
. 我想这与
JOptionPane.showMessageDialog
有关。 The MesageDialog has to be closed before the program proceeds. 在程序继续之前,必须关闭 MesageDialog。 And it can also throw an
HeadlessException
if you don't have a graphics device to show the dialog at. 如果您没有用于显示对话框的图形设备,它也可能引发
HeadlessException
。
Check any open windows and implement a good catch
to your try
block. 检查所有打开的窗口,并对您的
try
块实施良好的catch
。
A small example program to show what's happening: 一个小的示例程序来显示正在发生的事情:
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Message");
System.out.println("done");
}
The console output done
will only appear, if you have a graphics device, and only after you closed the dialog window. 仅当您具有图形设备时,并且仅在关闭对话框窗口之后,控制台输出
done
才会显示。
Some observations: 一些观察:
startScanning()
recursively, the first time on the Swing event thread, all the other recursive times off of the thread and this smells of trouble. startScanning()
,这是在Swing事件线程上的第一次,所有其他递归时间都在线程之外,这很麻烦。 I'd find out where it belongs and call it in that thread environment (on or off the EDT) and only that thread environment. For example 例如
import java.awt.Component;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
@SuppressWarnings("serial")
public class FooGui extends JPanel {
// create my button's Action
private StartScanningAction action = new StartScanningAction("Start Scanning", this);
private JButton button = new JButton(action); // pass Action into button's constructor
// this is spinner is used just to show passing information into the SwingWorker
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(25, 0, 50, 1));
// JTextField to show results from SwingWorker
private JTextField resultField = new JTextField(5);
public FooGui() {
resultField.setFocusable(false);
add(spinner);
add(button);
add(resultField);
}
// override method so that the JPanel controls whether its components are enabled or not
@Override
public void setEnabled(boolean enabled) {
button.setEnabled(enabled);
spinner.setEnabled(enabled);
super.setEnabled(enabled);
}
// get value so you can pass it into the Swingworker
public int getSpinnerValue() {
return (Integer) spinner.getValue();
}
// allow outside classes to set the resultField JTextField
public void setResultText(String text) {
resultField.setText(text);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("FooGui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new FooGui());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
// Start our GUI in a Swing Thread-safe way
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// JButton's Action
@SuppressWarnings("serial")
class StartScanningAction extends AbstractAction {
public static final int MINIMAL_VALUE = 50;
private FooGui fooGui; // the main GUI
private Component sourceComp; // the JButton
private int initValue; // value from the spinner
private JDialog dialog; // modal dialog to hold our JProgressBar
public StartScanningAction(String name, FooGui fooGui) {
super(name);
this.fooGui = fooGui;
}
@Override
public void actionPerformed(ActionEvent e) {
this.sourceComp = (Component) e.getSource();
// get the top-level window that holds our JButton
Window win = SwingUtilities.getWindowAncestor(sourceComp);
// create our JDialog in a lazy way
if (dialog == null) {
// JProgressBar to show in dialog when worker is working
JProgressBar progBar = new JProgressBar();
// if we plan to set the worker's progress property, then the dialog would not be indeterminate
progBar.setIndeterminate(true);
// pass win into dialog. Make it modal
dialog = new JDialog(win, "Awaiting Worker", ModalityType.APPLICATION_MODAL);
dialog.add(progBar);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
// disable the main GUI
fooGui.setEnabled(false);
// extract info from the main GUI
initValue = fooGui.getSpinnerValue();
// call the method that gets our worker going
startScanning(initValue);
}
// method that gets worker going. This is called on the EDT
private void startScanning(int initValue) {
// create a worker object
StartScanningWorker worker = new StartScanningWorker(initValue);
// add property change listener to the worker
worker.addPropertyChangeListener(new PcListener());
// execute the worker
worker.execute();
// show our dialog. this freezes program flow so must be done last
dialog.setVisible(true);
}
// listen for state changes to the worker. This is done on the EDT
private class PcListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
// if the worker is done working
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
dialog.dispose(); // get rid of the modal dialog
// extract worker
StartScanningWorker worker = (StartScanningWorker) evt.getSource();
try {
// deal with any exceptions that occurred during worker's run
worker.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
return; // this one's a bad exception
}
// get worker's value and check if it is adequate
int someValue = worker.getSomeValue();
if (someValue < MINIMAL_VALUE) {
// our worker failed -- display a JOptionPane. We're on the EDT so this thread is OK for this
String message = String.format("someValue is %d which is less than the "
+ "minimal value, %d. To re-run worker", someValue, MINIMAL_VALUE);
String title = "Some Value Not High Enough";
int messageType = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(sourceComp, message, title, messageType);
// recursive call made on the EDT. Be careful doing this.
startScanning(initValue);
} else {
// else the worker's result was good. Display the results and re-enable the GUI
fooGui.setResultText(String.valueOf(someValue));
fooGui.setEnabled(true);
}
}
}
}
}
// worker that doesn't do anything important
class StartScanningWorker extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 2 * 1000;
public static final String SOME_VALUE = "some value";
private int someValue;
public StartScanningWorker(int someInitialValue) {
// initialize the worker with a value from the GUI
this.someValue = someInitialValue;
}
public int getSomeValue() {
return someValue;
}
// if I want someValue to be a bound property. Not necessary in this example
public void setSomeValue(int someValue) {
int oldValue = this.someValue;
this.someValue = someValue;
firePropertyChange(SOME_VALUE, oldValue, someValue);
}
@Override
protected Void doInBackground() throws Exception {
// simulate along-running process
Thread.sleep(SLEEP_TIME);
// get a random value
int value = (int) (100 * Math.random()) + someValue;
setSomeValue(value);
// end the worker
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.