How to print lines from another class - java

UPDATE
I was wrong the whole time. I was blocking the output with a method I was using and didn't add here. Now it works well and I'm able to write from other process.
I would like to know if there is any way of printing a line to a console view from outside. I have a class (class1) that has an onMessage method.
public class Class1 implements MessageListener {
...
public void onMessage(Message msg) {
System.out.println(msg.getText());
}
...
}
And then I have a class with a main that creates an instance of this class and while doing things the onMessage of Class1 fires.
public class Class2{
public static void main(String args[]) {
Class1 obj = new Class1();
...
while(!":q".equals((action = scanner.next()))){
obj.anotherAction(action);
}
...
}
}
When I try that the object seems to be blocked. I think that I'm approaching wrong to the solution. Maybe calling println from outside blocks as it doesn't have anywhere to print to.
I would like to understand what's happening and how could I solve this. My problem is using the output that creates the Class2 main from Class1.
I hope I explained well, I'm not a native speaker.
EDIT
Now I added more coding. I'm now realizing that waiting for the standard input maybe is interfering with the Print of the other class. Should I run an external proccess for the output? How could I do it on the same console view?

try this
Class1.java
import java.util.Scanner;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
public class Class1 {
public static void main(String args[]) throws JMSException {
Class2 obj = new Class2();
Scanner s=new Scanner(System.in);
Message m;
TextMessage textMessage = null;
System.out.println("Enter a message");
textMessage.setText(s.next());
m=(Message)textMessage;
obj.onMessage(m);
}
}
Class2.java
import javax.jms.*;
public class Class2 implements MessageListener{
public void onMessage(Message msg) {
System.out.println(msg.toString());
TextMessage textMessage = (TextMessage) msg;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}

Related

Cannot reset StringBuffer in JavaFX Application

I am working on a college course project, a JavaFX application that is simulating a garage with vehicles moving around. Following on this answer, I created a mechanism for constantnly refreshing GUI without flooding the JavaFX thread.
The entire code can be found here.
Observer is a daemon thread whose task is computing a String value for output and sending it it to a TextArea, which is constantly being updated.
Observer run method:
#Override
public void run() {
while (true) {
synchronized (Garage.getLock()) {
try {
// buffer = new StringBuffer("");
buffer.append('\n');
garage.print(buffer);
buffer.append('\n');
garage.outputText.set(buffer.toString());
System.out.println(buffer.toString());
Garage.getLock().wait(3000);
} catch (InterruptedException exception) {
exception.printStackTrace();
} finally {
Garage.getLock().notifyAll();
}
}
}
}
Observer object has a reference to the model class - garage. print() method of the Garage class basically appends stuff to the buffer.
The complete output is printed to the console, which works fine. The output is also used to set outputText, a SimpleStringProperty, which has a listener attached in the MainControllerClass.
outputText member:
public class Garage implements Externalizable {
...
public SimpleStringProperty outputText = new SimpleStringProperty();
...
}
Refreshing the GUI is initiated with a button click.
MainController class:
package garage.controller;
import java.util.concurrent.atomic.AtomicInteger;
import garage.model.*;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class MainController {
#FXML
private TextArea output;
#FXML
private Button startButton;
private Garage model;
public MainController() {
}
private AtomicInteger control = new AtomicInteger(-1);
#FXML
public void initialize() {
}
#FXML
private void handleStartButton() {
model.outputText.addListener(new ChangeListener<String>() {
#Override
public void changed(final ObservableValue<? extends String> observable, final String oldValue,
final String newValue) {
if (control.getAndSet(1) == -1) {
javafx.application.Platform.runLater(new Runnable() {
#Override
public void run() {
control.set(-1);
output.setText(newValue);
}
});
}
}
});
}
public void setModel(Garage model) {
this.model = model;
}
}
When I run the application and click the button, everything is going well. TextArea is updated in real time. Since the output is constantly being appended to the StringBuffer, I wanted to refresh it in every cycle and get something like a simulation.
This is where the problems start.
When I uncomment the line in the Observer run method
// buffer = new StringBuffer("");
nothing is being printed to the TextArea. The console output is working well.
I also tried with other StringBuffer methods like delete and setLenght but nothing seems to work. However I try to clean the buffer, TextArea is no longer updated.
I cannot seem to reset the StringBuffer.
What am I missing here?
EDIT: print() methods
Garage print method
public void print(StringBuffer buffer) {
synchronized (Garage.lock) {
synchronized (lock) {
for (int i = 0; i < platformCount; i++)
platforms.get(i).print(buffer);
}
}
}
GarageItem print method
package garage.model;
import java.io.*;
public interface GarageItem extends Serializable {
public void print(StringBuffer buffer);
}
Lane print method
package garage.model;
public class Lane implements GarageItem {
private static final long serialVersionUID = 5L;
#Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append('.');
}
}
}
ParkingSpot print method
package garage.model;
public class ParkingSpot implements GarageItem {
private static final long serialVersionUID = 4L;
#Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append('*');
}
}
}
Vehicle print method
#Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append(symbol);
}
}
where symbol is 'V'.
Found the answer today. My text example was trivial and by the time I clicked the handleStartButton, all of the cars have finished moving and parked in the garage.
Because I reset the buffer in every loop iteration, it meant that the state of the garage didn't change anymore and it's String representation was the same. Because of this, change listener was not triggered and nothing was printed out to the TextArea.

