Click here to Skip to main content
16,005,149 members
Home / Discussions / Java
   

Java

 
AnswerRe: plz help me Pin
42774803-Oct-09 8:50
42774803-Oct-09 8:50 
QuestionImplementing a Dictionary Pin
pinkett2-Oct-09 23:40
pinkett2-Oct-09 23:40 
AnswerRe: Implementing a Dictionary Pin
42774803-Oct-09 0:34
42774803-Oct-09 0:34 
QuestionJAVA Swing Tooltips Pin
simondopickup2-Oct-09 6:23
simondopickup2-Oct-09 6:23 
AnswerRe: JAVA Swing Tooltips Pin
42774802-Oct-09 22:07
42774802-Oct-09 22:07 
AnswerRe: JAVA Swing Tooltips Pin
simondopickup3-Oct-09 5:19
simondopickup3-Oct-09 5:19 
GeneralRe: JAVA Swing Tooltips Pin
42774803-Oct-09 8:52
42774803-Oct-09 8:52 
QuestionProblem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
pohcb_sonic1-Oct-09 19:17
pohcb_sonic1-Oct-09 19:17 
Hi guys,

I have a problem in the following simple program of mine stated below. It's a simple program which enables the sending/receiving of messages(in bytes) from one PC to another. I'm sending the messages to Serial Comm ports R232 with Rxtcomm library.

There are two classes namely; serialCommMain and Comms.
serialCommMain is the GUI portion while Comms is the serial port comm portion.

I'm trying to send the messages over to another application in VB 6.0 in the other PC, as my other PC is using Windows 95 and unable to have java installed.
Although my other PC is able to verify that data is being sent through, the message isn't being displayed. The VB application I've created is working properly.


Kindly need help/assistance. thanks.


The code is as follows:
serialCommMain:

