Java/Development Class/COM Port
Содержание
- 1 Choose a port, any port!
- 2 Demonstrate the port conflict resolution mechanism
- 3 List the ports
- 4 Open a serial port using Java Communications
- 5 Port Finder
- 6 Port Reader
- 7 Port Sniffer
- 8 Port Writer
- 9 Printing a File
- 10 Querying Available COM Ports
- 11 Read from a Serial port, notifying when data arrives
- 12 Read from multiple Serial ports, notifying when data arrives on any
- 13 Subclasses CommPortOpen and adds send/expect handling for dealing with Hayes-type modems
- 14 This program tries to do I/O in each direction using a separate Thread
Choose a port, any port!
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Enumeration; import java.util.HashMap; import javax.rum.rumPortIdentifier; import javax.rum.SerialPort; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /**
* Choose a port, any port! * * Java Communications is a "standard extention" and must be downloaded and * installed separately from the JDK before you can even compile this program. * * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: PortChooser.java,v 1.9 2004/04/11 23:50:40 ian Exp $ */
public class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** * This will be called from either of the JComboBoxen when the user selects * any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String) ((JComboBox) e.getSource()) .getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier) map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** * Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** * Build the GUI. You can ignore this for now if you have not yet worked * through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0, 2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** * Populate the ComboBoxes by asking the Java Communications API what ports * it has. Since the initial information comes from a Properties file, it * may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier) pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>
Demonstrate the port conflict resolution mechanism
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Enumeration; import java.util.HashMap; import javax.rum.rumPort; import javax.rum.rumPortIdentifier; import javax.rum.rumPortOwnershipListener; import javax.rum.NoSuchPortException; import javax.rum.ParallelPort; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.UnsupportedCommOperationException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; /** Demonstrate the port conflict resolution mechanism.
* Run two copies of this program and choose the same port in each. * $Id: PortOwner.java,v 1.1 2000/02/27 03:45:34 ian Exp $ */
public class PortOwner extends CommPortOpen {
/** A name for showing which of several instances of this program */ String myName; public PortOwner(String name) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { super(null); myName = name; thePortID.addPortOwnershipListener(new MyResolver()); } public void converse() { // lah de dah... // To simulate a long conversation on the port... try { Thread.sleep(1000 * 1000); } catch (InterruptedException cantHappen) { // } } /** An inner class that handles the ports conflict resolution. */ class MyResolver implements CommPortOwnershipListener { protected boolean owned = false; public void ownershipChange(int whaHoppen) { switch (whaHoppen) { case PORT_OWNED: System.out.println("An open succeeded."); owned = true; break; case PORT_UNOWNED: System.out.println("A close succeeded."); owned = false; break; case PORT_OWNERSHIP_REQUESTED: if (owned) { if (JOptionPane.showConfirmDialog(null, "I"ve been asked to give up the port, should I?", "Port Conflict (" + myName + ")", JOptionPane.OK_CANCEL_OPTION) == 0) thePort.close(); } else { System.out.println("Somebody else has the port"); } } } } public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { if (argv.length != 1) { System.err.println("Usage: PortOwner aname"); System.exit(1); } new PortOwner(argv[0]).converse(); System.exit(0); }
} /**
* Open a serial port using Java Communications. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
class CommPortOpen {
/** How long to wait for the open to finish up. */ public static final int TIMEOUTSECONDS = 30; /** The baud rate to use. */ public static final int BAUD = 19200; /** The parent JFrame, for the chooser. */ protected JFrame parent; /** The input stream */ protected BufferedReader is; /** The output stream */ protected PrintStream os; /** The chosen Port Identifier */ CommPortIdentifier thePortID; /** The chosen Port itself */ CommPort thePort; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new CommPortOpen(null).converse(); System.exit(0); } /* Constructor */ public CommPortOpen(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // Use the PortChooser from before. Pop up the JDialog. PortChooser chooser = new PortChooser(null); String portName = null; do { chooser.setVisible(true); // Dialog done. Get the port name. portName = chooser.getSelectedName(); if (portName == null) System.out.println("No port selected. Try again.\n"); } while (portName == null); // Get the CommPortIdentifier. thePortID = chooser.getSelectedIdentifier(); // Now actually open the port. // This form of openPort takes an Application Name and a timeout. // System.out.println("Trying to open " + thePortID.getName() + "..."); switch (thePortID.getPortType()) { case CommPortIdentifier.PORT_SERIAL: thePort = thePortID.open("DarwinSys DataComm", TIMEOUTSECONDS * 1000); SerialPort myPort = (SerialPort) thePort; // set up the serial port myPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; case CommPortIdentifier.PORT_PARALLEL: thePort = thePortID.open("DarwinSys Printing", TIMEOUTSECONDS * 1000); ParallelPort pPort = (ParallelPort)thePort; // Tell API to pick "best available mode" - can fail! // myPort.setMode(ParallelPort.LPT_MODE_ANY); // Print what the mode is int mode = pPort.getMode(); switch (mode) { case ParallelPort.LPT_MODE_ECP: System.out.println("Mode is: ECP"); break; case ParallelPort.LPT_MODE_EPP: System.out.println("Mode is: EPP"); break; case ParallelPort.LPT_MODE_NIBBLE: System.out.println("Mode is: Nibble Mode."); break; case ParallelPort.LPT_MODE_PS2: System.out.println("Mode is: Byte mode."); break; case ParallelPort.LPT_MODE_SPP: System.out.println("Mode is: Compatibility mode."); break; // ParallelPort.LPT_MODE_ANY is a "set only" mode; // tells the API to pick "best mode"; will report the // actual mode it selected. default: throw new IllegalStateException("Parallel mode " + mode + " invalid."); } break; default: // Neither parallel nor serial?? throw new IllegalStateException("Unknown port type " + thePortID); } // Get the input and output streams // Printers can be write-only try { is = new BufferedReader(new InputStreamReader(thePort.getInputStream())); } catch (IOException e) { System.err.println("Can"t open input stream: write-only"); is = null; } os = new PrintStream(thePort.getOutputStream(), true); } /** This method will be overridden by non-trivial subclasses * to hold a conversation. */ protected void converse() throws IOException { System.out.println("Ready to read and write port."); // Input/Output code not written -- must subclass. // Finally, clean up. if (is != null) is.close(); os.close(); }
} class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** This will be called from either of the JComboBoxen when the * user selects any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String)((JComboBox)e.getSource()).getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier)map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** Build the GUI. You can ignore this for now if you have not * yet worked through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0,2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** Populate the ComboBoxes by asking the Java Communications API * what ports it has. Since the initial information comes from * a Properties file, it may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>
List the ports
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.util.Enumeration; import javax.rum.rumPortIdentifier; /**
* List the ports. * * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: CommPortLister.java,v 1.4 2004/02/09 03:33:51 ian Exp $ */
public class CommPortLister {
/** Simple test program. */ public static void main(String[] ap) { new CommPortLister().list(); } /** Ask the Java Communications API * what ports it thinks it has. */ protected void list() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list. while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier) pList.nextElement(); System.out.print("Port " + cpi.getName() + " "); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println("is a Serial Port: " + cpi); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { System.out.println("is a Parallel Port: " + cpi); } else { System.out.println("is an Unknown Port: " + cpi); } } }
}
</source>
Open a serial port using Java Communications
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Enumeration; import java.util.HashMap; import javax.rum.rumPort; import javax.rum.rumPortIdentifier; import javax.rum.NoSuchPortException; import javax.rum.ParallelPort; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.UnsupportedCommOperationException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /**
* Open a serial port using Java Communications. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
public class CommPortOpen {
/** How long to wait for the open to finish up. */ public static final int TIMEOUTSECONDS = 30; /** The baud rate to use. */ public static final int BAUD = 19200; /** The parent JFrame, for the chooser. */ protected JFrame parent; /** The input stream */ protected BufferedReader is; /** The output stream */ protected PrintStream os; /** The chosen Port Identifier */ CommPortIdentifier thePortID; /** The chosen Port itself */ CommPort thePort; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new CommPortOpen(null).converse(); System.exit(0); } /* Constructor */ public CommPortOpen(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // Use the PortChooser from before. Pop up the JDialog. PortChooser chooser = new PortChooser(null); String portName = null; do { chooser.setVisible(true); // Dialog done. Get the port name. portName = chooser.getSelectedName(); if (portName == null) System.out.println("No port selected. Try again.\n"); } while (portName == null); // Get the CommPortIdentifier. thePortID = chooser.getSelectedIdentifier(); // Now actually open the port. // This form of openPort takes an Application Name and a timeout. // System.out.println("Trying to open " + thePortID.getName() + "..."); switch (thePortID.getPortType()) { case CommPortIdentifier.PORT_SERIAL: thePort = thePortID.open("DarwinSys DataComm", TIMEOUTSECONDS * 1000); SerialPort myPort = (SerialPort) thePort; // set up the serial port myPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; case CommPortIdentifier.PORT_PARALLEL: thePort = thePortID.open("DarwinSys Printing", TIMEOUTSECONDS * 1000); ParallelPort pPort = (ParallelPort)thePort; // Tell API to pick "best available mode" - can fail! // myPort.setMode(ParallelPort.LPT_MODE_ANY); // Print what the mode is int mode = pPort.getMode(); switch (mode) { case ParallelPort.LPT_MODE_ECP: System.out.println("Mode is: ECP"); break; case ParallelPort.LPT_MODE_EPP: System.out.println("Mode is: EPP"); break; case ParallelPort.LPT_MODE_NIBBLE: System.out.println("Mode is: Nibble Mode."); break; case ParallelPort.LPT_MODE_PS2: System.out.println("Mode is: Byte mode."); break; case ParallelPort.LPT_MODE_SPP: System.out.println("Mode is: Compatibility mode."); break; // ParallelPort.LPT_MODE_ANY is a "set only" mode; // tells the API to pick "best mode"; will report the // actual mode it selected. default: throw new IllegalStateException("Parallel mode " + mode + " invalid."); } break; default: // Neither parallel nor serial?? throw new IllegalStateException("Unknown port type " + thePortID); } // Get the input and output streams // Printers can be write-only try { is = new BufferedReader(new InputStreamReader(thePort.getInputStream())); } catch (IOException e) { System.err.println("Can"t open input stream: write-only"); is = null; } os = new PrintStream(thePort.getOutputStream(), true); } /** This method will be overridden by non-trivial subclasses * to hold a conversation. */ protected void converse() throws IOException { System.out.println("Ready to read and write port."); // Input/Output code not written -- must subclass. // Finally, clean up. if (is != null) is.close(); os.close(); }
} class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** This will be called from either of the JComboBoxen when the * user selects any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String)((JComboBox)e.getSource()).getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier)map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** Build the GUI. You can ignore this for now if you have not * yet worked through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0,2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** Populate the ComboBoxes by asking the Java Communications API * what ports it has. Since the initial information comes from * a Properties file, it may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>
Port Finder
<source lang="java">
import java.io.*; import javax.rum.*; import java.util.*; public class Main {
public static void main(String[] args) { Enumeration ports = CommPortIdentifier.getPortIdentifiers(); while(ports.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)ports.nextElement(); System.out.println("Port " + cpi.getName()); } }
}
</source>
Port Reader
<source lang="java">
import java.io.*; import javax.rum.*; import java.util.*; public class PortReader SerialPortEventListener {
static Enumeration ports; static CommPortIdentifier pID; InputStream inStream; SerialPort serPort; public PortReader() throws Exception{ serPort = (SerialPort) pID.open("PortReader", 2000); inStream = serPort.getInputStream(); serPort.addEventListener(this); serPort.notifyOnDataAvailable(true); serPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } public void serialEvent(SerialPortEvent event) { switch (event.getEventType()) { case SerialPortEvent.BI: System.out.println("SerialPortEvent.BI occurred"); case SerialPortEvent.OE: System.out.println("SerialPortEvent.OE occurred"); case SerialPortEvent.FE: System.out.println("SerialPortEvent.FE occurred"); case SerialPortEvent.PE: System.out.println("SerialPortEvent.PE occurred"); case SerialPortEvent.CD: System.out.println("SerialPortEvent.CD occurred"); case SerialPortEvent.CTS: System.out.println("SerialPortEvent.CTS occurred"); case SerialPortEvent.DSR: System.out.println("SerialPortEvent.DSR occurred"); case SerialPortEvent.RI: System.out.println("SerialPortEvent.RI occurred"); case SerialPortEvent.OUTPUT_BUFFER_EMPTY: System.out.println("SerialPortEvent.OUTPUT_BUFFER_EMPTY occurred"); break; case SerialPortEvent.DATA_AVAILABLE: System.out.println("SerialPortEvent.DATA_AVAILABLE occurred"); byte[] readBuffer = new byte[20]; try { while (inStream.available() > 0) { int numBytes = inStream.read(readBuffer); } System.out.print(new String(readBuffer)); } catch (IOException ioe) { System.out.println("Exception " + ioe); } break; } } public static void main(String[] args) throws Exception{ ports = CommPortIdentifier.getPortIdentifiers(); while (ports.hasMoreElements()) { pID = (CommPortIdentifier) ports.nextElement(); System.out.println("Port " + pID.getName()); if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (pID.getName().equals("COM1")) { PortReader pReader = new PortReader(); System.out.println("COM1 found"); } } } }
}
</source>
Port Sniffer
<source lang="java">
import java.io.*; import javax.rum.*; import java.util.*; public class PortSniffer SerialPortEventListener {
static Enumeration ports; static CommPortIdentifier pID; InputStream inStream; SerialPort serPort; public PortSniffer() throws Exception { serPort = (SerialPort)pID.open("PortSniffer",2000); inStream = serPort.getInputStream(); serPort.addEventListener(this); serPort.notifyOnDataAvailable(true); serPort.notifyOnBreakInterrupt(true); serPort.notifyOnCarrierDetect(true); serPort.notifyOnCTS(true); serPort.notifyOnDataAvailable(true); serPort.notifyOnDSR(true); serPort.notifyOnFramingError(true); serPort.notifyOnOutputEmpty(true); serPort.notifyOnOverrunError(true); serPort.notifyOnParityError(true); serPort.notifyOnRingIndicator(true); serPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } public void serialEvent(SerialPortEvent event) { switch(event.getEventType()) { case SerialPortEvent.BI: System.out.println("SerialPortEvent.BI occurred"); case SerialPortEvent.OE: System.out.println("SerialPortEvent.OE occurred"); case SerialPortEvent.FE: System.out.println("SerialPortEvent.FE occurred"); case SerialPortEvent.PE: System.out.println("SerialPortEvent.PE occurred"); case SerialPortEvent.CD: System.out.println("SerialPortEvent.CD occurred"); case SerialPortEvent.CTS: System.out.println("SerialPortEvent.CTS occurred"); case SerialPortEvent.DSR: System.out.println("SerialPortEvent.DSR occurred"); case SerialPortEvent.RI: System.out.println("SerialPortEvent.RI occurred"); case SerialPortEvent.OUTPUT_BUFFER_EMPTY: System.out.println("SerialPortEvent.OUTPUT_BUFFER_EMPTY occurred"); break; case SerialPortEvent.DATA_AVAILABLE: System.out.println("SerialPortEvent.DATA_AVAILABLE occurred"); byte[] readBuffer = new byte[20]; try { while (inStream.available() > 0) { int numBytes = inStream.read(readBuffer); } System.out.print(new String(readBuffer)); }catch (IOException ioe) { System.out.println("Exception " + ioe); } break; } } public static void main(String[] args)throws Exception{ ports = CommPortIdentifier.getPortIdentifiers(); while(ports.hasMoreElements()) { pID = (CommPortIdentifier)ports.nextElement(); System.out.println("Port " + pID.getName()); if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (pID.getName().equals("COM1")) { PortSniffer pSniffer = new PortSniffer(); System.out.println("COM1 found"); } } } }
}
</source>
Port Writer
<source lang="java">
import java.io.*; import javax.rum.*; import java.util.*; public class PortWriter {
static Enumeration ports; static CommPortIdentifier pID; static OutputStream outStream; SerialPort serPort; static String messageToSend = "message!\n"; public PortWriter() throws Exception{ serPort = (SerialPort)pID.open("PortWriter",2000); outStream = serPort.getOutputStream(); serPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } public static void main(String[] args) throws Exception{ ports = CommPortIdentifier.getPortIdentifiers(); while(ports.hasMoreElements()) { pID = (CommPortIdentifier)ports.nextElement(); System.out.println("Port " + pID.getName()); if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (pID.getName().equals("COM1")) { PortWriter pWriter = new PortWriter(); System.out.println("COM1 found"); } } } outStream.write(messageToSend.getBytes()); }
}
</source>
Printing a File
<source lang="java">
import java.io.*; import javax.rum.*; public class PrintFile {
public static void main(String args[]) throws Exception { if (args.length != 2) { System.err.println("usage : java PrintFile port file"); System.err.println("sample: java PrintFile LPT1 sample.prn"); System.exit(-1); } String portname = args[0]; String filename = args[1]; // Get port CommPortIdentifier portId = CommPortIdentifier .getPortIdentifier(portname); // Open port // Requires owner name and timeout CommPort port = portId.open("Java Printing", 30000); // Setup reading from file FileInputStream fis = new FileInputStream(filename); BufferedInputStream bis = new BufferedInputStream(fis); // Setup output OutputStream os = port.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(os); int c; while ((c = bis.read()) != -1) { bos.write(c); } // Close bos.close(); bis.close(); port.close(); }
}
</source>
Querying Available COM Ports
<source lang="java">
// Install the Java Comm API first. if there is no necessary file, say Dll files, the API // won"t work. import java.util.Enumeration; import javax.rum.*; import java.util.Enumeration; public class ListPorts {
public static void main(String args[]) { Enumeration ports = CommPortIdentifier.getPortIdentifiers(); while (ports.hasMoreElements()) { CommPortIdentifier port = (CommPortIdentifier) ports.nextElement(); String type; switch (port.getPortType()) { case CommPortIdentifier.PORT_PARALLEL: type = "Parallel"; break; case CommPortIdentifier.PORT_SERIAL: type = "Serial"; break; default: /// Shouldn"t happen type = "Unknown"; break; } System.out.println(port.getName() + ": " + type); } }
}
</source>
Read from a Serial port, notifying when data arrives
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Enumeration; import java.util.HashMap; import java.util.TooManyListenersException; import javax.rum.rumPort; import javax.rum.rumPortIdentifier; import javax.rum.NoSuchPortException; import javax.rum.ParallelPort; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.SerialPortEvent; import javax.rum.SerialPortEventListener; import javax.rum.UnsupportedCommOperationException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /**
* Read from a Serial port, notifying when data arrives. * Simulation of part of an event-logging service. * @version $Id: SerialReadByEvents.java,v 1.4 2004/04/11 23:50:40 ian Exp $ * @author Ian F. Darwin, http://www.darwinsys.ru/ */
public class SerialReadByEvents extends CommPortOpen
implements SerialPortEventListener { public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new SerialReadByEvents(null).converse(); } /* Constructor */ public SerialReadByEvents(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { super(f); } /** * Hold the conversation. */ protected void converse() throws IOException { if (!(thePort instanceof SerialPort)) { System.err.println("But I wanted a SERIAL port!"); System.exit(1); } // Tell the Comm API that we want serial events. ((SerialPort)thePort).notifyOnDataAvailable(true); try { ((SerialPort)thePort).addEventListener(this); } catch (TooManyListenersException ev) { // "CantHappen" error System.err.println("Too many listeners(!) " + ev); System.exit(0); } } public void serialEvent(SerialPortEvent ev) { String line; try { line = is.readLine(); if (line == null) { System.out.println("EOF on serial port."); System.exit(0); } os.println(line); } catch (IOException ex) { System.err.println("IO Error " + ex); } }
}
/**
* Open a serial port using Java Communications. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
class CommPortOpen {
/** How long to wait for the open to finish up. */ public static final int TIMEOUTSECONDS = 30; /** The baud rate to use. */ public static final int BAUD = 19200; /** The parent JFrame, for the chooser. */ protected JFrame parent; /** The input stream */ protected BufferedReader is; /** The output stream */ protected PrintStream os; /** The chosen Port Identifier */ CommPortIdentifier thePortID; /** The chosen Port itself */ CommPort thePort; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new CommPortOpen(null).converse(); System.exit(0); } /* Constructor */ public CommPortOpen(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // Use the PortChooser from before. Pop up the JDialog. PortChooser chooser = new PortChooser(null); String portName = null; do { chooser.setVisible(true); // Dialog done. Get the port name. portName = chooser.getSelectedName(); if (portName == null) System.out.println("No port selected. Try again.\n"); } while (portName == null); // Get the CommPortIdentifier. thePortID = chooser.getSelectedIdentifier(); // Now actually open the port. // This form of openPort takes an Application Name and a timeout. // System.out.println("Trying to open " + thePortID.getName() + "..."); switch (thePortID.getPortType()) { case CommPortIdentifier.PORT_SERIAL: thePort = thePortID.open("DarwinSys DataComm", TIMEOUTSECONDS * 1000); SerialPort myPort = (SerialPort) thePort; // set up the serial port myPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; case CommPortIdentifier.PORT_PARALLEL: thePort = thePortID.open("DarwinSys Printing", TIMEOUTSECONDS * 1000); ParallelPort pPort = (ParallelPort)thePort; // Tell API to pick "best available mode" - can fail! // myPort.setMode(ParallelPort.LPT_MODE_ANY); // Print what the mode is int mode = pPort.getMode(); switch (mode) { case ParallelPort.LPT_MODE_ECP: System.out.println("Mode is: ECP"); break; case ParallelPort.LPT_MODE_EPP: System.out.println("Mode is: EPP"); break; case ParallelPort.LPT_MODE_NIBBLE: System.out.println("Mode is: Nibble Mode."); break; case ParallelPort.LPT_MODE_PS2: System.out.println("Mode is: Byte mode."); break; case ParallelPort.LPT_MODE_SPP: System.out.println("Mode is: Compatibility mode."); break; // ParallelPort.LPT_MODE_ANY is a "set only" mode; // tells the API to pick "best mode"; will report the // actual mode it selected. default: throw new IllegalStateException("Parallel mode " + mode + " invalid."); } break; default: // Neither parallel nor serial?? throw new IllegalStateException("Unknown port type " + thePortID); } // Get the input and output streams // Printers can be write-only try { is = new BufferedReader(new InputStreamReader(thePort.getInputStream())); } catch (IOException e) { System.err.println("Can"t open input stream: write-only"); is = null; } os = new PrintStream(thePort.getOutputStream(), true); } /** This method will be overridden by non-trivial subclasses * to hold a conversation. */ protected void converse() throws IOException { System.out.println("Ready to read and write port."); // Input/Output code not written -- must subclass. // Finally, clean up. if (is != null) is.close(); os.close(); }
} class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** This will be called from either of the JComboBoxen when the * user selects any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String)((JComboBox)e.getSource()).getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier)map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** Build the GUI. You can ignore this for now if you have not * yet worked through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0,2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** Populate the ComboBoxes by asking the Java Communications API * what ports it has. Since the initial information comes from * a Properties file, it may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>
Read from multiple Serial ports, notifying when data arrives on any
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Enumeration; import java.util.TooManyListenersException; import java.util.logging.Logger; import javax.rum.rumPortIdentifier; import javax.rum.NoSuchPortException; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.SerialPortEvent; import javax.rum.SerialPortEventListener; import javax.rum.UnsupportedCommOperationException; /**
* Read from multiple Serial ports, notifying when data arrives on any. * * @version $Id: SerialLogger.java,v 1.4 2004/03/11 04:09:14 ian Exp $ * @author Ian F. Darwin, http://www.darwinsys.ru/ */
public class SerialLogger {
public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new SerialLogger(); } /* Constructor */ public SerialLogger() throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, processing only serial ports. while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier) pList.nextElement(); String name = cpi.getName(); System.out.print("Port " + name + " "); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println("is a Serial Port: " + cpi); SerialPort thePort; try { thePort = (SerialPort) cpi.open("Logger", 1000); } catch (PortInUseException ev) { System.err.println("Port in use: " + name); continue; } // Tell the Comm API that we want serial events. thePort.notifyOnDataAvailable(true); try { thePort .addEventListener(new Logger(cpi.getName(), thePort)); } catch (TooManyListenersException ev) { // "CantHappen" error System.err.println("Too many listeners(!) " + ev); System.exit(0); } } } } /** Handle one port. */ public class Logger implements SerialPortEventListener { String portName; SerialPort thePort; BufferedReader ifile; public Logger(String name, SerialPort port) throws IOException { portName = name; thePort = port; // Make a reader for the input file. ifile = new BufferedReader(new InputStreamReader(thePort .getInputStream())); } public void serialEvent(SerialPortEvent ev) { String line; try { line = ifile.readLine(); if (line == null) { System.out.println("EOF on serial port."); System.exit(0); } System.out.println(portName + ": " + line); } catch (IOException ex) { System.err.println("IO Error " + ex); } } }
}
</source>
Subclasses CommPortOpen and adds send/expect handling for dealing with Hayes-type modems
<source lang="java">
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Enumeration; import java.util.HashMap; import javax.rum.rumPort; import javax.rum.rumPortIdentifier; import javax.rum.NoSuchPortException; import javax.rum.ParallelPort; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.UnsupportedCommOperationException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /**
* Subclasses CommPortOpen and adds send/expect handling for dealing * with Hayes-type modems. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */ class CommPortModem extends CommPortOpen { /** The last line read from the serial port. */ protected String response; /** A flag to control debugging output. */ protected boolean debug = true; public CommPortModem(JFrame f) throws IOException, NoSuchPortException,PortInUseException, UnsupportedCommOperationException { super(f); } /** Send a line to a PC-style modem. Send \r\n, regardless of * what platform we"re on, instead of using println(). */ protected void send(String s) throws IOException { if (debug) { System.out.print(">>> "); System.out.print(s); System.out.println(); } os.print(s); os.print("\r\n"); // Expect the modem to echo the command. if (!expect(s)) { System.err.println("WARNING: Modem did not echo command."); } // The modem sends an extra blank line by way of a prompt. // Here we read and discard it. String junk = is.readLine(); if (junk.length() != 0) { System.err.print("Warning: unexpected response: "); System.err.println(junk); } } /** Read a line, saving it in "response". * @return true if the expected String is contained in the response, false if not. */ protected boolean expect(String exp) throws IOException { response = is.readLine(); if (debug) { System.out.print("<<< "); System.out.print(response); System.out.println(); } return response.indexOf(exp) >= 0; }
} /**
* Dial a phone using the Java Communications Package. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
public class CommPortDial extends CommPortModem {
protected static String number = "000-0000"; public static void main(String[] ap) throws IOException, NoSuchPortException,PortInUseException, UnsupportedCommOperationException { if (ap.length == 1) number = ap[0]; new CommPortDial().converse(); System.exit(0); } public CommPortDial() throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { super(null); } protected void converse() throws IOException { String resp; // the modem response. // Send the reset command send("ATZ"); expect("OK"); send("ATDT" + number); expect("OK"); try { Thread.sleep(5000); } catch (InterruptedException e) { // nothing to do } is.close(); os.close(); }
} class CommPortOpen {
/** How long to wait for the open to finish up. */ public static final int TIMEOUTSECONDS = 30; /** The baud rate to use. */ public static final int BAUD = 19200; /** The parent JFrame, for the chooser. */ protected JFrame parent; /** The input stream */ protected BufferedReader is; /** The output stream */ protected PrintStream os; /** The chosen Port Identifier */ CommPortIdentifier thePortID; /** The chosen Port itself */ CommPort thePort; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new CommPortOpen(null).converse(); System.exit(0); } /* Constructor */ public CommPortOpen(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // Use the PortChooser from before. Pop up the JDialog. PortChooser chooser = new PortChooser(null); String portName = null; do { chooser.setVisible(true); // Dialog done. Get the port name. portName = chooser.getSelectedName(); if (portName == null) System.out.println("No port selected. Try again.\n"); } while (portName == null); // Get the CommPortIdentifier. thePortID = chooser.getSelectedIdentifier(); // Now actually open the port. // This form of openPort takes an Application Name and a timeout. // System.out.println("Trying to open " + thePortID.getName() + "..."); switch (thePortID.getPortType()) { case CommPortIdentifier.PORT_SERIAL: thePort = thePortID.open("DarwinSys DataComm", TIMEOUTSECONDS * 1000); SerialPort myPort = (SerialPort) thePort; // set up the serial port myPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; case CommPortIdentifier.PORT_PARALLEL: thePort = thePortID.open("DarwinSys Printing", TIMEOUTSECONDS * 1000); ParallelPort pPort = (ParallelPort)thePort; // Tell API to pick "best available mode" - can fail! // myPort.setMode(ParallelPort.LPT_MODE_ANY); // Print what the mode is int mode = pPort.getMode(); switch (mode) { case ParallelPort.LPT_MODE_ECP: System.out.println("Mode is: ECP"); break; case ParallelPort.LPT_MODE_EPP: System.out.println("Mode is: EPP"); break; case ParallelPort.LPT_MODE_NIBBLE: System.out.println("Mode is: Nibble Mode."); break; case ParallelPort.LPT_MODE_PS2: System.out.println("Mode is: Byte mode."); break; case ParallelPort.LPT_MODE_SPP: System.out.println("Mode is: Compatibility mode."); break; // ParallelPort.LPT_MODE_ANY is a "set only" mode; // tells the API to pick "best mode"; will report the // actual mode it selected. default: throw new IllegalStateException("Parallel mode " + mode + " invalid."); } break; default: // Neither parallel nor serial?? throw new IllegalStateException("Unknown port type " + thePortID); } // Get the input and output streams // Printers can be write-only try { is = new BufferedReader(new InputStreamReader(thePort.getInputStream())); } catch (IOException e) { System.err.println("Can"t open input stream: write-only"); is = null; } os = new PrintStream(thePort.getOutputStream(), true); } /** This method will be overridden by non-trivial subclasses * to hold a conversation. */ protected void converse() throws IOException { System.out.println("Ready to read and write port."); // Input/Output code not written -- must subclass. // Finally, clean up. if (is != null) is.close(); os.close(); }
} class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** This will be called from either of the JComboBoxen when the * user selects any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String)((JComboBox)e.getSource()).getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier)map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** Build the GUI. You can ignore this for now if you have not * yet worked through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0,2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** Populate the ComboBoxes by asking the Java Communications API * what ports it has. Since the initial information comes from * a Properties file, it may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>
This program tries to do I/O in each direction using a separate Thread
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Enumeration; import java.util.HashMap; import javax.rum.rumPort; import javax.rum.rumPortIdentifier; import javax.rum.NoSuchPortException; import javax.rum.ParallelPort; import javax.rum.PortInUseException; import javax.rum.SerialPort; import javax.rum.UnsupportedCommOperationException; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel;
/**
* This program tries to do I/O in each direction using a separate Thread. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
public class CommPortThreaded extends CommPortOpen {
public static void main(String[] ap) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { CommPortThreaded cp; try { cp = new CommPortThreaded(); cp.converse(); } catch (Exception e) { System.err.println("You lose!"); System.err.println(e); } } public CommPortThreaded() throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { super(null); } /** * This version of converse() just starts a Thread in each direction. */ protected void converse() throws IOException { String resp; // the modem response. new DataThread(is, System.out).start(); new DataThread(new DataInputStream(System.in), os).start(); } /** This inner class handles one side of a conversation. */ class DataThread extends Thread { BufferedReader inStream; PrintStream pStream; /** Construct this object */ DataThread(InputStream is, PrintStream os) { inStream = new BufferedReader(new InputStreamReader(is)); pStream = os; } DataThread(BufferedReader is, PrintStream os) { inStream = is; pStream = os; } /** A Thread"s run method does the work. */ public void run() { byte ch = 0; try { while ((ch = (byte) inStream.read()) != -1) pStream.print((char) ch); } catch (IOException e) { System.err.println("Input or output error: " + e); return; } } }
} /**
* Open a serial port using Java Communications. * * @author Ian F. Darwin, http://www.darwinsys.ru/ */
class CommPortOpen {
/** How long to wait for the open to finish up. */ public static final int TIMEOUTSECONDS = 30; /** The baud rate to use. */ public static final int BAUD = 19200; /** The parent JFrame, for the chooser. */ protected JFrame parent; /** The input stream */ protected BufferedReader is; /** The output stream */ protected PrintStream os; /** The chosen Port Identifier */ CommPortIdentifier thePortID; /** The chosen Port itself */ CommPort thePort; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { new CommPortOpen(null).converse(); System.exit(0); } /* Constructor */ public CommPortOpen(JFrame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { // Use the PortChooser from before. Pop up the JDialog. PortChooser chooser = new PortChooser(null); String portName = null; do { chooser.setVisible(true); // Dialog done. Get the port name. portName = chooser.getSelectedName(); if (portName == null) System.out.println("No port selected. Try again.\n"); } while (portName == null); // Get the CommPortIdentifier. thePortID = chooser.getSelectedIdentifier(); // Now actually open the port. // This form of openPort takes an Application Name and a timeout. // System.out.println("Trying to open " + thePortID.getName() + "..."); switch (thePortID.getPortType()) { case CommPortIdentifier.PORT_SERIAL: thePort = thePortID.open("DarwinSys DataComm", TIMEOUTSECONDS * 1000); SerialPort myPort = (SerialPort) thePort; // set up the serial port myPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); break; case CommPortIdentifier.PORT_PARALLEL: thePort = thePortID.open("DarwinSys Printing", TIMEOUTSECONDS * 1000); ParallelPort pPort = (ParallelPort) thePort; // Tell API to pick "best available mode" - can fail! // myPort.setMode(ParallelPort.LPT_MODE_ANY); // Print what the mode is int mode = pPort.getMode(); switch (mode) { case ParallelPort.LPT_MODE_ECP: System.out.println("Mode is: ECP"); break; case ParallelPort.LPT_MODE_EPP: System.out.println("Mode is: EPP"); break; case ParallelPort.LPT_MODE_NIBBLE: System.out.println("Mode is: Nibble Mode."); break; case ParallelPort.LPT_MODE_PS2: System.out.println("Mode is: Byte mode."); break; case ParallelPort.LPT_MODE_SPP: System.out.println("Mode is: Compatibility mode."); break; // ParallelPort.LPT_MODE_ANY is a "set only" mode; // tells the API to pick "best mode"; will report the // actual mode it selected. default: throw new IllegalStateException("Parallel mode " + mode + " invalid."); } break; default: // Neither parallel nor serial?? throw new IllegalStateException("Unknown port type " + thePortID); } // Get the input and output streams // Printers can be write-only try { is = new BufferedReader(new InputStreamReader(thePort .getInputStream())); } catch (IOException e) { System.err.println("Can"t open input stream: write-only"); is = null; } os = new PrintStream(thePort.getOutputStream(), true); } /** * This method will be overridden by non-trivial subclasses to hold a * conversation. */ protected void converse() throws IOException { System.out.println("Ready to read and write port."); // Input/Output code not written -- must subclass. // Finally, clean up. if (is != null) is.close(); os.close(); }
}
class PortChooser extends JDialog implements ItemListener {
/** A mapping from names to CommPortIdentifiers. */ protected HashMap map = new HashMap(); /** The name of the choice the user made. */ protected String selectedPortName; /** The CommPortIdentifier the user chose. */ protected CommPortIdentifier selectedPortIdentifier; /** The JComboBox for serial ports */ protected JComboBox serialPortsChoice; /** The JComboBox for parallel ports */ protected JComboBox parallelPortsChoice; /** The JComboBox for anything else */ protected JComboBox other; /** The SerialPort object */ protected SerialPort ttya; /** To display the chosen */ protected JLabel choice; /** Padding in the GUI */ protected final int PAD = 5; /** This will be called from either of the JComboBoxen when the * user selects any given item. */ public void itemStateChanged(ItemEvent e) { // Get the name selectedPortName = (String)((JComboBox)e.getSource()).getSelectedItem(); // Get the given CommPortIdentifier selectedPortIdentifier = (CommPortIdentifier)map.get(selectedPortName); // Display the name. choice.setText(selectedPortName); } /* The public "getter" to retrieve the chosen port by name. */ public String getSelectedName() { return selectedPortName; } /* The public "getter" to retrieve the selection by CommPortIdentifier. */ public CommPortIdentifier getSelectedIdentifier() { return selectedPortIdentifier; } /** A test program to show up this chooser. */ public static void main(String[] ap) { PortChooser c = new PortChooser(null); c.setVisible(true); // blocking wait System.out.println("You chose " + c.getSelectedName() + " (known by " + c.getSelectedIdentifier() + ")."); System.exit(0); } /** Construct a PortChooser --make the GUI and populate the ComboBoxes. */ public PortChooser(JFrame parent) { super(parent, "Port Chooser", true); makeGUI(); populate(); finishGUI(); } /** Build the GUI. You can ignore this for now if you have not * yet worked through the GUI chapter. Your mileage may vary. */ protected void makeGUI() { Container cp = getContentPane(); JPanel centerPanel = new JPanel(); cp.add(BorderLayout.CENTER, centerPanel); centerPanel.setLayout(new GridLayout(0,2, PAD, PAD)); centerPanel.add(new JLabel("Serial Ports", JLabel.RIGHT)); serialPortsChoice = new JComboBox(); centerPanel.add(serialPortsChoice); serialPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Parallel Ports", JLabel.RIGHT)); parallelPortsChoice = new JComboBox(); centerPanel.add(parallelPortsChoice); parallelPortsChoice.setEnabled(false); centerPanel.add(new JLabel("Unknown Ports", JLabel.RIGHT)); other = new JComboBox(); centerPanel.add(other); other.setEnabled(false); centerPanel.add(new JLabel("Your choice:", JLabel.RIGHT)); centerPanel.add(choice = new JLabel()); JButton okButton; cp.add(BorderLayout.SOUTH, okButton = new JButton("OK")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PortChooser.this.dispose(); } }); } /** Populate the ComboBoxes by asking the Java Communications API * what ports it has. Since the initial information comes from * a Properties file, it may not exactly reflect your hardware. */ protected void populate() { // get list of ports available on this particular computer, // by calling static method in CommPortIdentifier. Enumeration pList = CommPortIdentifier.getPortIdentifiers(); // Process the list, putting serial and parallel into ComboBoxes while (pList.hasMoreElements()) { CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(); // System.out.println("Port " + cpi.getName()); map.put(cpi.getName(), cpi); if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) { serialPortsChoice.setEnabled(true); serialPortsChoice.addItem(cpi.getName()); } else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) { parallelPortsChoice.setEnabled(true); parallelPortsChoice.addItem(cpi.getName()); } else { other.setEnabled(true); other.addItem(cpi.getName()); } } serialPortsChoice.setSelectedIndex(-1); parallelPortsChoice.setSelectedIndex(-1); } protected void finishGUI() { serialPortsChoice.addItemListener(this); parallelPortsChoice.addItemListener(this); other.addItemListener(this); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
}
</source>