strange things with btrace and java.lang.NoSuchMethodError

the main class:
package com.xxx.yyy;
public class Hello{
public static void main(String[] args){
A a = new A();
while(true){
try {
a.execute(1000);
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
class A:
package com.xxx.yyy;
public class A{
public void execute(int sleepTime) throws Exception {
System.out.println("sleep time is "+sleepTime);
}
}
btrace script:
import static com.sun.btrace.BTraceUtils.println;
import static com.sun.btrace.BTraceUtils.str;
import static com.sun.btrace.BTraceUtils.strcat;
import static com.sun.btrace.BTraceUtils.timeMillis;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.TLS;
#BTrace
public class BtraceTest{
#OnMethod(clazz="com.xxx.yyy.A",method="execute",location=#Location(Kind.RETURN))
public static void traceExecute(#ProbeClassName String name,#ProbeMethodName String method,int sleepTime){
println(strcat("the class name=>", name));
println(strcat("the class method=>", method));
println(strcat("the class method params=>", str(sleepTime)));
}
}
everything is right.
BUT: when I move the line Thread.sleep(1000) to class A's execute function, like this:
package com.xxx.yyy;
public class A{
public void execute(int sleepTime) throws Exception {
System.out.println("sleep time is "+sleepTime);
Thread.sleep(1000);
}
}
the NoSuchMethodError is thrown by Hello.
Exception in thread "main" java.lang.NoSuchMethodError: com.xxx.yyy.A.$btrace$BtraceTest$traceExecute(Ljava/lang/String;Ljava/lang/String;I)V
at com.xxx.yyy.A.execute(Unknown Source)
at com.xxx.yyy.Hello.main(Hello.java:8)
my environment is
java version "1.8.0_121"
BTrace v.1.3.9 (20170111)
anyone can explain why?thanks!
I think your class should implements Runnable or extends Thread. Then only you can use start, sleepand such similar methods in your program. Have a look at here to know how to implement thread methods.

Hyperlinklistener will not connect [duplicate]

I'm encountering a weird issue in Java at the moment that I've never seen before.
The error is "No enclosing instance of type Server is accessible. Must qualify the allocation with an enclosing instance of type Server (e.g. x.new A() where x is an instance of Server)."
The line I've commented on is where the error occurs.
package game;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
public class Server {
private static List<ThreadModtagClient> clients;
class ReceiveDataListener implements SocketListener {
#Override
public void dataReceived(ThreadModtagClient client, String data) {
}
}
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
clients = new ArrayList<ThreadModtagClient>();
ServerSocket welcomeSocket = new ServerSocket(16567);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
ThreadModtagClient client = new ThreadModtagClient(connectionSocket);
ReceiveDataListener listener = new ReceiveDataListener(); // <--- this is where the error occurs
client.addSocketListener(listener);
clients.add(client);
}
}
}
class ThreadModtagClient extends Thread implements SocketThread {
private BufferedReader inFromClient;
private DataOutputStream outToClient;
private Player player;
private List<SocketListener> listeners;
public ThreadModtagClient(Socket connection) throws IOException {
inFromClient = new BufferedReader(new InputStreamReader(connection.getInputStream()));
outToClient = new DataOutputStream(connection.getOutputStream());
listeners = new ArrayList<SocketListener>();
}
public void addSocketListener(SocketListener listener) {
listeners.add(listener);
}
public void removeSocketListener(SocketListener listener) {
listeners.remove(listener);
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public void sendData(String data) throws IOException {
outToClient.writeChars(data);
}
public void run() {
while (true) {
try {
String data = inFromClient.readLine();
for(SocketListener listener : listeners) {
listener.dataReceived(this, data);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(NoSuchElementException e1) {
e1.printStackTrace();
}
}
}
}
Server.ReceiveDataListener is a (non-static) inner class. You are creating it from a static context. You need to supply an instance of Server to be the outer instance. However, almost certainly you want ReceiveDataListener to be a static nested class, or probably an outer class.
well the error tells you exactly what needs to be done. ReceiveDataListener is a non-static inner class and must be accessed via an object of the outer class (Server). You have three options:
1. take the compiler's advice (access via an object of Server)
2. make ReceiveDataListener static
3. pull ReceiveDataListener out to a separate .java and use it.
HTH
You cannot instantiate a non-static inner class from a static context like main.
This is because you're trying to create a ReceiveDataListener from a static method, and since ReceiveDataListener is not a static class, it needs to be attached to an instance of Server.

Java - Synchronized

Hi i have made a something that extends thread that adds adds an object that has a IP in it. then i made two instances of this thread and started them. they use the same list.
I now want to use Synchronized to stop the concurrent update problem. But its not working and i cant work out why.
My main class:
import java.util.*;
import java.io.*;
import java.net.*;
class ListTest2 {
public static LinkedList<Peer> myList = new LinkedList<Peer>();
public static void main(String [] args) {
try {
AddIp test1 = new AddIp(myList);
AddIp test2 = new AddIp(myList);
test1.start();
test2.start();
} catch(Exception e) {
System.out.println("not working");
}
}
}
My thread class:
class AddIp extends Thread {
public static int startIp = 0;
List<Peer> myList;
public AddIp(List<Peer> l) {
myList = l;
}
public synchronized void run() {
try {
startIp = startIp+50;
int ip = startIp;
InetAddress address = InetAddress.getByName("127.0.0.0");
Peer peer = new Peer(address);
while(ip <startIp+50) {
ip++;
address = InetAddress.getByName("127.0.0."+ip);
peer = new Peer(address);
myList.add(peer);
if(myList.indexOf(peer)== (myList.size() -1)) {
} else {
System.out.println("Lost"+peer.peerIp);
}
}
} catch(Exception e) {
}
}
}
Can anyone help me out here im lost for ideas thanks.
public synchronized void run()
Synchronizes on calling instance: this.
So,
1st thread synchronizes on test1 and 2nd thread synchronizes on test2, which doesn't help at all.
You want to synchronize on the shared resource, in this case: myList
public void run() {
synchronize(myList){
//your Logic
}
}
As a side note: Implement runnable instead of extending a Thread. Read more here.
You'd be better off implementing Runnable oppose to extending thread
also
public void run() {
synchronize(list){
//stuffs
}
}
they use the same list.
You can try to use Vector instead List. Vector is synchronized
or set your List to be synchronized:
List myList = Collections.synchronizedList(myList);
instead to use:
synchronize(myList){
}
The easiest way is to use a List implementation that can handle multiple threads. Try CopyOnWriteArrayList.

java remote function need calling twice

I've created a java code (swing GUI JFrame form) that call another class function (which is in another project) when the button is pressed, but it needs me to click the button twice in order to successfully return the value from the called function. Is there any solution?
here is my code,
The GUI
package aarib;
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import AlKhalil.ui.Aarib;
public class GUI extends javax.swing.JFrame {
public String Input;
public String Lexems;
public Aarib A;
public GUI() {
initComponents();
A = new Aarib();
jTextField1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
jLabel2.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if(jTextField1.getText().isEmpty())
{
jLabel2.setText("No input");
}
else{
Input = jTextField1.getText().toString();
A.inputText= Input;
try {
Lexems = A.LexicalAnalysis();
jLabel2.setText(Lexems);
} catch (Exception ex) {
jLabel2.setText("Error");
Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
and the remote function
package AlKhalil.ui;
import java.util.*;
import java.util.List;
import AlKhalil.token.*;
import AlKhalil.analyse.*;
import AlKhalil.*;
import AlKhalil.result.*;
public class Aarib {
public Analyzer analyzer;
public String myResult="";
public String inputText="";
public Aarib() {
Settings settings = new Settings();
analyzer = new Analyzer();
}
public String LexicalAnalysis() throws Exception {
Thread t = new Thread()
{
public void run()
{
//some code
...
...
...
}
};
t.start();
return myResult;
}
}
Thanks in advance :)
The solution is to wait for the result produced in the Thread t. With your current code you start a concurrent thread and instantly return the attribute myResult. With the second click on your button the myResult is (most times) filled by the thread and returned after starting another concurrent thread doing the calculation.
I suggest considering some kind of Observer-Pattern for your program. Your GUI then should obsever the calculating thread and get notified about a result, which then will be handled.
But as we all cannot see the code executed in the thread and as you wait for the thread to finish, why not simply not use a thread.

Categories