I am woring on simple example to use Wii Remote control on a Ev3 using Lejos 0.9.1-beta. I am using WiiRemoteJ and Bluecove 2.1.1-SNAPSHOT and the example works on my Mac, but I have the next error on my EV3:
Native Library bluecove_arm not available WR
I found a solution on the next link, but I don't know how to compile and create a new jar inside of the EV3.
Can you help me please?
This is my code
package test;
import wiiremotej.*;
import wiiremotej.event.*;
import com.intel.bluetooth.BlueCoveConfigProperties;
import lejos.hardware.lcd.LCD;
public class Wii extends WiiRemoteAdapter {
private WiiRemote remote;
private static boolean accelerometerSource = true;
private static int y = 0;
private static int lastY = 0;
public static void main(String args[]) {
System.setProperty(BlueCoveConfigProperties.PROPERTY_JSR_82_PSM_MINIMUM_OFF, "true");
WiiRemoteJ.setConsoleLoggingOff();
try {
LCD.drawString("Buscando WR", 0, 2);
WiiRemote remote = null;
while (remote == null) {
try {
remote = WiiRemoteJ.findRemote();
LCD.drawString("WR encontrado", 0, 2);
}
catch (Exception e) {
remote = null;
LCD.drawString("ERROR", 0, 2);
}
}
remote.addWiiRemoteListener(new Wii(remote));
remote.setAccelerometerEnabled(true);
remote.setSpeakerEnabled(false);
remote.setIRSensorEnabled(false, WRIREvent.BASIC);
remote.setLEDIlluminated(0, false);
remote.getButtonMaps().add(new ButtonMap(WRButtonEvent.HOME, ButtonMap.NUNCHUK, WRNunchukExtensionEvent.C,
new int[] { java.awt.event.KeyEvent.VK_CONTROL }, java.awt.event.InputEvent.BUTTON1_MASK, 0, -1));
final WiiRemote remoteF = remote;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
remoteF.disconnect();
}
}));
} catch (Exception e) {
e.printStackTrace();
}
}
public Wii(WiiRemote remote) {
this.remote = remote;
}
public void accelerationInputReceived(WRAccelerationEvent evt) {
//Doblar derecha y izquierda
if(accelerometerSource){
lastY = y;
//300 es el centro
y = (int)(evt.getYAcceleration()/5*300)+300;
if( y < lastY - 2){
LCD.drawString("Izquierda", 3, 2);
}
else if( y > lastY + 2){
LCD.drawString("Derecha", 3, 2);
}
}
}
public void buttonInputReceived(WRButtonEvent evt) {
if (evt.isPressed(WRButtonEvent.ONE)){
LCD.drawString("Avanzar", 5, 2);
}
if (evt.isPressed(WRButtonEvent.TWO)){
LCD.drawString("Retroceder", 5, 2);
}
}
public void disconnected() {
System.out.println("Remote disconnected... Please Wii again.");
System.exit(0);
}
public void statusReported(WRStatusEvent evt) {
}
public void IRInputReceived(WRIREvent evt) {
}
public void extensionConnected(WiiRemoteExtension extension) {
System.out.println("Extension connected!");
try {
remote.setExtensionEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public void extensionPartiallyInserted() {
System.out.println("Extension partially inserted. Push it in more next time!");
}
public void extensionUnknown() {
System.out.println("Extension unknown. Did you try to plug in a toaster or something?");
}
public void extensionDisconnected(WiiRemoteExtension extension) {
System.out.println("Extension disconnected. Why'd you unplug it, eh?");
}
}
Related
Hey guys,
I'm trying to make a digital version of this Simon says game, and I can't get the path entered from the player to save correctly.
Every color corresponds to a number, so Green = 0, Red = 1, Yellow = 2, and Yellow = 3.
The problem is that the playerPath is never resetting, so it will just add the current entered path to the path of last round, making it seem incorrect when compared to the original turnPath which is just a substring of the fullPath.
I attached all of the code below. Any help would be greatly appreciated.
import java.awt.Color;
import java.awt.event.*;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Simon implements ActionListener {
static JFrame f = new JFrame();
static JButton greenButton = new JButton("Green");
static JButton redButton = new JButton("Red");
static JButton yellowButton = new JButton("Yellow");
static JButton blueButton = new JButton("Blue");
static String playerPath = "";
static int turn = 1;
static int lostGame = 0;
static Random rand = new Random();
static String fullPath = "";
static String turnPath;
Simon() {
for (int i = 0; i < 100; i++) {
int maxIndex = 4;
int randomIndex = rand.nextInt(maxIndex);
fullPath = fullPath + randomIndex;
}
turnPath = fullPath.substring(0,turn);
prepareGUI();
buttonProperties();
}
public void prepareGUI() {
f.setSize(415,435);
f.setLayout(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void buttonProperties() {
greenButton.setBounds(0,0,200,200);
redButton.setBounds(200,0,200,200);
yellowButton.setBounds(0,200,200,200);
blueButton.setBounds(200,200,200,200);
greenButton.setBackground(Color.black);
redButton.setBackground(Color.black);
yellowButton.setBackground(Color.black);
blueButton.setBackground(Color.black);
greenButton.setOpaque(true);
redButton.setOpaque(true);
yellowButton.setOpaque(true);
blueButton.setOpaque(true);
greenButton.setForeground(Color.green);
redButton.setForeground(Color.red);
yellowButton.setForeground(Color.yellow);
blueButton.setForeground(Color.blue);
f.add(greenButton);
f.add(redButton);
f.add(yellowButton);
f.add(blueButton);
greenButton.addActionListener(this);
redButton.addActionListener(this);
yellowButton.addActionListener(this);
blueButton.addActionListener(this);
greenButton.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
greenButton.setBackground(Color.green);
}
#Override
public void mouseReleased(MouseEvent e) {
greenButton.setBackground(Color.black);
}
});
redButton.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
redButton.setBackground(Color.red);
}
#Override
public void mouseReleased(MouseEvent e) {
redButton.setBackground(Color.black);
}
});
yellowButton.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
yellowButton.setBackground(Color.yellow);
}
#Override
public void mouseReleased(MouseEvent e) {
yellowButton.setBackground(Color.black);
}
});
blueButton.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
blueButton.setBackground(Color.blue);
}
#Override
public void mouseReleased(MouseEvent e) {
blueButton.setBackground(Color.black);
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
//Recording user input
if (e.getActionCommand().matches("Green")) {
playerPath += "0";
}
else if (e.getActionCommand().matches("Red")) {
playerPath += "1";
}
else if (e.getActionCommand().matches("Yellow")) {
playerPath += "2";
}
else if (e.getActionCommand().matches("Blue")) {
playerPath += "3";
}
}
public static void main(String[] args) {
while (lostGame < 1) {
lightButtons();
try {
Thread.sleep(1000 + (1000*turn));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (playerPath.equals(turnPath)) {
playerPath = "";
turn++;
}
else if (!(playerPath.equals(turnPath))) {
lostGame += 1;
System.out.println(playerPath);
System.out.println(turnPath);
System.out.println("GAME OVER" + '\n' + "Your Score: " + (turn-1));
}
}
}
public static void lightButtons() {
new Simon();
for (int i = 0; i < turnPath.length(); i++) { // iterates through string based on turn number
if (turnPath.charAt(i) == '0') {
greenButton.setBackground(Color.green); //* "Flashes" a color at appropriate box
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
greenButton.setBackground(Color.black); //*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if (turnPath.charAt(i) == '1') {
redButton.setBackground(Color.red); //*
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
redButton.setBackground(Color.black); //*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if (turnPath.charAt(i) == '2') {
yellowButton.setBackground(Color.yellow); //*
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
yellowButton.setBackground(Color.black); //*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if (turnPath.charAt(i) == '3') {
blueButton.setBackground(Color.blue); //*
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
blueButton.setBackground(Color.black); //*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} ```
You can reset a String variable by writing playerPath = "";
Using code examples from stockoverflow I made a class to receive data over TCP/IP.
Class code below. It is working OK and I do receive data from other PC.
recPositions Map is build correctly. After transmission is finished I can display all data I received using getRecPositions()
This thread is started in other class that build simple HMI screen.
Thread runs and display data received from other PC.
Problem is I would like to access same data in MainWindow class (HMI)
but it always show that nothing was received.
Class MainWindow below (not all of it since there is lots of useless pushbuttons and so on)
At the very bottom I have pushbutton that should display how many positions were recorded (elements in Map) but it always show 0.
Code snippet from push button update.
System.out.println(dataServer.getRecPositions().size())
So at some point I am doing something wrong.
Thread starts and runs and I can see incoming positions. At some point after I received "EOT" I display received positions stored in Map. But when I tried to display the size of Map in main window it always show 0.
/*
* Simple data server for receiving string data from IIWA robot
*/
public class SimpleDataServer implements Runnable {
Map<Integer, String> recPositions = new HashMap<>();
Server1Connection oneconnection;
ServerSocket echoServer = null;
Socket clientSocket = null;
int port;
boolean reset = false;
public SimpleDataServer( int port ) {
this.port = port;
}
public void stopServer() {
System.out.println( "Simple data server stopped" );
}
public void startServer() {
// Try to open a server socket on the given port
// Note that we can't choose a port less than 1024 if we are not
// privileged users (root)
try {
echoServer = new ServerSocket(port);
}
catch (IOException e) {
System.out.println(e);
}
System.out.println( "Waiting for connections. Only one connection is allowed." );
// Create a socket object from the ServerSocket to listen and accept connections.
// Use Server1Connection to process the connection.
while ( true ) {
try {
clientSocket = echoServer.accept();
oneconnection = new Server1Connection(clientSocket, this);
oneconnection.run();
if(isReset()) {
setReset(false);
System.out.println("Recording finished");
System.out.println("DEBUG:" + this.getRecPositions().size() + " positions recorded: " + this.getRecPositions());
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
#Override
public void run() {
int port = this.port;
SimpleDataServer server = new SimpleDataServer( port );
server.startServer();
}
public Map<Integer, String> getRecPositions() {
return recPositions;
}
public void setRecPositions(Map<Integer, String> recPositions) {
this.recPositions = recPositions;
}
public boolean isReset() {
return reset;
}
public void setReset(boolean reset) {
this.reset = reset;
}
}
class Server1Connection {
BufferedReader is;
PrintStream os;
Socket clientSocket;
SimpleDataServer server;
public Server1Connection(Socket clientSocket, SimpleDataServer server) {
this.clientSocket = clientSocket;
this.server = server;
System.out.println( "Connection established with: " + clientSocket );
try {
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public Map<Integer, String> getPositions() {
return server.getRecPositions();
}
public void run() {
String line; //whole line recevied
String segment = null; //single segment from line using comma delimiter
List<String> stringsList;
try {
boolean serverStop = false;
//server runs here
while (true)
{
line = is.readLine();
System.out.println( "DEBUG Server Received: " + line );
//check is string is not empty
if (line.equals(null)) {
System.err.println("Empty String received");
break;
}
stringsList = new ArrayList<String>(Arrays.asList(line.split(";")));
if (!stringsList.isEmpty()) {
stringsList.set(0, stringsList.get(0).replaceAll("\\s+",""));
stringsList.set((stringsList.size()-1), stringsList.get(stringsList.size()-1).replaceAll("\\s+",""));
String lastSegment = stringsList.get((stringsList.size()-1));
if (lastSegment.equals("ETX") || lastSegment.equals("EOT")) {
switch (stringsList.get(0)) {
case "MSG":
stringsList.remove(0);
stringsList.remove(stringsList.size()-1);
System.out.println("Message: " + stringsList.toString());
break;
case "POS":
// for (String blah : stringsList) {
// System.out.println("DEBUG" + blah);
// }
iiwaPosfromString iiwaPos = new iiwaPosfromString(stringsList.get(1), stringsList.get(2));
System.out.println("DEBUG Position number: " + iiwaPos.posNum + " ; " + iiwaPos.toString());
if (iiwaPos.getPosNum() > 0) {
server.getRecPositions().put(iiwaPos.getPosNum(), iiwaPos.toString());
}
break;
case "EOT":
case "EXT":
//ignore handled later
break;
default:
System.err.println("Ausgebombt!");
break;
}
}
//ETX End Of Text - dump data to screen - close current connection
if(lastSegment.equals("ETX")) {
System.out.println("End of Text received");
break;
}
//EOT End Of Transmission - shuts down server
if(lastSegment.equals("EOT")) {
System.out.println("End of Transmission received");
serverStop = true;
server.setReset(true);
break;
}
System.err.println("No correct end string!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
} else {
System.out.println("Empty String received");
break;
}
}
System.out.println( "Connection closed." );
is.close();
os.close();
clientSocket.close();
if ( serverStop ) server.stopServer();
} catch (IOException e) {
System.out.println(e);
}
}
public class iiwaPosfromString {
private double posX;
private double posY;
private double posZ;
private double posA;
private double posB;
private double posC;
private int posNum;
public iiwaPosfromString(String posNum, String posString) {
List <String>stringsList = new ArrayList<String>(Arrays.asList(posString.split(" ")));
for (int i = 0; i < stringsList.size(); i++) {
String newElement = stringsList.get(i);
newElement = newElement.replaceAll("[^\\d.]", "");
stringsList.set(i, newElement);
}
this.setPosNum(Integer.parseInt(posNum));
this.setPosX(Double.parseDouble(stringsList.get(1)));
this.setPosY(Double.parseDouble(stringsList.get(2)));
this.setPosZ(Double.parseDouble(stringsList.get(3)));
//this is stupid and don't do that
//from right to left, string to double, change radians to degrees, format to two decimals(string), string to double again
this.setPosA(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
this.setPosB(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
this.setPosC(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
}
public double getPosX() {
return posX;
}
public void setPosX(double posX) {
this.posX = posX;
}
public double getPosY() {
return posY;
}
public void setPosY(double posY) {
this.posY = posY;
}
public double getPosZ() {
return posZ;
}
public void setPosZ(double posZ) {
this.posZ = posZ;
}
public double getPosA() {
return posA;
}
public void setPosA(double posA) {
this.posA = posA;
}
public double getPosB() {
return posB;
}
public void setPosB(double posB) {
this.posB = posB;
}
public double getPosC() {
return posC;
}
public void setPosC(double posC) {
this.posC = posC;
}
#Override
public String toString() {
return "<" +
"X: " + getPosX() + ", " +
"Y: " + getPosY() + ", " +
"Z: " + getPosZ() + ", " +
"A: " + getPosA() + ", " +
"B: " + getPosB() + ", " +
"C: " + getPosC() +
">";
}
public int getPosNum() {
return posNum;
}
public void setPosNum(int posNum) {
this.posNum = posNum;
}
}
}
public class MainWindow {
private Thread dataServerThread;
private SimpleDataServer dataServer;
private XmlParserGlobalVarsRD globalVarPLC, globalVarKRC;
private JFrame frame;
private JTextField simpleWorkingDirStiffness;
private JTextField simpleWorkingDirAdditionalForce;
private JTextField simpleTravelDistance;
private JTextField simpleTravelVelocity;
private JTextField simpleTotalTime;
private JTextField simpleTheoreticalDepth;
private JTextField simpleZProgress;
private JComboBox oscillationMode;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
final JCheckBox emptyScanCycle = new JCheckBox("VRSI Scan Cycle Plain Fasteners");
//set data server thread and start it
dataServer = new SimpleDataServer(30008);
dataServerThread = new Thread(dataServer);
dataServerThread.setDaemon(true);
dataServerThread.start();
...
JButton pbUpdate = new JButton("UPDATE");
pbUpdate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println(dataServer.getRecPositions().size())
}
});
pbUpdate.setBounds(210, 176, 90, 28);
frame.getContentPane().add(pbUpdate);
}
I believe the issue is in your SimpleDataServer.run method. You are creating a separate instance of SimpleDataServer from WITHIN your SimpleDataServer instance. Therefore, all of the communication is taking place in an object that your MainWindow has no direct reference to. I believe your SimpleDataServer.run method should look like this:
#Override
public void run() {
this.startServer();
}
As with basically every exchanger task, I have a producer filling up an empty buffer2, a consumer clearing a full buffer1 and when each thread is done, they should exchange their respective buffers.
I am really unsure about where and how to apply the exchange. I defined readyconsumer and readyproducer as booleans, so that a third thread can check whether it's time to exchange the buffers once both are true. This should solve the problem I had doing it with two threads, where the program was stuck with both threads at wait() (which it unfortunately still is).
This is what the code looks like at the moment. Can anyone help me in which class I have to exchange and at what point in the code? Thank you very much in advance!
class Buffer {
static boolean readyconsumer, readyproducer = false;
volatile int count; // number of put actions
static int max = 10;
Buffer() {
count = 0;
}
public synchronized void put() {
if (count == max) {
readyproducer = true;
System.out.println(" wait ");
try {
wait();
} catch (InterruptedException e) {
}
}
count++;
System.out.println("put " + count);
notifyAll();
}
public synchronized void get() {
if (count == 0) {
readyconsumer = true;
System.out.println(" wait");
try {
wait();
} catch (InterruptedException e) {
}
}
count--;
System.out.println("get " + count);
notifyAll();
}
}
class CheckandSwitch extends ProdCon {
public void run() {
while (true) {
if (Buffer.readyconsumer && Buffer.readyproducer) {
try {
ProdCon.buffer2 = exchanger.exchange(ProdCon.buffer1);
ProdCon.buffer1 = exchanger.exchange(ProdCon.buffer2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Buffer.readyconsumer = false;
Buffer.readyproducer = false;
buffer1.count = 0;
buffer2.count = 10;
notifyAll();
}
}
}
}
class Consumer extends ProdCon {
static Buffer buffer;
Consumer(Buffer b) {
super();
buffer = b;
b.count = 10;
}
public void run() {
while (true) {
consume();
buffer.get();
}
}
private void consume() {
System.out.println("consume");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
class Producer extends ProdCon {
static Buffer buffer;
Producer(Buffer b) {
super();
buffer = b;
b.count = 0;
}
public void run() {
while (true) {
produce();
buffer.put();
}
}
private void produce() {
System.out.println("produce ");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
import java.util.concurrent.*;
public class ProdCon extends Thread {
static Exchanger<Buffer> exchanger = new Exchanger<Buffer>();
static Buffer buffer1, buffer2 = null;
public static void main(String[] args) {
buffer1 = new Buffer();
buffer2 = new Buffer();
new Consumer(buffer1).start();
new Producer(buffer2).start();
new CheckandSwitch().start();
}
}
You could use an Exchanger.
Here's the code from the javadoc tweaked into a working example.
class DataBuffer<T> {
T data = null;
public boolean isFull() {
return data != null;
}
public boolean isEmpty() {
return data == null;
}
public T get() {
T d = data;
data = null;
return d;
}
public void put(T data) {
this.data = data;
}
}
class FillAndEmpty {
Exchanger<DataBuffer<Integer>> exchanger = new Exchanger<>();
DataBuffer<Integer> initialEmptyBuffer = new DataBuffer<>();
DataBuffer<Integer> initialFullBuffer = new DataBuffer<>();
int countDown = 10;
class FillingLoop implements Runnable {
#Override
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null && countDown > 0) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void addToBuffer(DataBuffer<Integer> currentBuffer) {
currentBuffer.put(countDown--);
}
}
class EmptyingLoop implements Runnable {
#Override
public void run() {
DataBuffer<Integer> currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void takeFromBuffer(DataBuffer<Integer> currentBuffer) {
System.out.println(currentBuffer.get());
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}
public void test() {
System.out.println("Hello");
new FillAndEmpty().start();
}
I have code to stored the value using RMS in J2ME. It's working fine on emulator. So, my first problem is
When i restart the emulator all the stored values are deleted.
Stored values are showing in the emulator, but not in the Mobile, in which i am testing my application.
I am using NetBeans for developing my J2ME application.
===UPDATED===
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
public class TryNew extends MIDlet implements CommandListener, ItemCommandListener {
private RecordStore record;
private StringItem registered;
static final String REC_STORE = "SORT";
//Button existUser;
Display display = null;
private Ticker ticker;
Form form = null;
Form form1 = null;
TextField tb, tb1, tb2, tb3;
ChoiceGroup operator = null;
String str = null;
Command backCommand = new Command("Back", Command.BACK, 0);
Command loginCommand = new Command("Login", Command.OK, 2);
Command saveCommand = new Command("Save New", Command.OK, 1);
Command sendCommand = new Command("Send", Command.OK, 2);
Command selectCommand = new Command("Select", Command.OK, 0);
Command exitCommand = new Command("Exit", Command.STOP, 3);
private ValidateLogin ValidateLogin;
public TryNew() {
}
public void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
form = new Form("Login");
registered = new StringItem("", "Registered ?", StringItem.BUTTON);
form1 = new Form("Home");
tb = new TextField("Login Id: ", "", 10, TextField.PHONENUMBER);//TextField.PHONENUMBER
tb1 = new TextField("Password: ", "", 30, TextField.PASSWORD);
operator = new ChoiceGroup("Select Website", Choice.POPUP, new String[]{"Game", "Joke", "SMS"}, null);
form.append(tb);
form.append(tb1);
form.append(operator);
form.append(registered);
registered.setDefaultCommand(selectCommand);
registered.setItemCommandListener(this);
form.addCommand(saveCommand);
ticker = new Ticker("Welcome Screen");
form.addCommand(loginCommand);
form.addCommand(selectCommand);
form.addCommand(exitCommand);
// existUser = new StringItem(null, "Registered ?");
// form.append(existUser);
form.setCommandListener(this);
form1.addCommand(exitCommand);
form1.addCommand(sendCommand);
form1.setCommandListener(this);
form.setTicker(ticker);
display.setCurrent(form);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
void showMessage(String message, Displayable displayable) {
Alert alert = new Alert("");
alert.setTitle("Error");
alert.setString(message);
alert.setType(AlertType.ERROR);
alert.setTimeout(5000);
display.setCurrent(alert, displayable);
}
public void commandAction(Command c, Displayable d) {
if (c == exitCommand) {
destroyApp(true);
notifyDestroyed();
} else if (c == backCommand) {
display.setCurrent(form);
} else if (c == loginCommand) {
ValidateLogin = new ValidateLogin(this);
ValidateLogin.start();
ValidateLogin.validateLogin(tb.getString(), tb1.getString(), operator.getString(operator.getSelectedIndex()));
} else if (c == saveCommand) {
openRecord();
writeRecord(tb.getString(), tb1.getString(), operator.getString(operator.getSelectedIndex()));
closeRecord();
showAlert("Login Credential Saved Successfully !!");
}
}
////==============================================================================/////
/// Record Management
public void openRecord() {
try {
record = RecordStore.openRecordStore(REC_STORE, true);
} catch (Exception e) {
db(e.toString());
}
}
public void closeRecord() {
try {
record.closeRecordStore();
} catch (Exception e) {
db(e.toString());
}
}
public void deleteRecord() {
if (RecordStore.listRecordStores() != null) {
try {
RecordStore.deleteRecordStore(REC_STORE);
} catch (Exception e) {
db(e.toString());
}
}
}
public void writeRecord(String login_id, String pwd, String operator_name) {
String credential = login_id + "," + pwd + "," + operator_name;
byte[] rec = credential.getBytes();
try {
if (login_id.length() > 10 || login_id.length() < 10) {
showAlert("Please Enter valid Login Id");
} else if (pwd.length() < 1) {
showAlert("Please Password !!");
} else {
record.addRecord(rec, 0, rec.length);
}
} catch (Exception e) {
db(e.toString());
}
}
private void showAlert(String err) {
Alert a = new Alert("");
a.setString(err);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
}
public void readRecord() {
try {
if (record.getNumRecords() > 0) {
Comparator comp = new Comparator();
RecordEnumeration re = record.enumerateRecords(null, comp, false);
while (re.hasNextElement()) {
String str = new String(re.nextRecord());
showAlert(str);
}
}
} catch (Exception e) {
db(e.toString());
}
}
private void db(String error) {
System.err.println("Exception: " + error);
}
public void commandAction(Command c, Item item) {
if (c == selectCommand && item == registered) {
openRecord();
readRecord();
closeRecord();
}
}
class Comparator implements RecordComparator {
public int compare(byte[] rec1, byte[] rec2) {
String str1 = new String(rec1);
String str2 = new String(rec2);
int result = str1.compareTo(str2);
if (result == 0) {
return RecordComparator.EQUIVALENT;
} else if (result < 0) {
return RecordComparator.PRECEDES;
} else {
return RecordComparator.FOLLOWS;
}
}
}
class ValidateLogin implements Runnable {
TryNew midlet;
private Display display;
String login_id;
String pwd;
String operator_name;
public ValidateLogin(TryNew midlet) {
this.midlet = midlet;
display = Display.getDisplay(midlet);
}
public void start() {
Thread t = new Thread(this);
t.start();
}
public void run() {
if (login_id.length() > 10 || login_id.length() < 10) {
showAlert("Please Enter valid Login Id");
} else if (pwd.length() < 1) {
showAlert("Please Password !!");
} else {
showHome();
}
}
/* This method takes input from user like text and pass
to servlet */
public void validateLogin(String login_id, String pwd, String operator_name) {
this.login_id = login_id;
this.pwd = pwd;
this.operator_name = operator_name;
}
/* Display Error On screen*/
private void showAlert(String err) {
Alert a = new Alert("");
a.setString(err);
a.setTimeout(Alert.FOREVER);
display.setCurrent(a);
}
private void showHome() {
tb2 = new TextField("To: ", "", 30, TextField.PHONENUMBER);
tb3 = new TextField("Message: ", "", 300, TextField.ANY);
form1.append(tb2);
form1.append(tb3);
form1.addCommand(loginCommand);
//display.setCurrent(tb3);
display.setCurrent(form1);
}
};
}
This is what i got, when i click the Manage Emulator
You need to fix the storage_root of your app in WTK,
Whenever you start your enulator it would refer to same storage_root, by default it creates different data files for each session
I want to prevent multiple instances of application being launched in java. I know 2 methods for this:
locking file
locking socket
But which is one is more efficient and good to use? Which one should I use?
Any other solution to do the same are also welcome.
There is a library called jUnique which does that and will save you the bother of implementing it yourself.
If you deploy with Java WebStart the SingleInstanceService does this.
See http://download.oracle.com/javase/6/docs/technotes/guides/javaws/developersguide/faq.html#218
EDIT: I tried that with Win200864b(version isn't important) and alive JFrame and move toFront() or Iconified in SystemTray with JFrame.DO_NOTHING_ON_CLOSE
public interface ApplicationStartedListener {
void applicationStarted();
void foreignApplicationStarted(String name);
void messageArrived(Object obj);
}
//
import java.io.Serializable;
public class ClassCheck implements Serializable {
private static final long serialVersionUID = 1L;
private String className = null;
public ClassCheck() {
}
public ClassCheck(String className) {
setClassName(className);
}
#Override
public String toString() {
return this.className;
}
public String getClassName() {
return this.className;
}
public void setClassName(String className) {
this.className = className;
}
}
//
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class RunOnceFromFile {
private SingleInstanceController sic = null;
private JFrame frame;
private Robot r;
private JTextField tf;
public RunOnceFromFile() {
try {
r = new Robot();
} catch (AWTException ex) {
ex.printStackTrace();
}
sic = new SingleInstanceController(new File(System.getProperty("java.io.tmpdir") + "Example.file"), "sic_example_application");
if (sic.isOtherInstanceRunning()) {
sic.sendMessageToRunningApplication("toFront");
System.exit(0);
} else {
frame = new JFrame("TEST");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
tf = new JTextField("JTextFiled");
frame.add(tf, BorderLayout.NORTH);
frame.setExtendedState(Frame.ICONIFIED);
frame.setExtendedState(Frame.NORMAL);
frame.setExtendedState(frame.getExtendedState() | JFrame.ICONIFIED);
frame.setExtendedState(frame.getExtendedState() & (~JFrame.ICONIFIED));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
sic.registerApplication();
sic.addApplicationStartedListener(new ApplicationStartedListener() {
public void applicationStarted() {
Runnable doRun = new Runnable() {
public void run() {
frame.toFront();
}
};
SwingUtilities.invokeLater(doRun);
}
public void foreignApplicationStarted(final String name) {
Runnable doRun = new Runnable() {
public void run() {
frame.toFront();
}
};
SwingUtilities.invokeLater(doRun);
}
public void messageArrived(final Object obj) {
Runnable doRun = new Runnable() {//activateWindow(frame);
public void run() {
frame.toFront();
}
};
SwingUtilities.invokeLater(doRun);
}
private void activateWindow(JFrame frame) {
frame.setExtendedState(Frame.ICONIFIED);
frame.setExtendedState(Frame.NORMAL);
frame.setAlwaysOnTop(true);
frame.setAlwaysOnTop(false);
Point location = MouseInfo.getPointerInfo().getLocation();
Point locationOnScreen = frame.getLocationOnScreen();
r.mouseMove(locationOnScreen.x + 100, locationOnScreen.y + 10);
r.mousePress(InputEvent.BUTTON1_MASK);
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(location.x, location.y);
}
});
}
}
public static void main(String[] args) {
RunOnceFromFile roff = new RunOnceFromFile();
}
}
//
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class SingleInstanceController {
private String appname = null;
private Socket client = null;
private File file = null;
private ArrayList<ApplicationStartedListener> listener = null;
private ObjectInputStream ois = null;
private ObjectOutputStream oos = null;
private boolean result = false;
private ServerSocket server = null;
public SingleInstanceController(String appname) {
this(new File(System.getProperty("java.io.tmpdir") + "/923jhakE53Kk9235b43.6m7"), appname);
}
public SingleInstanceController(File file, String appname) {
this.file = file;
this.appname = appname;
this.listener = new ArrayList<ApplicationStartedListener>();
}
public void addApplicationStartedListener(ApplicationStartedListener asl) {
this.listener.add(asl);
}
public void removeApplicationStartedListener(ApplicationStartedListener asl) {
this.listener.remove(asl);
}
public boolean isOtherInstanceRunning() {
if (!this.file.exists()) {
return false;
}
return sendMessageToRunningApplication(new ClassCheck(this.appname));
}
public boolean sendMessageToRunningApplication(final Object obj) {
this.result = false;
try {
this.client = new Socket("localhost", getPortNumber());
new Thread(new Runnable() {
public void run() {
try {
SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
SingleInstanceController.this.oos.writeObject(obj);
SingleInstanceController.this.oos.flush();
SingleInstanceController.this.result = SingleInstanceController.this.ois.readBoolean();
} catch (IOException e) {
SingleInstanceController.this.result = false;
}
}
}).start();
for (int i = 0; i < 10; i++) {
if (this.result == true) {
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.client.close();
return this.result;
} catch (IOException e) {
return false;
}
}
public boolean registerApplication() {
try {
if (!this.file.exists()) {
if (!this.file.getParentFile().mkdirs() && !this.file.getParentFile().exists()) {
return false;
}
if (!this.file.createNewFile()) {
return false;
}
}
BufferedWriter wuffy = new BufferedWriter(new FileWriter(this.file));
int port = getFreeServerSocket();
if (port != -1) {
startServer();
}
wuffy.write(String.valueOf(port));
wuffy.close();
return true;
} catch (IOException e) {
return false;
}
}
protected void messageArrived(Object obj) {
for (ApplicationStartedListener asl : this.listener) {
asl.messageArrived(obj);
}
}
protected void applicationStartet() {
for (ApplicationStartedListener asl : this.listener) {
asl.applicationStarted();
}
}
protected void foreignApplicationStarted(String name) {
for (ApplicationStartedListener asl : this.listener) {
asl.foreignApplicationStarted(name);
}
}
private int getPortNumber() {
try {
BufferedReader buffy = new BufferedReader(new FileReader(this.file));
int port = Integer.parseInt(buffy.readLine().trim());
buffy.close();
return port;
} catch (Exception e) {
return -1;
}
}
private void startServer() {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
SingleInstanceController.this.client = SingleInstanceController.this.server.accept();
if (SingleInstanceController.this.client.getInetAddress().isLoopbackAddress()) {
new Thread(new Runnable() {
public void run() {
try {
SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
Object obj = SingleInstanceController.this.ois.readObject();
if (obj instanceof ClassCheck) {
if (obj.toString().equals(SingleInstanceController.this.appname)) {
SingleInstanceController.this.oos.writeBoolean(true);
applicationStartet();
} else {
SingleInstanceController.this.oos.writeBoolean(false);
foreignApplicationStarted(obj.toString());
}
} else {
messageArrived(obj);
SingleInstanceController.this.oos.writeBoolean(true);
}
SingleInstanceController.this.oos.flush();
SingleInstanceController.this.client.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
private int getFreeServerSocket() {
for (int i = 2000; i < 10000; i++) {
try {
this.server = new ServerSocket(i);
return i;
} catch (IOException ignore) {
}
}
return -1;
}
}
My vote goes to locking on a port (i think this is what you mean by socket). I don't know the exact reason for this. But in fact i come across only this as a solution in most practical projects. Though i will be happy to hear the alternative ways.
In response to your question, the port solution will keep more resources from the machine:
- You will keep a port locked: ports are limited and you may find problems with firewalls or other programs listening on the same port.
- You'll need an active thread.
The file solution will use less resources from the machine, to avoid locking the file forever you need to add a thread, to delete the file, in the addShutdownHook method from Runtime.
the serversocket solution is cross-platform . And will not be vulnerable to the program crashing and not resetting the lock.
File lock is better way to do- imo. When you create the file in User's Home directory, this will still work in a multi-user environment.
I came across - JUnique - haven't had a chance to use it
http://www.sauronsoftware.it/projects/junique/manual.php
I know that this question is pretty old, but I have to solve the same problem at the moment. I prefer the socket solution because I have never thought that such kind of task should have anything to do with the file system. It is better to solve the problem in memory and not in the file system I think.