<br />
<small><br />
package SerialComm;<br />
import org.apache.commons.io.EndianUtils;<br />
<br />
public class serialCommMain extends JFrame{<br />
//	Menu<br />
	<br />
		int indx = 9;<br />
		static double number;<br />
		static String Ans;<br />
		//Window//<br />
		private static final long serialVersionUID = 1L;<br />
		static Container pane;<br />
	 <br />
		static Insets insets;<br />
	    <br />
		static JTabbedPane Menu = new JTabbedPane();<br />
	    <br />
		Comms C1;<br />
		   <br />
		<br />
		<br />
		//Timers<br />
	    public Timer timer;<br />
	    public int speed = 500;<br />
	   <br />
	    <br />
	    <br />
		 //Global Variables <br />
	      public  byte[] BytetxtMsg;<br />
	      public  byte[] readMsg = new byte[400];<br />
	      static JButton BtnTransmit;<br />
		  static JButton BtnPause;<br />
	      byte START_BYTE = (byte) 0xAA;<br />
	      byte Checksum;<br />
	    <br />
	      <br />
	     //Receive & Transmit Msg<br />
	     static JTextArea txtRx, txtTx;<br />
	    <br />
	     static JPanel Rx = new JPanel();<br />
	     static JPanel Tx = new JPanel();<br />
	     static TitledBorder Tx_Rx, Tx_Tx;<br />
	    <br />
	     <br />
	     //TextBox<br />
	     static JLabel lblENT, lblDEC;<br />
	     static JFormattedTextField Entry;<br />
	     static JTextField Decipher;<br />
	     static JPanel ENT = new JPanel(new BorderLayout());<br />
	     static TitledBorder D_ENT;<br />
	     <br />
	     static JPanel DEC = new JPanel(new BorderLayout());<br />
	     static TitledBorder D_DEC;<br />
 <br />
	     <br />
		public serialCommMain() {<br />
			// TODO Auto-generated constructor stub<br />
			super();<br />
			BytetxtMsg = new byte[indx];<br />
	<br />
		}<br />
		<br />
	<br />
		/**<br />
		 * @param args<br />
		 */<br />
		public static void main(String[] args) {<br />
			// TODO Auto-generated method stub<br />
			showGUI();<br />
<br />
		}<br />
		<br />
		public static void showGUI(){<br />
	        //set look and feel<br />
			<br />
			<br />
			//try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} <br />
		    //catch (ClassNotFoundException e){}<br />
		   //catch (InstantiationException e) {}<br />
		   //catch (IllegalAccessException e) {}<br />
		   //catch (UnsupportedLookAndFeelException e) {}<br />
			<br />
			<br />
			<br />
			//for<br />
<br />
			//Create and set up Window<br />
			JFrame frame = new JFrame("Serial Comm.");<br />
			frame.setSize(800, 600);<br />
			frame.setLocation(150,50);<br />
			<br />
			<br />
			pane = frame.getContentPane();<br />
			insets = pane.getInsets();<br />
			pane.setLayout(null);<br />
			<br />
			<br />
			//Textareas<br />
			Tx_Rx =  BorderFactory.createTitledBorder(Tx_Rx, "Receive Message: ", TitledBorder.LEFT, <br />
	    			TitledBorder.CENTER, new Font("Verdana", Font.BOLD, 10));<br />
			<br />
			txtRx = new JTextArea(10,30);<br />
			txtRx.setEditable(false);<br />
			<br />
<br />
			Rx.add(txtRx);<br />
			Rx.setBorder(Tx_Rx);<br />
			pane.add(Rx);<br />
			<br />
			<br />
			Tx_Tx =  BorderFactory.createTitledBorder(Tx_Tx, "Transmit Message: ", TitledBorder.LEFT, <br />
	    			TitledBorder.CENTER, new Font("Verdana", Font.BOLD, 10));<br />
			<br />
			txtTx = new JTextArea(10,30);<br />
			txtTx.setEditable(false);<br />
			<br />
			<br />
			Tx.add(txtTx);<br />
			Tx.setBorder(Tx_Tx);<br />
			pane.add(Tx);<br />
			<br />
			<br />
			<br />
			//Entry<br />
			lblENT  = new JLabel("Transmit: ");<br />
			lblENT .setFont(new Font("Verdana", Font.BOLD, 10));<br />
					<br />
			D_ENT =  BorderFactory.createTitledBorder(D_ENT, "TX: ", TitledBorder.LEFT, <br />
	    			TitledBorder.CENTER, new Font("Verdana", Font.BOLD, 10));<br />
			<br />
			<br />
			Entry = new JFormattedTextField(Entry);<br />
			Entry.setValue(new Double(number));<br />
			Entry.setColumns(10);<br />
			Entry.addPropertyChangeListener("value", new ButtonListener());<br />
			<br />
			<br />
			<br />
			<br />
			ENT.add(Entry, BorderLayout.EAST);<br />
			ENT.add(lblENT, BorderLayout.WEST);<br />
			ENT.setBorder(D_ENT);<br />
			pane.add(ENT);<br />
			<br />
			<br />
			<br />
			<br />
			//Decipher<br />
			lblDEC  = new JLabel("Received: ");<br />
			lblDEC .setFont(new Font("Verdana", Font.BOLD, 10));<br />
					<br />
			D_DEC =  BorderFactory.createTitledBorder(D_DEC, "RX: ", TitledBorder.LEFT, <br />
	    			TitledBorder.CENTER, new Font("Verdana", Font.BOLD, 10));<br />
			<br />
			<br />
			Decipher = new JTextField(25);<br />
			Decipher.setEditable(false);<br />
			<br />
			DEC.add(Decipher, BorderLayout.EAST);<br />
			DEC.add(lblDEC, BorderLayout.WEST);<br />
			DEC.setBorder(D_DEC);<br />
			pane.add(DEC);<br />
			<br />
			<br />
			<br />
			//Buttons<br />
			BtnTransmit = new JButton("Transmit");<br />
			BtnTransmit.setFont(new Font("Verdana", Font.BOLD, 10));<br />
			pane.add(BtnTransmit);<br />
			BtnTransmit.addActionListener(new ButtonListener());<br />
			<br />
			BtnPause = new JButton("Pause");<br />
			BtnPause.setFont(new Font("Verdana", Font.BOLD, 10));	<br />
			pane.add(BtnPause);<br />
			BtnPause.addActionListener(new ButtonListener());<br />
			<br />
			  <br />
			<br />
			//Resolutions<br />
			Rx.setBounds(insets.left+5, insets.top+5, Rx.getPreferredSize().width, Rx.getPreferredSize().height);<br />
			Tx.setBounds(Rx.getX()+400, Rx.getY(), Tx.getPreferredSize().width, Tx.getPreferredSize().height);<br />
		    ENT.setBounds(Rx.getX(), Rx.getY()+200,  ENT.getPreferredSize().width, ENT.getPreferredSize().height);<br />
		    DEC.setBounds(Tx.getX(), Tx.getY()+200,  DEC.getPreferredSize().width, DEC.getPreferredSize().height);<br />
	    	<br />
		    BtnTransmit.setBounds(ENT.getX(), ENT.getY()+ 150, BtnTransmit.getPreferredSize().width, BtnTransmit.getPreferredSize().height);<br />
			BtnPause.setBounds(BtnTransmit.getX()+ 120, BtnTransmit.getY(), BtnPause.getPreferredSize().width, BtnPause.getPreferredSize().height);<br />
<br />
	  	  frame.addWindowListener(new WindowAdapter(){<br />
	            public void windowClosing(WindowEvent e){<br />
	               System.exit(0);   <br />
	            }<br />
	         });<br />
	  	  <br />
			//Display the Window<br />
			frame.setVisible(true);<br />
		}<br />
<br />
		<br />
	}<br />
