I am creating a chat client which contains a class Server ( main class ) and a client class ( which starts a client and connects to the server ).
Then now I am trying to add a combobox with contacts before I connect a client to the server, so I did a new class for Combobox, with a actionListener and actionPerformed to open a client when pressing a contact. Problem is the Client that opens is running (seeing the printouts when messaging through Server ) but the Client GUI is gray and frozen, (like when a program does not answer). Same problem was with the combobox before I did dispose().
So I am currently quite new to thread coding, but my understanding of the problem (might be wrong) is that the Swing component thread which is used in the comboBoxClass is used on creating and clicking on contacts in the comboBox. When I then create a new Client in the comboBoxClass I already use the Swingthread there and the Client will not be able to use "enough" threads. Not sure thought but that is my conclusion.
Also here is a link to whole the code: https://pastebin.com/mNeBFn7q
(Using 4 textfiles so it wont run without them, but you will see the full structure).
};
class comboBoxClass {
public comboBoxClass() {
String[] favContacts = {
"BigKarlos",
"lilVillz",
"metaforMatte",
"BirkoStoteles",
"Övriga Kontakter!!"
JComboBox contactList = new JComboBox(favContacts);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 100);
Container cont = frame.getContentPane();
cont.setLayout(new FlowLayout());
cont.add(contactList);
frame.setVisible(true);
contactList.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
//contactList.addActionListener(this);
ArrayList<String> arrayList = readFile();
contentArr = new String[arrayList.size()];
arrayList.toArray(contentArr);
if (contactList.getSelectedIndex() == 0) {
port = contentArr[4];
IP = contentArr[5];
}
if (contactList.getSelectedIndex() == 1) {
port = contentArr[7];
IP = contentArr[8];
}
if (contactList.getSelectedIndex() == 2) {
port = contentArr[1];
IP = contentArr[2];
}
if (contactList.getSelectedIndex() == 3) {
port = contentArr[10];
IP = contentArr[11];
}
if (contactList.getSelectedIndex() == 4) {
JFileChooser contactChooser = new JFileChooser("/Users/kasperknudsen/Documents/Chatten");
contactChooser.getFileFilter();
contactChooser.showOpenDialog(frame);
}
frame.dispose();
Client kontakt = new Client(IP,Integer.parseInt(port));
}
});
}
Related
first post here. I've tried to look for a question I have but no luck so I figure I ask it myself.
I am working on 2 programs. An Android app in Java and a C# Windows Form App on windows. They are both simply scorekeeping calculators to keep track of the score of 2 players.
The goal of the 2 programs is to use a Bluetooth connection to send data back and forth between each other so that they are "synced". Android app is a client, c# app is a server (32feet library).
Using the Bluetooth Chat example on Android and some code i put together in VS, I managed to get the 2 programs to connect and send and receive data to each other, great!
But now my main goal is that I need to find out a way to take the incoming data coming from the Android app and change the appropriate labels/text on the windows app.
So for example:
on the Windows App, there are 2 Labels: one for Player1, one for Player2 that both say "10".
On the Android App, I have 2 buttons that separately subtract from either Player1 or Player2's score.
On the android app, if I touch the button that subtracts(-) 1 from Player1 it would be 9. I now want that change to apply to Player1's score label on the windows app, where it would also show 9.
I then want the same thing for Player2's score.
This is the best I can describe my goal, and I would like to know if it's possible, and if so, be pointed in the right direction.
Here is some provided code for what I have so far:
C# windows form app:
private void button1_Click(object sender, EventArgs e)
{
if (serverStarted == true)
{
updateUI("Server already started");
return;
}
if (radioButton1.Checked)
{
connectAsClient();
}
else
{
connectAsServer();
}
}
private void connectAsServer()
{
Thread bluetoothServerThread = new Thread(new ThreadStart(ServerConnectThread)); //creates new thread and runs "ServerConnectThread"
bluetoothServerThread.Start();
}
private void connectAsClient()
{
throw new NotImplementedException();
}
Guid mUUID = new Guid("fa87c0d0-afac-11de-8a39-0800200c9a66");
bool serverStarted = false;
public void ServerConnectThread()
{
serverStarted = true;
updateUI("Server started, waiting for client");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
BluetoothClient conn = blueListener.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mStream = conn.GetStream();
while (true)
{
try
{
//handle server connection
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI("Received: " + Encoding.ASCII.GetString(received));
byte[] sent = Encoding.ASCII.GetBytes("hello world");
mStream.Write(sent, 0, sent.Length);
}
catch (IOException exception)
{
updateUI("Client disconnected");
}
}
}
private void updateUI(string message)
{
Func<int> del = delegate ()
{
textBox1.AppendText(message + Environment.NewLine);
return 0;
};
Invoke(del);
}
}
Android App (snippet from the Bluetooth Chat example - i think this is the only relevant part):
/**
* Sends a message.
*
* #param message A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
You will want to have to add the clients to alist of streams for reference and also store the scores of each client on a list and then send the data coming from each client to the rest of the clients
so from the server youd have basically something like this
List<Stream> clients=new List<Stream>();
List<String> client_scores=new List<String>();
public void ServerConnectThread()
{
serverStarted = true;
updateUI("Server started, waiting for client");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
BluetoothClient conn = blueListener.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mStream = conn.GetStream();
clients.add(mStream);
client_scores.add(new Random().Next()+"");
int index_cnt = clients.IndexOf(mStream);
while (true)
{
try
{
//handle server connection
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI("Received: " + Encoding.ASCII.GetString(received));
client_scores[client_scores.FindIndex(ind=>ind.Equals(index_cnt))] = Encoding.ASCII.GetString(received);
byte[] sent = Encoding.ASCII.GetBytes("hello world");
mStream.Write(sent, 0, sent.Length);
foreach(Stream str in clients)
{
byte[] my_score = Encoding.ASCII.GetBytes(clients.ToArray()[index_cnt]+"");
str.Write(my_score, 0, my_score.Length);
}
}
catch (IOException exception)
{
updateUI("Client disconnected");
}
}
}
You can then serialize the data being sent in some sort of json so as to send multiple fields of data comfortably for example :
{
"data type": "score",
"source_id": "client_unique_id",
"data": "200"
}
On your displaying side,just get the values of (in our example case source_id and data) and display on a label
When I typed in my question, similar questions came up, like this one [ How can I communicate Servlet from Swing ], but I looked at it, and didn't find the answer I'm looking for, so here is my question.
I'm developing a web app for internal call center, it uses a Java application [ CCT : call center technology ] to call asterisk server to make calls, this CCT has lots of servlets to generate html web pages so caller agents can access web pages and make calls. In order to better develop and debug, I added a Swing GUI panel to it, so when it runs on my development PC, it will open a window with lots of buttons, each represents a caller agent with their setting info, so I can click and look at the details. It runs fine and I've copies the code to a test server, when it runs there I can remote into it and see the Swing panel with JButtons representing each caller agent.
But the problem is, when this Java app runs on production server, it will be run as a Windows service [ so I was told by my boss ], and there will be no display, so the Swing panel won't be seen, therefore I thought about Java web Start, with it I can have a web page with a "WebStartLaunchButton" so when I click that button it will let me download a Jar file which will start a Swing App. But then I realize the Jar file will be downloaded onto my local PC, and run from the PC, it will have no knowledge of the servlet setting/info, it is independent, it has nothing to do with the call center web app sevlet, and won't be able to show caller agents info. Am I right, is there a way to have a Swing app run on the server and see [ have access to ] it from my PC ?
Here are more details, from the servlet there is a class like this :
public class DialerService extends Service implements Runnable
{
private boolean running = false;
private Thread thread;
private CallManager cm = null;
private AgentDialListManager adlm = null; // <-- My Swing program
private DataAccessManager dam = null;
...
public void run()
{
adlm = new AgentDialListManager(); // <-- My Swing program
...
}
...
private CallData getNextDial(SessionManager sm, SessionData session)
{
CallData nextDial = null;
AgentData agent = session.getAgentData();
if (agent != null)
{
SystemSettingsData settings = dam.getSystemSettings();
if (settings.isNextDialBufferOn())
{
nextDial = adlm.getNextNumber(dam,session); // <-- My Swing program : Get a number from self-managed agent dial list
}
...
}
}
...
}
Here is my main Swing program [ other related classes not shown ] :
package com.amerisave.cct.call;
import com.amerisave.cct.data.DataAccessManager;
import com.amerisave.cct.session.AgentData;
import com.amerisave.cct.session.SessionData;
import com.orderlysoftware.orderlycalls.OrderlyCalls;
...
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
...
public class AgentDialListManager extends JPanel implements Runnable
{
public static final long serialVersionUID = 26362862L;
static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
static int W = 1136, H = 800, updateInterval = 1000;
HashMap<Integer,AgentDialListRunner> agentDialListMap = null;
HashMap<Integer,JFrame> Agent_Panel_Frame_Map = null;
AgentData agent;
Insets anInset = new Insets(0,0,0,0);
AgentDialListRunner adlr;
JPanel agentPanel = new JPanel(),Log_Panel=new JPanel(new FlowLayout(1,0,0));
...
static JTabbedPane Tabbed_Pane;
static JTextArea Log_TextArea = new JTextArea(Get_System_Properties());
String hostAddress,hostName,dialerServerInfo="";
List dialerServerList = null;
Thread agentDialListManagerThread;
AgentDialListManager()
{
if (!agentDialListManager_Exists_B)
{
agentDialListMap = new HashMap();
Agent_Panel_Frame_Map = new HashMap();
shutdown = false;
if (showGUI_B) Init();
start();
agentDialListManager_Exists_B = true;
}
}
void Init()
{
setLayout(new FlowLayout(1,0,1));
Tabbed_Pane=new JTabbedPane();
Tabbed_Pane.setDoubleBuffered(true);
Tabbed_Pane.setPreferredSize(new Dimension(W - 20,H - 42));
Tabbed_Pane.setAutoscrolls(true);
Tabbed_Pane.setFont(new Font("Times New Roman",0,16));
Tabbed_Pane.setForeground(new Color(0,0,230));
add(Tabbed_Pane);
agentPanel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(134,134,134))," Agents",TitledBorder.CENTER,TitledBorder.TOP,new Font("Times New Roman",0,15),new Color(0,60,198)));
agentPanel.setPreferredSize(new Dimension(W - 20,H - 42));
Tabbed_Pane.addTab("Agents",null,agentPanel,"");
JPanel bottomPanel = new JPanel(new FlowLayout(1,0,0));
JPanel skipRatioPanel = new JPanel(new FlowLayout(1,0,0));
skipRatioPanel.setBorder(new EtchedBorder(EtchedBorder.RAISED,new Color(0,188,250),new Color(134,134,134)));
skipRatioPanel.setPreferredSize(new Dimension(330,30));
bottomPanel.add(skipRatioPanel);
...
Tabbed_Pane.addTab("Log",null,Log_Panel,"");
setPreferredSize(new Dimension(W,H));
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
CallData getNextNumber(DataAccessManager dam,SessionData session)
{
CallData nextDial = null;
if (agentDialListMap != null)
{
agent = session.getAgentData();
int nEmployeeId = agent.nEmployeeId;
if (!agentDialListMap.containsKey(nEmployeeId))
{
adlr = new AgentDialListRunner(nEmployeeId,dam);
agentDialListMap.put(nEmployeeId,adlr);
agentCount = agentDialListMap.size();
agentPanel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(134,134,134)),agentCount + " Agent" + (agentCount > 1 ? "s" : ""),TitledBorder.CENTER,TitledBorder.TOP,new Font("Times New Roman",0,15),new Color(0,60,198)));
addAgent(adlr.id,adlr,agent);
}
adlr = agentDialListMap.get(nEmployeeId);
nextDial = adlr.getNextNumber();
}
return nextDial;
}
void createAndShowGUI()
{
JFrame frame = new JFrame("AgentDialListManager [ Java = " + System.getProperty("java.version") + " | jetty.home = "+System.getProperty("jetty.home")+" ] dialerServerInfo = " + dialerServerInfo+" [ hostAddress = " + hostAddress+" hostName = " + hostName+" ]");
frame.add(this);
frame.addWindowListener(new WindowAdapter()
{
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowClosing(WindowEvent e) { if (runFromMain_B) System.exit(0); }
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { repaint(); }
public void windowGainedFocus(WindowEvent e) { repaint(); }
public void windowIconified(WindowEvent e) { }
public void windowLostFocus(WindowEvent e) { }
public void windowOpening(WindowEvent e) { repaint(); }
public void windowOpened(WindowEvent e) { }
public void windowResized(WindowEvent e) { repaint(); }
public void windowStateChanged(WindowEvent e) { repaint(); }
});
frame.pack();
if (runFromMain_B) frame.setLocationRelativeTo(null);
else frame.setBounds(displayCount==3?-1728:0,displayCount==3?0:26,this.getWidth(),this.getHeight() + 43);
frame.setVisible(true);
}
public void run()
{
try
{
while (!shutdown)
{
Thread.sleep(sleepTime);
AgentDialListRunner.averageTimeToMoreNumbers = 0;
for (Map.Entry<Integer,AgentDialListRunner> mapElement : agentDialListMap.entrySet())
{
int nEmployeeId = (int)mapElement.getKey();
AgentDialListRunner adlr = (AgentDialListRunner)mapElement.getValue();
AgentDialListRunner.averageTimeToMoreNumbers += adlr.averageTimeInSecondsBeforeGettingMoreNumbers;
}
agentCount = agentDialListMap.size();
if (agentCount > 0)
{
AgentDialListRunner.averageTimeToMoreNumbers /= agentCount;
averageTimeToMoreNumbersValueLabel.setText(AgentDialListRunner.averageTimeToMoreNumbers + " Sec.");
}
}
}
catch (Exception e)
{
log.error("Exception in runner thread:", e);
}
}
public void start()
{
stop();
if (agentDialListManagerThread == null)
{
agentDialListManagerThread = new Thread(this);
agentDialListManagerThread.setPriority(Thread.NORM_PRIORITY);
agentDialListManagerThread.start();
}
}
public void stop()
{
if (agentDialListManagerThread != null) agentDialListManagerThread = null;
}
...
public static void main(String[] args)
{
runFromMain_B = true;
new AgentDialListManager();
}
}
The GUI when the server starts looks like the following, on the left side there is a window showing all active caller agents [ only showing one on my development PC ], when the agent button is clicked, another panel shows up on the right side displaying the numbers in the buffer for the agent to call, mouse over each number, customer info for that number will be displayed in tooltip of the button :
Hope these details will make the question more clear.
I was trying to understand for quite a while how your application works. I think what you are doing is that you have a servlet which is handling an http request AND as a part of the request handling you start a thread which opens up a Swing application. Is this correct?
If so, this is a bad design. Servlet is for serving web content. If you start a Swing app, it runs in the same JVM and you can actually access same backend resources as in the servlet but the problem is that the content that servlet serves is transported over the network to the client. While this can work on your local machine (where the server machine is also the client machine) it will not work on a normal client-server architecture, where server is a different machine than the client. Here the client receives the response (html) but has no access to the Swing app running on server machine.
Another problem with this design is how would you bind the swing application to the correct client? Image 100 users access the servlet, does it open 100 instances of the Swing application? As Kayaman said, you would need some kind of another connection to client's machine to access the Swing application. This is not trivial and not worth doing.
I am actually from Webswing team, but this is not the right use case for Webswing. Webswing is for standalone Swing/JavaFX applications that user would normally start up from desktop, not from a servlet.
I think the best choice for you is to implement the logic from you Swing app into an HTML page served by the servlet, probably use some AJAX calls on the buttons, etc. There is really a lot of possibilities how to access backend from webpage in a very responsive and native-like way.
This question already has answers here:
Download a file from the internet using java : How to authenticate?
(6 answers)
Closed 7 years ago.
I have a problem, I am very new to Java and I'm currently trying to create a Java application to download files from a website. To enter the website you need a password and username. I use NativeSwing to enter and get the path of the files, I saw many examples, but I don't know how implement them.
Any advice ?
public class Test {
public JFrame frame;
private static JWebBrowser browser;
private static JPanel configurationButtonPanel;
public Test() {
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createContent(), BorderLayout.CENTER);
frame.setSize(800, 800);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public JComponent createContent() {
JPanel contentPane = new JPanel(new BorderLayout());
JPanel configurationPanel = new JPanel(new BorderLayout());
configurationButtonPanel = new JPanel(new FlowLayout(
FlowLayout.CENTER, 0, 0));
JButton beginButton = new JButton("Download");
beginButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ArrayList<String> ligas = new ArrayList<String>();
int a=0;
Document doc = Jsoup.parse(browser.getHTMLContent());
Element ele = doc.getElementById("ctl00_MainContent_PnlResultados");
System.setProperty("java.net.useSystemProxies", "true");
try{
Elements img_2 = ele.getElementsByClass("BtnDescarga");
for (Element el : img_2) {
for( Attribute attribute : el.attributes() )
{
if( attribute.getKey().equalsIgnoreCase("onclick"))
{
ligas.add("https://portalcfdi.facturaelectronica.sat.gob.mx/"+attribute.getValue().substring(19,535));
}
}
}
}
catch(NullPointerException nulo){
}
for( int i = 0 ; i < ligas.size() ; i++ ) {
System.out.println( ligas.get( i ) );
}
}
});
browser = new JWebBrowser();
browser.navigate("https://cfdiau.sat.gob.mx/nidp/app/login?id=SATUPCFDiCon&sid=0&option=credential&sid=0");
configurationButtonPanel.add(beginButton);
configurationButtonPanel.setVisible(true);
configurationPanel.add(configurationButtonPanel, BorderLayout.NORTH);
contentPane.add(configurationPanel, BorderLayout.SOUTH);
contentPane.add(browser, BorderLayout.CENTER);
return contentPane;
}
/**
* #param args
*/
public static void main(String[] args) {
NativeInterface.open();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Test();
}
});
NativeInterface.runEventPump();
}
}
When it run this part
for( int i = 0 ; i < ligas.size() ; i++ ) {
System.out.println( ligas.get( i ) );
}
I get the following URL like this:
https://portalcfdi.facturaelectronica.sat.gob.mx/RecuperaCfdi.aspx?Datos=huswUYX1eXMlGkDiItMUBgaWREHHqhXOWtYxqyUh0oUZnCKLYE/gx6ENJ+0TwW5auWw8d/AiCJyuFSDNVY+5l0vkiELroo/fEmF+x5w+DQDDTfMX9qIINS1NgP9C1bFhirjcVXpZI1ed4ycpLPczkYMEGEKvqWemni8LWcbqC0BuZskOJnCQCaWRh1Kt7AL5GdBVKqkm3T5mvzhtkmE5dn0vcWbCFFO3d3G8hu7rlcc0XM+7+6iR52SZYYaHa/TOhcl2DjuzztADpa9tPxZ9VO6EzMVkYKTfDOqHwZO8m2U9BZ7UhFjqsyoAwsQneqhIqGwN21yEpGEcptsTb9uZ1t0Fc/1Ggd6SuK9NeGdBpiawn6cv6QM1uc4QQHMNpAgG89Rq5tOd4YAoRQHBe/vO8ppq60JwvJgQ4BN76EtZF0UtEWK+k57P01vatuvTHIdMBncbXyU+TrtE5AlhdGKkY2a8HwSxHw3nfoQ+SLBrjyg=
They use applets for non-standard authentication, so take a look at my second post. This one is only valid for normal authentication mechanisms, i will leave it here, because it could be valid for someone else.
You need to connect to this site first, by sending the HTTPS authentication POST, with your credentials. You should do all this communication in the "https://...".
The next step is to read a cookie value from the authentication response, and then set this cookie in to the header of the next URLconnection you will do for the resource. It is standard mechanism for server to distinguish the logged user, the authentication cookie is added to every request after login automatically by the browser, but in java, you need to do it manually.
It should work, if the server has a standard authentication mechanism, if it has different mechanism, you need to reverse enginerrig what is send, by using for example FireBug plugin, and switch to the Network tab, doing some log in, log out, downloading file, inspect what the communication looks like, and repeat it in your code.
Here you can find how to send your AUTHENTICATION POST with parameters in java: http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
You will probably need to send parameters like password and login, but it could vary, look at the firebug network tab, when you login, it will give idea what params for that looks like. For example:
password=MySecretPassword&login=MyLogin
how to get cookies:
URLConnection connection = new URL("your url").openConnection();
// insert auth parameters and set method to post
// call doInput, doOutput on connection
// read cookie
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
myCookie = you need to change cookies list to one String containing all cookies, i don't have this code right now, but is should be easy.
URLConnection resourceCon = new URL("your url").openConnection();
resourceCon.setRequestProperty("Cookie", myCookie);
I see, that they don't use standard authentication mechanism at this site:
https://cfdiau.sat.gob.mx/nidp/wsfed/ep?id=SATx509Custom&sid=0&option=credential&sid=0
They use some applets, you need to download the applets files that they have:
https://cfdiau.sat.gob.mx/nidp/applet/SgiCripto.jar
and
https://cfdiau.sat.gob.mx/nidp/applet/x509applet.jar
Then you could use some java decompiler, for instance this one: http://jd.benow.ca/
And after decompiling those project, you need to dig in to the code and do reverse-engineering to investigate how this site works.
I have made a little Java program that asks a person to enter a pin code. As soon as the pin code is entered, it reads into a "bdd.txt" file in which all the pins are stored and then it displays :) if good and :( if wrong. Simple application so far.
What I want to do is to move that "database" file into a Virtual Machine on my computer (such as Ubuntu for example), and then do the same thing. This way, it won't be local anymore, since the file will not be located at the root of my project anymore.
Here is what my application looks like :
As you can see, the app starts, the user is asked to enter is pin code. If this is a good one, the app is done, if not he has 2 more tries left until the app stops.
When the pin is entered, my program checks in "bdd.txt" if the pin is there or not. It plays the database role:
To understand what I need, it is necessary to assimilate this program to something that needs to be secure. We do not want the pins database at the same place as the program (or the device in real life). So we put it on a Virtual Machine and we have to communicate between my Windows7 Java program in Eclipse and the bdd.txt file on VMWare Player's Ubuntu.
My question is how is that possible ? How do I need to change my code to let my program reach something on my VM ? Is there a specifig technology I should use for it ? Do I need to do some configurations first ?
Here is my code :
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel container = new JPanel();
private JPasswordField p1 = new JPasswordField(4);
private JLabel label = new JLabel("Enter Pin: ");
private JButton b = new JButton("OK");
public Main() {
this.setTitle("NEEDS");
this.setSize(300, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
container.setBackground(Color.white);
container.setLayout(new BorderLayout());
container.add(p1);
JPanel top = new JPanel();
PlainDocument document =(PlainDocument)p1.getDocument();
b.addActionListener(new BoutonListener());
top.add(label);
top.add(p1);
p1.setEchoChar('*');
top.add(b);
document.setDocumentFilter(new DocumentFilter(){
#Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
String string =fb.getDocument().getText(0, fb.getDocument().getLength())+text;
if(string.length() <= 4)
super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates.
}
});
this.setContentPane(top);
this.setVisible(true);
}
class BoutonListener implements ActionListener {
private final AtomicInteger nbTry = new AtomicInteger(0);
ArrayList<Integer> pins = readPinsData(new File("bdd.txt"));
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e) {
if (nbTry.get() > 2) {
JOptionPane.showMessageDialog(null,
"Pin blocked due to 3 wrong tries");
return;
}
final String passEntered=p1.getText().replaceAll("\u00A0", "");
if (passEntered.length() != 4) {
JOptionPane.showMessageDialog(null, "Pin must be 4 digits");
return;
}
//JOptionPane.showMessageDialog(null, "Checking...");
//System.out.println("Checking...");
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
boolean authenticated = false;
if (pins.contains(Integer.parseInt(passEntered))) {
JOptionPane.showMessageDialog(null, ":)");
authenticated = true;
}
if (!authenticated) {
JOptionPane.showMessageDialog(null, ":(");
nbTry.incrementAndGet();
}
return null;
}
};
worker.execute();
}
}
//Function to read/access my bdd.txt file
static public ArrayList<Integer> readPinsData(File dataFile) {
final ArrayList<Integer> data=new ArrayList<Integer>();
try {
BufferedReader reader = new BufferedReader(new FileReader(dataFile));
String line;
try {
while ((line = reader.readLine()) != null) {
try {
data.add(Integer.parseInt(line));
} catch (NumberFormatException e) {
e.printStackTrace();
System.err.printf("error parsing line '%s'\n", line);
}
}
} finally {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("error:"+e.getMessage());
}
return data;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main();
}
});
}
}
Any ideas ? Thanks,
Florent.
A shared folder will certainly work, but there seems little point in having a VM at all, because the PIN file is also on your host machine, and java is reading it directly.
Maybe you need a client/server architecture?
You program with the UI will be the client. The client will be configured with a means of calling the server (IP address and port). The client does not have access to the bdd.txt file, but the server does.
On your VM, you have another java application, the Server. Your server listens for requests from the client. The request will contain a PIN entered by the user. The server then checks it against the PINs in the file, and responds with a yes or no. Your client receives the yes/no response from the server, and reports the result back to the user.
Read about Sockets programming here to get started
There are two things you would need to do:
Share a folder between your host OS and your VM. This will allow your Virtual Machine to access files from the host operating system. You would want to put your pin file in this folder.
Have your application read the pin file from the shared folder. This would mean changing this line:
ArrayList<Integer> pins = readPinsData(new File("bdd.txt"));
Right now, this code is reading the file bdd.txt from the current directory the user is in, which I assume is the directory your executable is in. Instead, you want this to point to the pin file in your shared directory. To make your code as flexible as possible, you may want to pass in the path to the pin file as a command line argument when you start the program.
I want to develop a piece of software that helps the user to open and close a Neo4j embedded server within my java application. Practically, I click the button and the web admin tool should be opened in the default web browser. However, I am stuck because I have a problem with the line code
InternalAbstractGraphDatabase graphdb = getGraphDb();
I don't understand how to open my implemented db which is in the variable:
private static GraphDatabaseService BORO_DB;
and has path:
public static String DB_PATH;
Below the code:
final Variable var = new Variable(true);
InternalAbstractGraphDatabase graphdb = getGraphDb();
final WrappingNeoServerBootstrapper srv;
srv = new WrappingNeoServerBootstrapper( graphdb );
final JButton btnNewButton = new JButton("Show Graph - Start Server");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (var.getVar()){
var.setVar(false);
btnNewButton.setText("Graph - Stop Server");
srv.start();
try {
String url = "http://localhost:7474";
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
}
catch (java.io.IOException e) {
System.out.println(e.getMessage());
}
}else{
var.setVar(true);
btnNewButton.setText("Show Graph - Start Server");
srv.stop();
}
}
});
May you teach me how to link my DB (BORO_DB) to getGraphDb()?
Thank you
Using DB_PATH, you can instantiate BORO_DB like this:
BORO_DB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
srv=new WrappingNeoServerBootstrapper((GraphDatabaseAPI) BORO_DB);