JavaFX chat Application - javafx

Im trying to build a Chat Program. i can do it when i use java awt package but with java fx i seem to be a bit confused. when you first build a java fx project all your methods even the public static void main(string args[]) is in there and there's a place where you Start the primaryStage of the coding...I have no problem coding the visual side of my program its just i dont know where i should setup the Network part of my program and where to put it when im done..
**CODE: This is Just a View**
Server extends Application{
public void start(Stage primaryStage){
//Where you setup the visual of your program
}
public static void main(String args[]){
launch(args); // Where the program will run
}
public void ServerConnection(){
//where i put the codes to setup my streams and SOCKET
}
The ServerConnection method contains other methods as well But all of those will go to the ServerConnectionMethod now My question is Where will i place my ServerConnection Method so that it will run along with the my primary Stage
Sorry for the long post..have a String ="potato";

If a JavaFX application is launched correctly, it won't use the main() method at all - you can remove it temporarily (as an experiment) and check, but chances are it's not serving any purpose other than for backwards compatibility. You certainly should not rely on the main method doing anything special in the case of an FX app; it should only call launch() and nothing else.
Instead, your main class should extend Application, and the JavaFX runtime will create an instance of it for you, create a primary stage, and call the start method providing you with a reference to that stage. From this method you can do anything you like, but bear in mind it is on the UI thread (so you should create an additional thread for any long running task, the same as you would in any other toolkit such as Swing.)

You could run this setupConnection method at the beginning of the start(Stage primaryStage) method. This way it will be executed before showing the stage. You could also just run both from the main method, but as berry120 said: You don't need to call the launch(args) method in the main, if it extends Application you're fine with just the start method.
When you are done, you could use a
stage.setOnCloseRequest(e -> {
//code to execute, something like socket.close();
});
And you could change the stage.show() to stage.showAndWait()

Related

How do I refer to the top Node in TestFX?

Just getting started with TestFX and I'm wondering how to refer to the top Node (i.e. the Stage).
Here I see it says
All TestFX tests should use verifyThat(Node, Matcher, Function) when
writing tests, so that the developer can use DebugUtils to provide
additional info as to why a test failed.
This is a useful pointer... so say I want to say verify that "the JavaFX dialog/window is at least 600 pixels wide and at most 400 pixels high"?
NB for what it's worth I'm using the org.junit approach because the examples on the TestFX github site seem to. Actually I'm a Groovy fan and would hope to switch to the Spock TestFX implementation before too long.
NB2 it occurs to me that one way to get the Stage in testing code is to make the Stage a field of the class under test:
class ClickApplication extends Application {
Stage allTheWorldsA
public void start(Stage stage) {
Parent sceneRoot = new ClickPaneGG()
Scene scene = new Scene(sceneRoot, 500, 1000)
stage.setScene(scene)
stage.show()
allTheWorldsA = stage
}
... but somehow this feels the wrong way to do things: if the Stage is passed as a parameter of start it feels like the designers didn't want you to make a class field of it.

An object reference is required for the non-static field, method, or property 'MainPage.readOut'

I'm really having problems resolving this.
The 'HandleNewTag' method is in the Droid MainActivity class. It's a non static but complains about the 'MainPage.HandleNFC' method it's calling, so I changed that to static and it didn't error.
The 'MainPage.HandleNFC' method also calls a method which was non static. I changed it to a static void to stop the error. Then inside that method, where it sets some properties of a XAML control, it complains that the control is not static which I am unable to change.
I've searched high and low on the internet to resolve this and although I can find similar errors, none of them refer to a non static control issue.
MainActivity.cs
public void HandleNewTag(object sender, NfcFormsTag e)
{
//MainPage mp = new MainPage();
byte[] bytes = e.Id;
Console.WriteLine(BitConverter.ToString(bytes));
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
Console.WriteLine(BitConverter.ToString(bytes));
// Call method to send byte stream across machine boundaries.
// Receive byte stream from beyond machine boundaries.
Console.WriteLine(BitConverter.ToString(bytes));
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
Console.WriteLine(BitConverter.ToString(bytes));
int result = BitConverter.ToInt32(bytes, 0);
MainPage.HandleNFC(result.ToString());
}
MainPage.xaml
public static void HandleNFC(string convertedtag)
{
addToReadout(convertedtag);
}
public static void addToReadout(string text)
{
Label label1 = new Label { Text = "Successfully clocked out # " + text, TextColor = Color.Black };
StackLayout sl = new StackLayout();
readOut.Children.Add(label1);
readOut.BackgroundColor = Color.Black;
readOut.Children.Count();
}
Something is wrong here. Why would you be calling your Forms MainPage (living in PCL or Shared Project) from the Xamarin.Android MainActivity? The dependency flow there is backwards. I'm also assuming "MainPage.xaml" is "MainPage.xaml.cs" as you are showing C# code and not XAML.
Either way, it looks like you want to add tags to a control on your MainPage. The HandleNewTag event handler living in MainActivity.cs probably shouldn't work like this because your solution will get complicated when you have to think about the other platforms. Typically you want your calls to triage from your PCL down to the platform specific projects, like what Xamarin.Forms.DependencyService does (basic container/IoC patterns).
I understand that on Android the NFC capabilities would require the Application or Activity Context to perform actions and the NFC readings you receive are coming in through your MainActivity. One way to handle this would be the MessagingCenter built into Xamarin.Forms. It was designed just for this purpose because then you can also send messages through the MessagingCenter from your iOS or UWP projects and everything will work fine. You would have one MessagingCenter subscription that lives in your MainPage.xaml.cs, I typically will use the constructor for that stuff.
Another option would be to create an "AppViewModel" that lives at your top level of your application. I typically make this a static variable in my App class so I can reference it from anywhere by calling App.ViewModel.(whatever). Your challenge will be taking that data and updating your UI. I would do this by just binding controls directly to the sources in that static instance and creating a "Refresh" mechanism that utilizes OnPropertyChanged to update the bindings. This is of course a more complex solution and is really built/designed around what you are trying to do exactly.
I hope this helps!
Disclosure: I work for Xamarin/Microsoft

Microsoft Fakes - Stubbing an Extension Method Shouldn't Work But It Does

I have an interface, ILoader, on which I have defined an extension method CheckLoaderDatabaseConnection:
//the extension method
public static class LoaderExtensions
{
public static void CheckLoaderDatabaseConnection(this ILoader loader)
{
//data access stuff
}
All the doumentation out there tells me I have to use shims when I want to stub an extension method because the method is static and it can't be stubbed.
True, it doesn't work in Moq because I've tried it.
But I can stub the interface in Fakes:
var loader = new MyNamespace.Fakes.StubILoader() { };
In my unit test, I pass in the stub to the constructor of the concrete instance I'm testing and when it gets to this line:
loader.CheckLoaderDatabaseConnection();
It calls the stubbed method (which does nothing) and works ok.
Why is this? I must be missing something. I haven't had to use shims here at all (though I can't stub it in Moq - when I try that, the real world extension is called & the whole thing blows up)
No, the extension method wasn't getting invoked but after rebooting from a blue screen of death earlier the extension method is now getting invoked and the unit test is failing as I would expect.
Don't understand how this was working for several days though; something weird & I don't think this question can be answered.

How do I "restart" a JavaFX Application?

I've been coding a simulation in Java and now generate graphs of the results in JavaFX. However, I'm stumped as to how to call the graphs so that when I try to run the simulation (and generate the graphs) for a second time, I don't get the "can't call launch() more than once" error. I read that launch() can only be called once, so what do I need to change to call the graphs successfully on a second run of the simulation?
public class AnswerWorker extends SwingWorker<Void, Integer> {
protected Void doInBackground() throws Exception
{
AMEC.runsimulation();
return null;
}
protected void done()
{
try {
Graphs.launch(Graphs.class, "");
JOptionPane.showMessageDialog(InputGUI.this, AMEC.unsuccesfulpercentage + "% of iterations had trucks that had to sleep over");
AMEC.unsuccesfulpercentage = 0;
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
with a pretty standard graphing class:
public class Graphs extends Application {
#Override public void start(Stage stage) {
....
stage.show();
}
}
Why are you using SwingWorker in a JavaFX application? If your graphs are computed for display in a JavaFX application, there is no reason for you to use the Event Dispatch Thread (AWT). If I'm not mistaken, With the release of JDK 8, the JavaFX Application Thread and the Event Dispatch Thread will become one, so there is no reason (yet) for you to use SwingWorker. If I really am wrong, still, there is no reason for you to use SwingWorker. Although it is possible the coupling of Swing components in JavaFX applications, you should only use EDT when manipulating Swing components, not JavaFX nodes. The following link says this:
...The JavaFX application thread is a different thread from the Swing and AWT Event Dispatch Thread (EDT), so care must be taken when embedding JavaFX code into Swing applications...
Source: http://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htm
To learn how you can put processes to be done in the background, and also find out which thread is responsible for handling the JavaFX elements, check out this link:
http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Regarding your question, I believe the beginning of a JavaFX application should be called only once. So much is, that when a JavaFX application is started, the thread of main method is captured, and is only returned when the JavaFX application is finalized. Just see the Application DOC (Especially this part). Note also that the life cycle of a JavaFX application is given by the following steps:
Life-cycle
The entry point for JavaFX applications is the Application class. The JavaFX runtime does the following, in order, whenever an application is launched:
Constructs an instance of the specified Application class
Calls the init() method
Calls the start(javafx.stage.Stage) method
Waits for the application to finish, which happens when either of
the following occur:
the application calls Platform.exit()
the last window has been closed and the implicitExit attribute on Platform is true
Calls the stop() method
You might be using the wrong approach. I believe that you should leave your JavaFX application running while you're processing something. Once you have processed what you want in the background, you should make your JavaFX application show the results. The way your JavaFX application run while something is being processed in the background is entirely up to you. Maybe you should hide the window while something is processed, and display it again with your chart done. As I said, this is something you will have to decide. I recommend you to take a look at the documentation of classes referring to the window system, starting with Window, and then Stage.
Any questions, we're here. Good Luck! :)
EDIT:
From what I'm seeing, the user jewelsea is right. Apparently it is not certain that the EDT and the JavaFX Application Thread shall become one (it would be quite interesting if that happened). But anyway, be careful not to confuse yourself with the use of both threads.

Unit Test & Log4net

I have unit test testing an action in my controller, the action writes to log4net.
When I run my action it works well - writes to log4net .
However , When I run the unit test - the action doesn't write to log4net but doesn't throw any exception.
Does anyone have a solution?
// ARRANGE
var memoryAppender = new MemoryAppender();
BasicConfigurator.Configure(memoryAppender);
// ACT
_sut.DoWhatever();
// ASSERT - using xunit - change the expression to fit your purposes
Assert.True(memoryAppender.GetEvents().Any(le => le.Level == Level.Warn), "Expected warning messages in the logs");
You don't need to add in another layer of indirection by using a logging interface (if you don't want to). I have used the abstracted way for years, but now am moving towards just using the MemoryAppender as it is testing what is actually happening. Just be sure to .Clear() the appender after each test.
Log4net does not throw exceptions: http://logging.apache.org/log4net/release/faq.html
Writing to an log on disk or in a database in a unit test is counterproductive; the whole point is automation. You shouldn't have to check the logs every time you run tests.
If you truly need to verify that a call was made to log something, you should mock the ILog interface and assert that the appropriate method was called.
If you are using a mocking framework, this is trivial. If you aren't, you can create a TestLogger class that implements or partially implements ILog and exposes extra properties that show how many times a given method was called. Your assertions will check that the methods were called as expected.
Here is an example of a class to be tested:
public class MyComponent
{
private readonly ILog _log;
public MyComponent(ILog log)
{
_log = log;
}
public string DoSomething(int arg)
{
_log.InfoFormat("Argument was [{0}]", arg);
return arg.ToString();
}
}
and the test (using Rhino.Mocks to mock the ILog):
[TestClass]
public class MyComponentTests
{
[TestMethod]
public void DoSomethingTest()
{
var logger = MockRepository.GenerateStub<ILog>();
var component = new MyComponent(logger);
var result = component.DoSomething(8);
Assert.AreEqual("8", result);
logger.AssertWasCalled(l => l.InfoFormat(Arg<string>.Is.Anything, Arg<int>.Is.Equal(8)));
}
}
Try adding:
[assembly: log4net.Config.XmlConfigurator()]
To the AssemblyInfo.cs (or init log4net any other way).
Or try using AssemblyInitialize as suggested in this answer.
It is your log4net configuration. Right now it might be in your web.config or log4net.config file in the web/bin. You have to place it in a common location and make it discoverable by both web app and test. Or you have to put it into your unittest.project=>app.config file. But if you have many test projects, it would be duplicated in number of places. So the ideal would be to put it in a common place.
Here's another possible solution if none of the other solutions work for you...
Try writing your log file to the root of the c drive. By default, I set log4net to write to the current directory which is always the directory the unit test is running from right?... wrong! I'm running windows 8 with vs 2012 using MS Unit Test, and it writes the file to a local temp directory which gets deleted after the unit test completes. In my setup it writes the file to here:
C:\Users\[myself]\AppData\Local\Temp\TestResults
Bottom line, any unit tests I write for now on, are going to use a full absolute log file path and not a relative one.

Resources