<br />
	class ButtonListener extends serialCommMain implements ActionListener, PropertyChangeListener{<br />
	 <br />
		/**<br />
		 * <br />
		 */<br />
		private static final long serialVersionUID = 1L;<br />
<br />
		public ButtonListener(){<br />
			<br />
			<br />
			timer = new Timer();	<br />
			   <br />
			BytetxtMsg[0]= START_BYTE;<br />
		}<br />
		<br />
		 TimerTask Trx = new TimerTask(){<br />
<br />
<br />
				public void run() {<br />
					// TODO Auto-generated method stub<br />
					//   Display_Msg(indx);<br />
					   <br />
					  C1 = new Comms(); <br />
					  <br />
					   try{				 <br />
						  C1.sendBytes(BytetxtMsg);							<br />
					   } catch (Exception e) {<br />
			                System.err.println("ERROR: " + e.getMessage());<br />
			           }<br />
					  <br />
					   <br />
			       //     try {<br />
			                // Sleep for 10-secs<br />
			              //  Thread.sleep(10000);<br />
			    //        } catch (InterruptedException ex) {<br />
			     //       }		<br />
				}<br />
		     };<br />
		     <br />
		     <br />
		<br />
		     <br />
		<br />
			<br />
		<br />
		public void actionPerformed(ActionEvent E) {<br />
			// TODO Auto-generated method stub<br />
			Object Src = E.getSource();<br />
			<br />
							<br />
				<br />
				<br />
			<br />
			<br />
			if (Src == BtnTransmit){<br />
				<br />
				timer.scheduleAtFixedRate(Trx, 100, speed);<br />
				<br />
				number = ((Number)Entry.getValue()).doubleValue();<br />
					<br />
				System.out.println(number);<br />
				EndianUtils.writeSwappedDouble(BytetxtMsg, 2, reverse(number));<br />
			}	<br />
		}<br />
		<br />
		public static double reverse(double x) {<br />
	        ByteBuffer bbuf = ByteBuffer.allocate(8);<br />
	        bbuf.order(ByteOrder.LITTLE_ENDIAN);<br />
	        bbuf.putDouble(x);<br />
	        bbuf.order(ByteOrder.BIG_ENDIAN);<br />
	        return bbuf.getDouble(0);<br />
	    }<br />
		public void propertyChange(PropertyChangeEvent Evt) {<br />
			// TODO Auto-generated method stub<br />
	 <br />
	<br />
			}	<br />
			<br />
	}	<br />
		</small>


