I have recently been following some tutorials on how to program and whilst programming the public static void for an array, the tutorial said to declare the array as an object. Below is the code for the array and at the end of the code I have put a split between the two sections so it is visible to as where my question lies
import java.io.*;
import java.lang.*;
public class LoginList
{
int arraySize=500;
Login[] arrayLogin=new Login[arraySize];
int nextPosition=0;
int LoginLocation=-1;
public void addLogin(Login tempLoginParameters)
{
arrayLogin[nextPosition] = tempLoginParameters;
nextPosition++;
}
public void writeLogins()
{
try
{
BufferedWriter LoginWriter = new BufferedWriter(new FileWriter("LoginDetails.txt"));
for(int i=0;i<nextPosition;i++)
{
LoginWriter.write(arrayLogin[i].toString());
LoginWriter.newLine();
}
LoginWriter.close();
}
catch(Exception e)
{
System.out.println("Error with writer");
}
}
public void readLogins()
{
try
{
BufferedReader LoginReader = new BufferedReader(new FileReader("LoginDetails.txt"));
String ReadLine = LoginReader.readLine();
while(ReadLine!= null)
{
String[] arrayStringLogin = ReadLine.split(", ");
Login tempLogin = new Login();
tempLogin.UserName = arrayStringLogin[0];
tempLogin.Password = arrayStringLogin[1];
arrayLogin[nextPosition] = tempLogin;
nextPosition++;
ReadLine = LoginReader.readLine();
}
}
catch(Exception e)
{
System.out.println("Error with reader");
}
}
public void displayLoginDetails()
{
for(int i=0;i<nextPosition;i++)
{
System.out.println("Login "+nextPosition+": "+arrayLogin[i].toString());
}
}
public void searchLogins(String TempLog)
{
LoginLocation=-1;
for(int i=0;i<nextPosition;i++)
{
if(arrayLogin[i].UserName.equals(TempLog))
{
System.out.println("Match At Position:"+i);
LoginLocation=i;
}
else
{
System.out.println("No match for UserName");
}
}
}
public static void main(String[] args)
{
LoginList ll = new LoginList(); //Declares the array as an object
Why is it that you have to declare the array as an object? Look just above here.
Login tempLogin = new Login();
ll.readLogins();
ll.displayLoginDetails();
}
}
LoginList is not an array, it's a class that happens to have an array of Login objects as one of its instance members. The code in main creates an object of type LoginList and calls its methods; the LoginList object uses an array internally, but the main method doesn't have to know about it.
Related
import java.io.*;
import java.util.ArrayList;
public class Main {
static ArrayList<test> testArrey = new ArrayList<test>();
public static void main(String[] args) {
output(new test(18, "aren"));
output(new test(22, "ahmad"));
input();
read();
}
public static void read() {
for (test a : testArrey) {
System.out.println(a.age);
}
}
public static void input() {
try {
FileInputStream fileInput = new FileInputStream("open.ses");
ObjectInputStream ObjectInput = new ObjectInputStream(fileInput);
Object a1 = ObjectInput.readObject();
test b1 = (test) a1;
testArrey.add(b1);
Object a2 = ObjectInput.readObject();
test b2 = (test) a2;
testArrey.add(b2);
ObjectInput.close();
} catch (Exception ex) {
System.out.println("input error");
ex.printStackTrace();
}
}
public static void output(test a) {
try {
FileOutputStream fileOut = new FileOutputStream("open.ses");
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(a);
objectOut.close();
} catch (Exception ex) {
System.out.println("output error");
ex.printStackTrace();
}
}
public static class test implements Serializable {
int age ;
String name ;
public test(int age , String name ) {
this.age = age;
this.name = name;
}
}
}
as you can see a called output() method two time with new to object of (test)as argument ,and it must write two object on (open.ses)file but when i want to call (.readobject)two times it gives me an error that says one object is saved ............
how to write more than one object with the help of method like the one i wrote ??
I am trying to implement the observer pattern to a game i have made. When a villain is created in the battle-zone file using threads, I would like to use the observer pattern to create a hero using threads and add it to the same file. The villians and heroes are created using the factory method pattern. I am unsure of where to go with regards to linking my HeroCreationMain class to the observer pattern classes.
Villian Creation
public class VillianCreationMain {
private static Villian villian;
public static void main(String[] args, int userInput) throws IOException {
String fileName = null;
Random randomVillian = new Random();
int amountOfVillians = userInput;
if (amountOfVillians < 7) {
for (int x = 0; x < amountOfVillians; x++) {
int randomGenerator = randomVillian.nextInt(6);
for (int i = 0; i < 5; i++) {
if (randomGenerator == 0 ) {
setVillian(new FlyingVillian());
}
else if (randomGenerator == 1) {
setVillian(new StrongVillian());
}
else if (randomGenerator == 2) {
setVillian(new FastVillian());
}
else if (randomGenerator == 3) {
setVillian(new SmartVillian());
}
else if (randomGenerator == 4) {
setVillian(new FireVillian());
}
else if (randomGenerator == 5) {
setVillian(new IceVillian());
}
try {
writeToFile(getVillian(), i, fileName);
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
VillianThreads t1 = new VillianThreads(VillianCreationMain.getVillian());
t1.start();
}
}
else {
System.out.println("Please enter a value of less than 7");
}
}
public static void writeToFile(Villian villian, int amountOfVillians, String fileName) throws IOException {
for(int x = 0; x < amountOfVillians; x++) {
// String parsedInt = Integer.toString(x);
fileName = "battle-zone.ser";
FileOutputStream file = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(file);
oos.writeObject(villian);
file.close();
oos.close();
}
}
public static Villian getVillian() {
return villian;
}
public static void setVillian(Villian villian) {
VillianCreationMain.villian = villian;
}
}
Hero Creation
public class HeroCreationMain {
private static Hero hero = null;
public static void main(String[] Hero) {
EnemyStatus enemyStatus = new EnemyStatus();
VillianObserver observer1 = new VillianObserver(enemyStatus);
}
public static void readFile() throws IOException, ClassNotFoundException {
#SuppressWarnings("resource")
ObjectInputStream ois = new ObjectInputStream (new FileInputStream("battle-zone.ser"));
Villian targetVillian = (Villian) ois.readObject();
System.out.println(targetVillian + " is being attacked by a hero!");
}
public static Hero getHero() {
return hero;
}
public static void setHero(Hero hero) {
HeroCreationMain.hero = hero;
}
}
Observer
public interface Observer {
public void update(boolean enemyPresent);
}
public interface Subject {
public void register(Observer o);
public void unregister(Observer o);
public void notifyObserver();
}
Observable
public class VillianObserver implements Observer {
private boolean enemyPresent;
private static int heroIDTracker;
private int heroID;
private Subject villianObserver;
public VillianObserver(Subject villianObserver) {
this.villianObserver = villianObserver;
this.heroID = ++heroIDTracker;
System.out.println("New Observer " + this.heroID);
villianObserver.register(this);
}
#Override
public void update(boolean enemyPresent) {
this.enemyPresent = enemyPresent;
printResult();
}
public void printResult() {
System.out.println(heroID + " " + enemyPresent);
}
}
Enemy Status
import java.util.ArrayList;
public class EnemyStatus implements Subject {
private ArrayList<Observer> observers;
private boolean enemyPresent;
public EnemyStatus() {
// Creates an ArrayList to hold all observers
observers = new ArrayList<Observer>();
}
#Override
public void register(Observer newObserver) {
observers.add(newObserver);
}
#Override
public void unregister(Observer deleteObserver) {
// Get the index of the observer to delete
int heroIndex = observers.indexOf(deleteObserver);
// Print out message (Have to increment index to match
System.out.println("Observer " + (heroIndex+1) + " deleted");
// Removes observer from the ArrayList
observers.remove(heroIndex);
}
#Override
public void notifyObserver() {
for(Observer observer : observers) {
observer.update(enemyPresent);
}
}
public void setEnemyStatus(boolean enemyPresent) {
this.enemyPresent = enemyPresent;
notifyObserver();
}
}
JNotify is the Java library to observe file changes on the file system.
One piece of advice: Object(Input/Output)Streams are easy when you're just getting started but they lead you down a path of ruin. Objects get so easily BadVersion'ed. Object files are also relatively hard to inspect using a text editor. I'd advise you to try using a different data format (like JSON) instead.
I just want to print learning... as long as I enter 1
package a;
import java.util.Scanner;
class main extends Thread {
static String n;
Scanner reader = new Scanner(System.in);
public void run() {
n = reader.nextLine();
}
public static void main(String args[]) throws InterruptedException {
(new Thread(new main())).start();
n="5";
System.out.println("1 = ON\n0 = OFF");
while (n.equals("1")) {
System.out.println("Learning..");
}
}
}
You may be interested in reading up on the Producer-Consumer pattern. You can take a look here http://javarevisited.blogspot.fr/2012/02/producer-consumer-design-pattern-with.html and try with something like
class main extends Thread {
// a thread-safe queue for decoupling reading and writing threads avoiding
// synchronization issues. The capacity of the queue is 1 to avoid reading (producing) a
// command without having handled (consumed) the previous before
private static final BlockingQueue<String> sharedQueue = new LinkedBlockingQueue<>(1);
Scanner reader = new Scanner(System.in);
public void run() {
while (true) {
String s = reader.nextLine();
try {
//if the queue is empty, adds the element,
//otherwise blocks waiting for the current element to be handled by main thread
sharedQueue.put(s);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
public static void main(String args[]) throws InterruptedException {
(new Thread(new main())).start();
System.out.println("1 = ON\n0 = OFF");
while (true) {
//will block till an element is available, then removes and handles it
final String s = sharedQueue.take();
if ("1".equals(s)) {
System.out.println("Learning..");
}
}
}
}
If you are trying to stop start, it is always better to maintain two threads one for printing and other for taking input. Try with blow code. It is working fine for me.
public class ThreadsStop {
static String n="";
class Printer extends Thread{
#Override
public void run() {
while(!n.equals(null)){
try {
Thread.sleep(1000);
if(n.trim().equals("1"))
System.out.println("Learning..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Starter extends Thread{
#Override
public void run() {
Scanner reader = new Scanner(System.in);
while(true){
System.out.println("1 = ON \n 0 = OFF");
n= reader.nextLine();
}
}
}
public static void main(String[] args) {
new ThreadsStop().start();
}
private void start() {
new Starter().start();
new Printer().start();
}
}
Use can use the given below code.
class main extends Thread {
static String n;
Scanner reader = new Scanner(System.in);
public void run() {
while (true) {
n = reader.nextLine();
if (Integer.parseInt(n) == 0) {
break;
}
}
}
public static void main(String args[]) throws InterruptedException {
(new Thread(new main())).start();
System.out.println("1 = ON\n0 = OFF");
while (n == null) {
}
while (n.equals("1")) {
System.out.println("Learning..");
}
System.out.println("DONE");
}
}
Try below program, it will take your input and print it.
class main extends Thread {
static String n;
Scanner reader = new Scanner(System.in);
public void run() {
System.out.println("Enter n value ");
n = reader.nextLine();
}
public static void main(String args[]) throws InterruptedException {
(new Thread(new main())).start();
n="5";
System.out.println("1 = ON\n0 = OFF");
while (n.equals("5")) {
//System.out.println("Learning..");
}
System.out.println(n);
}
}
The reason why your code is not taking input, before providing the input your main method executed, which means that program execution completed. I have done few modifications to your code. Now your code will take your input.
I have a problem with my code. Code is about to find gateways/subnets and if program finds one it returns it to a class that called "call()" method. That part works fine but problem is that I want to pass ID of gateway(you know if gateway was 192.168.1.1 , it will also pass number 1 to class that fills vector of founded gateways). Problem is that for some reason vector that holds IDs of gateways is empty. Can you give me a clue how to fix problem ? Best regards.
Here is code that I used in my project:
int GateWayKey = 1;
int GateWayKeyStop=254;
String ip="";
StoredGW FoundedGW = new StoredGW();
int SubNetKey = 2;
int SubNetKeyStop = 254;
Vector <Integer> AllGateWays= new Vector <Integer>();
Vector <Future<String>> AllSQLs = new Vector <Future<String>>();
final int NUM_THREADS = Runtime.getRuntime().availableProcessors();
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
public void run() {
for (;GateWayKey<=GateWayKeyStop;GateWayKey++){
ip="192.168."+GateWayKey+".1";
AllSQLs.add(exec.submit((new PingTask(ip,GateWayKey))));
}
AllGateWays = FoundedGW.GiveMeGWs();
for (int j : AllGateWays){
for (;SubNetKey<=SubNetKeyStop;SubNetKey++){
ip="192.168."+j+"."+SubNetKey;
AllSQLs.add (exec.submit(new PingTask(ip,null))));
}
exec.shutdown();
}
Here is class that preform pinging and storing ID of gateway:
public class PingTask implements Callable <String> {
String ips;
int GateWay;
public PingTask (){
}
public PingTask (String ip, int GateWayKey){
ips=ip;
GateWay=GateWayKey;
}
public String call(){
InetAddress address;
try {
address = InetAddress.getByName(ips);
try {
if (address.isReachable(5000)) {
StoredGW GWs = new StoredGW();
GWs.addNewGW(GateWay);
} else {
return null;
}
} catch (IOException e) {
return null;
}
} catch (UnknownHostException e) {
return null;
}
}
}
and here is class where I store GateWays
public class StoredGW {
Vector <Integer> AllFoundedGWs= new Vector<Integer>();
public void addNewGW(int i){
AllFoundedGWs.add(i);
}
public Vector<Integer> GiveMeGWs(){
return AllFoundedGWs;
}
}
The problem is here:
StoredGW GWs = new StoredGW();
GWs.addNewGW(GateWay);
You make a new StoreGW (as local variable) and then you throw it away. Instead use, FoundedGW. You have to make sure it is visible to your task, you might have to pass it as a constructor argument so that it can be used within your task.
Try this:
public class PingTask implements Callable <String> {
String ips;
int GateWay;
StoredGW store;
public PingTask (){
}
public PingTask (String ip, int GateWayKey, StoredGW store){
ips=ip;
GateWay=GateWayKey;
this.store = store;
}
public String call(){
InetAddress address;
try {
address = InetAddress.getByName(ips);
try {
if (address.isReachable(5000)) {
store.addNewGW(GateWay);
} else {
return null;
}
} catch (IOException e) {
return null;
}
} catch (UnknownHostException e) {
return null;
}
}
}
Then you can call it this way:
AllSQLs.add(exec.submit((new PingTask(ip,GateWayKey, FoundedGW))));
As an unrelated side note, you need to take a look at the standard for Java naming conventions, it'll make your code easier for others to understand.
I'm building an application in Java which requires a Hashtable to be accessed from instances of two classes and both extend threads. I have declared the Hashtable in one of the two classes. I always get null when i try to access the Hashtable contents from one of the classes. The other class is able to access the contents without any problem. I thought this was a problem of concurrency control. Since these are threads of different classes we cannot use synchronized methods. Is there a way to make the Hashtable accessible from threads of both the classes?
Here are the some parts of the code of my application
This is the class which stores the HashMap:
public class DataStore {
public Map ChatWindows ;
public DataStore()
{
ChatWindows = new ConcurrentHashMap();
}
public synchronized void putWindow(String with,ChatWindow t)
{
ChatWindows.put(with,t);
notifyAll();
}
public synchronized ChatWindow getWindow(String with)
{
notifyAll();
return (ChatWindow)ChatWindows.get(with);
}
public synchronized void ChatWindowOpen(chatClient cc,String with,String msg)
{
// chatWith = with;
ChatWindow t;
System.out.println(with);
t = getWindow(with);
if(t == null)
{
t = new ChatWindow(cc,with,msg);
// th = new Thread(t);
putWindow(with, t);
// th.start();
}
else
{
t.setVisible(true);
}
}
}
Two classes which access 'ChatWindows' HashMap
public class chatClient extends javax.swing.JFrame implements
Runnable,ListSelectionListener,MouseListener,WindowListener{
static String LoginName,chatWith,msgToChatWindow;
Thread listThread=null,th,chatListen;
static Socket soc;
static DataOutputStream dout,dout1;
static DataInputStream din,din1;
DefaultListModel listModel;
ChatWindow t;
public DataStore ds;
/** Creates new form chatClient */
public chatClient(Login l,DataStore ds) {
listModel = new DefaultListModel();
initComponents();
clientList.addListSelectionListener(this);
clientList.addMouseListener(this);
addWindowListener(this);
this.LoginName=l.loginName;
soc = l.soc2;
din = l.din2;
dout = l.dout2;
dout1 = l.dout1;
din1 = l.din1;
super.setTitle(LoginName);
listThread = new Thread(this);
listThread.start();
this.ds = ds;
}
.
.
.
.
public void mouseClicked(MouseEvent e)
{
chatWith = (String)clientList.getSelectedValue();
ds.ChatWindowOpen(this,chatWith,"");
}
This class has run() method too, but that doesn't use the HashMap. This class is able to access the 'ChatWindows' properly.'ChatListenThread' class is not able to access the contents of HashMap properly.
public class ChatListenThread implements Runnable{
DataOutputStream dout1;
DataInputStream din1;
public static chatClient cc;
public static ChatWindow t;
public DataStore ds;
public ChatListenThread(Login l,DataStore ds)
{
din1 = l.din1;
dout1= l.dout1;
this.ds = ds;
}
.
.
.
.
public void run(){
while(true)
{
try{
String msgFromServer=new String();
msgFromServer = din1.readUTF();
StringTokenizer st=new StringTokenizer(msgFromServer);
String msgFrom=st.nextToken();
String MsgType=st.nextToken();
String msg = "";
while(st.hasMoreTokens())
{
msg=msg+" " +st.nextToken();
}
ds.ChatWindowOpen(cc,msgFrom,msg);
}
catch(IOException e)
{
System.out.println("Read failed");
}
}
}
}
It's possible. Take a look at Sharing data safely between two threads.
Okey, I couldn't use your code because I don't understand, what I did see was that you want something like this:
Create a empty JFrame with a JTabbedPane and start a thread that connects to a Socket
When input comes on the socket, create a ChatPanel (~JTextArea) and add it to one of the tabs
Add the ChatPanel to a Map that handles the messages from "from"
Pass the message to the newly created ChatPanel
So I did that and I'm posting the code below! Hope that you can use it!
If you like to test this, first start the TestChatServer (code below) and then the ChatSupervisor.
This is the code for the client
public class ChatSupervisor extends JFrame implements Runnable {
JTabbedPane tabs = new JTabbedPane();
Map<String, ChatPanel> chats = new ConcurrentHashMap<String, ChatPanel>();
public ChatSupervisor() {
super("Test Chat");
add(tabs, BorderLayout.CENTER);
new Thread(this).start();
}
public void run() {
Socket sock = null;
try {
sock = new Socket("localhost", 32134);
Scanner s = new Scanner(sock.getInputStream());
while (true) {
String from = s.next();
String type = s.next();
String message = s.nextLine();
getChat(from).incomingMessage(type, message);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sock != null) try { sock.close(); } catch (IOException e) {}
}
}
public ChatPanel getChat(String from) {
if (!chats.containsKey(from))
chats.put(from, new ChatPanel(from));
return chats.get(from);
}
public static void main(String[] args) {
ChatSupervisor cs = new ChatSupervisor();
cs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cs.setSize(400, 300);
cs.setVisible(true);
}
class ChatPanel extends JTextArea {
public ChatPanel(final String from) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
tabs.addTab(from, ChatPanel.this);
}
});
}
public void incomingMessage(final String type, final String message) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
append("[" + type + "]" + message);
append("\n");
}
});
}
}
}
This is the code for the test server:
public class TestChatServer {
public static void main(String[] args) throws Exception {
Socket s = new ServerSocket(32134).accept();
System.out.println("connected");
PrintWriter p = new PrintWriter(s.getOutputStream());
while (true) {
p.println("hello info Hello World!");
p.flush();
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
p.println("test" + i + " warn Testing for testing " + i);
p.flush();
Thread.sleep(100);
}
}
}
}