Comms:
<br />
<small><br />
<br />
package SerialComm;<br />
<br />
public class Comms extends serialCommMain implements SerialPortEventListener {<br />
private CommPortIdentifier commPortId;<br />
    private SerialPort serialPort;<br />
    private OutputStream outStream;<br />
    private InputStream inStream;<br />
    private byte[] readBuffer = new byte[400];<br />
    int SIZE;   <br />
    String S;<br />
    int DisplayLen = 0;<br />
    public Comms(){<br />
    	<br />
    	super();<br />
    	<br />
    	   try{<br />
			   <br />
				 <br />
	    		 connect("COM2");<br />
		         }catch (Exception e) {<br />
		          System.err.println("ERROR: " + e.getMessage());<br />
		          <br />
		       }<br />
			  <br />
    }<br />
<br />
    public void connect(String portName) throws IOException {<br />
        try {<br />
            <br />
            // Obtain a CommPortIdentifier object for the port you want to open<br />
            commPortId = CommPortIdentifier.getPortIdentifier(portName);<br />
         <br />
<br />
            // Get the port's ownership<br />
            serialPort = (SerialPort) commPortId.open(this.getClass().getName(), 2000);<br />
           <br />
            // Set the parameters of the connection.<br />
            setSerialPortParameters();<br />
<br />
            // Open the input and output streams for the connection. If they won't<br />
            // open, close the port before throwing an exception.<br />
            outStream = serialPort.getOutputStream();<br />
            inStream = serialPort.getInputStream();<br />
            <br />
            <br />
        } catch (NoSuchPortException e) {<br />
            throw new IOException(e.getMessage());<br />
        } catch (PortInUseException e) {<br />
            throw new IOException(e.getMessage());<br />
        } catch (IOException e) {<br />
            serialPort.close();<br />
            throw e;<br />
        }<br />
       <br />
<br />
    }<br />
<br />
 public void sendBytes (byte[] bytes)<br />
  {<br />
    try<br />
    {<br />
   <br />
    	SIZE = indx;<br />
    	for(int i = 0; i< SIZE; i++){	<br />
			 //Convert converted int arrayMsg to Hex in string (16 hexa), since Java's is 32Bits in byte<br />
			S = Integer.toString(ByteConversion(bytes[i]), 16) + " ";<br />
			txtTx.append(S.toUpperCase());<br />
			DisplayLen = txtTx.getLineCount();<br />
       <br />
    	}<br />
    	<br />
    	<br />
    	txtTx.append("\n");<br />
    	<br />
    	if (DisplayLen > 8){<br />
				txtTx.setText("");<br />
			 }<br />
 <br />
    	<br />
    	outStream.write (bytes, 0, bytes.length);<br />
    }<br />
   <br />
    catch (IOException e)<br />
    {<br />
      System.out.println("IOException" + e);<br />
    }      <br />
  }<br />
 <br />
 <br />
 /* public byte[] receiveBytes(int number) <br />
  {<br />
    byte[] bytes = null;<br />
    try<br />
    {<br />
      bytes = new byte[number];<br />
      inStream.read (bytes, 0, number);<br />
    }<br />
    catch (IOException e)<br />
    {<br />
      System.out.println("IOException" + e);<br />
    }<br />
    return bytes; <br />
  }*/<br />
<br />
<br />
 <br />
    /**<br />
     * Sets the serial port parameters<br />
     */<br />
    private void setSerialPortParameters() throws IOException {<br />
        int baudRate = 9600; // 9600bps<br />
<br />
        try {<br />
            // Set serial port to 9600bps-8N1..my favourite<br />
            serialPort.setSerialPortParams(<br />
                    baudRate,<br />
                    SerialPort.DATABITS_8,<br />
                    SerialPort.STOPBITS_1,<br />
                    SerialPort.PARITY_NONE);<br />
<br />
            serialPort.setFlowControlMode(<br />
                    SerialPort.FLOWCONTROL_NONE);<br />
        } catch (UnsupportedCommOperationException ex) {<br />
            throw new IOException("Unsupported serial port parameter");<br />
        }<br />
    }<br />
    <br />
	 public int ByteConversion(byte mySignedByte){<br />
	    		<br />
	 		ByteBuffer bb = ByteBuffer.allocate(4);<br />
<br />
	 		bb.put(new byte[] {0, 0, 0, mySignedByte});<br />
<br />
	 		bb.rewind();<br />
<br />
	 		int unsignedByteVal = bb.getInt();<br />
	 		<br />
	 		return unsignedByteVal;<br />
<br />
	 	}<br />
	 <br />
<br />
<br />
    <br />
public void disconnect() {<br />
<br />
if (serialPort != null) {<br />
        try {<br />
            // close the i/o streams.<br />
            outStream.close();<br />
            inStream.close();<br />
        } catch (IOException ex) {<br />
            // don't care<br />
        }<br />
        // Close the port.<br />
        serialPort.close();<br />
        serialPort = null;<br />
    }<br />
}<br />
<br />
<br />
        private void readSerial() {<br />
        	<br />
        	 <br />
            try {<br />
                int availableBytes = inStream.available();<br />
                if (availableBytes > 0) {<br />
                    // Read the serial port<br />
                    inStream.read(readBuffer, 0, availableBytes);<br />
<br />
                    // Print it out<br />
                    txtRx.append("Received :" +<br />
                            new String(readBuffer, 0, availableBytes));<br />
                }<br />
            } catch (IOException e) {<br />
            }<br />
        }<br />
<br />
<br />
  public void serialEvent(SerialPortEvent event) {<br />
	switch (event.getEventType()) {<br />
<br />
	case SerialPortEvent.BI:<br />
<br />
	case SerialPortEvent.OE:<br />
<br />
	case SerialPortEvent.FE:<br />
<br />
	case SerialPortEvent.PE:<br />
<br />
	case SerialPortEvent.CD:<br />
<br />
	case SerialPortEvent.CTS:<br />
<br />
	case SerialPortEvent.DSR:<br />
<br />
	case SerialPortEvent.RI:<br />
<br />
	case SerialPortEvent.OUTPUT_BUFFER_EMPTY:<br />
	    break;<br />
<br />
	case SerialPortEvent.DATA_AVAILABLE:<br />
	    readSerial();<br />
<br />
	    break;<br />
	}<br />
    } <br />
<br />
    <br />
}<br />
</small>


The errors I've got:
<small><br />
<br />
1500.0 //output of value 1500 from textfield.<br />
<br />
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 9<br />
	at org.apache.commons.io.EndianUtils.writeSwappedLong(EndianUtils.java:209)<br />
	at org.apache.commons.io.EndianUtils.writeSwappedDouble(EndianUtils.java:263)<br />
	at SerialComm.ButtonListener.actionPerformed(serialCommMain.java:303)<br />
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)<br />
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)<br />
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)<br />
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)<br />
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)<br />
	at java.awt.Component.processMouseEvent(Unknown Source)<br />
	at javax.swing.JComponent.processMouseEvent(Unknown Source)<br />
	at java.awt.Component.processEvent(Unknown Source)<br />
	at java.awt.Container.processEvent(Unknown Source)<br />
	at java.awt.Component.dispatchEventImpl(Unknown Source)<br />
	at java.awt.Container.dispatchEventImpl(Unknown Source)<br />
	at java.awt.Component.dispatchEvent(Unknown Source)<br />
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)<br />
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)<br />
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)<br />
	at java.awt.Container.dispatchEventImpl(Unknown Source)<br />
	at java.awt.Window.dispatchEventImpl(Unknown Source)<br />
	at java.awt.Component.dispatchEvent(Unknown Source)<br />
	at java.awt.EventQueue.dispatchEvent(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)<br />
	at java.awt.EventDispatchThread.run(Unknown Source)<br />
Stable Library<br />
=========================================<br />
Native lib Version = RXTX-2.1-7<br />
Java lib Version   = RXTX-2.1-7<br />
ERROR: SerialComm.Comms<br />
ERROR: null<br />
ERROR: SerialComm.Comms<br />
ERROR: null<br />
<br />
<br />
<br />
</small>


DA: http://www.pohcbsonic.deviantart.com/
Blog: http://www.pohcbsonicx.blogspot.com/
Homepage: http://www.pohcbsonic.tripod.com/

AnswerRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
David Skelly1-Oct-09 22:20
David Skelly1-Oct-09 22:20 
AnswerRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
42774802-Oct-09 22:12
42774802-Oct-09 22:12 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
pohcb_sonic3-Oct-09 4:44
pohcb_sonic3-Oct-09 4:44 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
pohcb_sonic3-Oct-09 4:44
pohcb_sonic3-Oct-09 4:44 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
Richard MacCutchan3-Oct-09 5:39
mveRichard MacCutchan3-Oct-09 5:39 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
42774803-Oct-09 8:53
42774803-Oct-09 8:53 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
Richard MacCutchan3-Oct-09 21:38
mveRichard MacCutchan3-Oct-09 21:38 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
42774804-Oct-09 0:10
42774804-Oct-09 0:10 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
Richard MacCutchan4-Oct-09 1:15
mveRichard MacCutchan4-Oct-09 1:15 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
42774804-Oct-09 2:40
42774804-Oct-09 2:40 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
Richard MacCutchan4-Oct-09 4:01
mveRichard MacCutchan4-Oct-09 4:01 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) [modified] Pin
pohcb_sonic4-Oct-09 17:21
pohcb_sonic4-Oct-09 17:21 
AnswerRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
42774804-Oct-09 22:15
42774804-Oct-09 22:15 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
regionwar5-Oct-09 2:35
regionwar5-Oct-09 2:35 
GeneralRe: Problem : Reading and Writing of Byte[] Array Messages to Serial Comm (Serial Port RS232) Pin
pohcb_sonic6-Oct-09 14:18
pohcb_sonic6-Oct-09 14:18 
Generalhelp regarding j2ee Pin
madhu91241-Oct-09 1:24
madhu91241-Oct-09 1:24 
GeneralRe: help regarding j2ee Pin
Nagy Vilmos1-Oct-09 3:12
professionalNagy Vilmos1-Oct-09 3:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.