Anonymous functions in java - java

I have a class called LinkGroup which holds some game objects. I call Rotate to set some rotation variables for these objects. Whenever my game hits its update loop, I rotate the objects according to the rotation variables. If they've rotated enough, I fire an onComplete callback.
The following code works...
public void Rotate(){
_currentRotation = _0;
_targetRotation = 180; //degrees
_rotationSpeed = 50;
try{
_onComplete = LinkGroup.class.getDeclaredMethod("rotateComplete", null);
}
catch(Exception ex){
}
}
...but this is ugly.
I don't like having to declare the method rotateComplete and manually link it to Rotate via a string. Is there something similar to anonymous functions in C# so I can just declared the rotateComplete method inside the Rotate method?
For bonus points, is there a better way to implement the required exception handling for "getDeclaredMethod"? Terseness is a preference.

From my understanding, I believe you are trying to call onRotateComplete() method in the LinkGroup class whenever some game object is been rotated. You can use the pattern that Java Swing uses for handling button clicks or other events: This could be done this way:
Define an interface
interface IRotateHandler {
public void onRotateComplete();
}
Change the Rotate() to Rotate(IRotateHandler handler) and then in LinkGroup class you can call your game object like this.
gameObject.Rotate(new IRotateHandler() {
public void onRotateComplete() {
/* do your stuff!
}
}

You don't need to use getDeclaredMethod. Just make _onComplete be a Runnable (or something similar), and create an anonymous class:
public void Rotate(){
_currentRotation = _0;
_targetRotation = 180; //degrees
_rotationSpeed = 50;
_onComplete = new Runnable() {
public void run() {
rotateComplete();
}
};
}

Java 7 doesn't yet have closures. Java 8 will. So, for the time being, there's no way to write that function anonymously in Java.
As for the error handling, a quick glance at the API shows me that you throw two RuntimeExceptions and a ReflectiveOperationException. Catching Exception may be your best bet, unless you wanted to catch all three of these possible exceptions differently, and take different action based on each.

Related

(JDA) How do I check for two different event types in the same method?

I know this sounds super simple and dumb but honestly im new to java and am having trouble figuring this out.
I have a class Reactions that checks for a react and a method onGameStart that startups a "game" i made (or will make)
#Override
public void onMessageReactionAdd(MessageReactionAddEvent e) {
Game start = new Game();
TextChannel pOneChannel = e.getGuild().getTextChannelsByName("player-1",true).get(0);
TextChannel pTwoChannel = e.getGuild().getTextChannelsByName("player-2",true).get(0);
if(e.getTextChannel().getIdLong() == channelID) {
pOneChannel.sendMessage(playerOne()).queue();
pTwoChannel.sendMessage(playerTwo()).queue();
}
if(e.getTextChannel() == pOneChannel) {
if(e.getTextChannel() != pTwoChannel)
printMessage("Waiting for players...", e);
else
start.onGameStart();
}
else if(e.getTextChannel() == pTwoChannel) {
if(e.getTextChannel() != pOneChannel)
printMessage("Waiting for players...", e);
else
start.onGameStart();
}
}
Before, I had the class Game require a MessageReceivedEvent. But of course this would mean I would need that as a parameter in the above class. When adding it to the above class, I can no longer override and it doesnt work.
So then I made my Game class have a method that runs with a MessageReceivedEvent that is just passed in with a null value. But of course this doesnt work, I need a real value. Does anyone know how to accomplish this?
Also another error I have is that I'd like to check for an emote response in the player 1 and player two channels. When there exists a response in both, start the game. I tried to write that above but it just runs Waiting for players.. every time. Any help is appreciated, thank you.
You can not process multiple Event-Types with one method. It's that simple. The Event Structure calls a generic method (EventListener#onEvent(GenericEvent e)) on each individual Event. That includes everything, like receiving a message or a new reaction.
However I assume your Listener extends the ListenerAdapter-Class. This class implements some logic that splits all events in seperate methods. These methods are the one you are overriding. These are only provided for Singular Events (although there are some supertypes of events). If you want something to happen on two different event types you have basically two options:
You use the GenericEvent and parse everything yourself (I do not recommend doing this, but it is possible)
You override all Events you need and call a helper Method as shown below:
#Override
public void onMessageReceivedEvent(MessageReceivedEvent event) {
utilMethod(/*add Args here*/);
}
#Override
public void onMessageReceivedEvent(MessageReceivedEvent event) {
utilMethod(/*add Args here*/);
}
private void utilMethod(/*add Args here*/) {
// do stuff
}
However these methods are still called for every event individually. Assume you and a friend send two messages at the exact same time (theoretically). JDA would still trigger the method two times with information for each message individually. If you want to do a ready check (since I assume you want to do something like that) you have to save the state of your game and update it depending on the messages you receive.
E.g. you could have a class player like this:
public class Player {
long id; // Represents the Discord ID
boolean ready = false; // Update this on a message
// ... some other stuff
}
and then update the Player#ready field when you receive the event and then check if all players are ready.
Hope this helps you understand the Event-Architecture of JDA a little better :D

How can I invoke a Processing method from outside a Processing sketch?

I want to have a method invokeProcessingMethod(String name, Object... args) that invokes a method from Processing and returns any value that may result.
I already have a method invokeMethod(String name, Object...args) that invokes a method from a superclass on the current instance, so I thought an implementation of this would be create a sketch with the method I already have
class ProcessingRELP extends PApplet{
public static void main(String[] args) {
PApplet.main("ProcessingRELP");
}
void settings(){
}
void setup() {
}
void draw() {
}
invokeProcessingMethod(String name, Object... args) {
invokeMethod(name, args);
}
}
and then do something like
class Test {
public static void main(String[] args) {
ProcessingRELP sketch = new ProcessingRELP();
Object data = sketch.invokeProcessingMethod("textWidth", "hello");
}
}
but I get the following exception because I am not invoking the Processing method in setup or draw
Exception in thread "main" java.lang.NullPointerException
at processing.core.PApplet.textWidth(PApplet.java:12960)
at ProcessingRELP.invokeProcessingMethod(ProcessingRELP.java:27)
at Test.main(Test.java:25)
Is there anyway to invoke a Processing method outside the sketch or a creative way to still do it in the sketch but be able to retrieve the data from outside the sketch?
You need to run the sketch first, because you are trying to invoke methods that depend on the runtime of the sketch (textWidth() uses the textFont and textSize of a live sketch in its calculation) and not static methods. Simply instantiating a ProcessingRELP object will not run it; this can be done with the following:
ProcessingRELP sketch = new ProcessingRELP();
PApplet.runSketch(new String[]{"--location=0,0", ""}, sketch);
Now you are able to call your method since the sketch is running.
I don't know of a way to initialize a Processing sketch in a way that gives you a reference to it. You need to use the PApplet.main() function:
String[] appletArgs = new String[] { "MySketch" };
PApplet.main("ProcessingRELP");
Shameless self-promotion: here is a tutorial on using Processing as a Java library.
On top of that, I would be very suspicious of your invokeMethod() approach. Why can't you just invoke the function directly?
Something like this:
float stringWidth = sketch.textWidth("hello");
Either way, I think you're going to need to refactor your code to use the PApplet.main() function instead of assuming you have a reference to the sketch itself.
You could do something like move your logic into the setup() function of your sketch class. But either way, your Processing sketch needs to be the entry point.

Swing Timer on main(String[]) exits the program after the time specified

I need to generate a new Thread every 2 seconds. So I tried to use the Timer class in the main(String[]) method but my program just exists after the milliseconds I specified in the Timer constructor.
Program.java:
public class Program
{
private static int panelWidth;
private static int panelHeight;
private static MyPanel panel = new MyPanel();
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
frame.add(Program.panel);
Program.panelWidth = frame.getWidth();
Program.panelHeight = frame.getHeight();
Timer generateBallTimer = new Timer(2000, new GenerateBalls());
while (true)
{
generateBallTimer.start();
}
} // End of main method
/**
* Generate a new ball every 2 seconds.
*
*/
public static class GenerateBalls implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
Program.generateBalls();
}
}
public static void generateBalls()
{
// Generate a ball each 2 seconds
while (true)
{
Program.panel.balls.add(new Ball(Program.panel));
}
}
} // End of program class
If in the Timer constructor I will specify 3000ms my program will be closed after 3 seconds and so on.
What am I doing wrong here?
Can you give me example of that "display list"?
You talk about "balls". What does your program need to know about a ball? Probably its position, maybe its speed, maybe its mass. Size? color? other stuff? It's up to you. The simplest implementation of a Ball object would just be a class with public fields to hold all of that information. Then, if Ball is the only kind of moving object in your animation, then your display list could just be a List<Ball>.
In a more complicated program, your Ball class might be an extension of some more general class, maybe VisibleObject, and then your display list would be a List<VisibleObject>.
As far as I know,for all the objects in a game to work concurrently they need to be Threads.
In a sense, you are right because there is only one class in all of Java that can do any work at all, and that class is Thread. No other class actually ever does anything. Other classes merely define methods that can be called by threads.
The trick is, to decouple the threads in the program from the work that they do. That's the motivation for the Runnable interface. Instead of having one object that both is a thread and also, describes the work to be done by the thread, you can have two classes; One takes care of all the thread-y stuff (.start(), .interrupt(), .join(), ...), and the other describes the work to be done (.run()).
Some say, it's hard to write a program that has too many classes/objects, but it's easy to write one that has too few.
As long as your Ball objects or your VisibleObject objects cleanly describe the things that you want to see on the screen and the ways in which you want to see those things move, there's no reason why each one's methods must be called by its own dedicated thread. There's no reason why you can't have just one thread that does the calculations for each one in its turn.

Java synchronizing Threads with Swing

I've written a program which displays balls in a window which are moving and which absorb each other with a certain probability when getting in contact.
The current version works, the balls's movement is been calculated every time the paintComponent method is (implicitely) invoked:
public class ColliderPanel extends JPanel {
...
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
// calculate balls's movement
Random r = new Random();
ListIterator<Ball> it = cp.getColliderPanel().balls.listIterator();
Vector<Ball> ballsToRemove = new Vector<Ball>();
while (it.hasNext()) {
Ball b = it.next();
b.move(1.0 / 60.0);
b.collideFrame(cp.getColliderPanel().getSize());
ListIterator<Ball> it2 = cp.getColliderPanel().balls.listIterator(it.nextIndex());
while (it2.hasNext()) {
Ball b2 = it2.next();
if (b.collide(b2)) {
if (r.nextDouble() < 0.5) {
if (b.m > b2.m) {
b.swallow(b2);
ballsToRemove.add(b2);
} else {
b2.swallow(b);
ballsToRemove.add(b);
}
}
}
}
}
cp.getColliderPanel().balls.removeAll(ballsToRemove);
try {
Thread.sleep((long) (1000.0 / 60.0));
} catch (InterruptedException e) {
e.printStackTrace();
}
for(Ball b : balls) b.draw(g);
repaint();
}
...
}
Now I want to outsource the calculation of the balls's movement to a second thread. I tried to create another class SimulateBallsMovement implements Runnable which does the calculation in the overriden run method and created a new Thread in ColliderPanel, which has SimulateBallsMovement as Runnable-object.
public class ColliderPanel extends JPanel {
private Thread simThread = new Thread(new SimulateBallsMovement());
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
// calculate balls's movement
// what to to here? how to synchronize the painting and the calculation?
for(Ball b : balls) b.draw(g);
repaint();
}
...
}
My problem is that I don't know how to synchronize the painting of the balls and the movement calculation? Does ColliderPanel even need the Thread as a member? I just found tutorials on how the synchronize two threads which invoke the same method, but what do I want to do here?
The main thing to remember with Swing is that almost none of the Swing methods should be called from any other thread except the Swing Event Dispatch Thread (EDT).
The EDT is what sits in a loop, waiting for key presses, mouse clicks, and other events, and calling your handlers each time an event happens that interests your program.
Whenever any of your other threads wants to do something that will affect the GUI, it should call the SwingUtilities.invokeLater(r) method where r is some Runnable object. The invokeLater(r) method will post an event containing r to the event queue, and the EDT will handle the event by calling r.run(). The r.run() method can then safely call whatever Swing methods you need it to call.
This looks like classic producer consumer scenario. The thread which calculates ball movements is producer and the thread which paints them is consumer. Check out these tutorial on the topic: http://www.tutorialspoint.com/javaexamples/thread_procon.htm or https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
One suggestion is to move the calculations into a swingworkers background processing method and calling repaint in done method of the worker.
To simplify the use of the AWT thread mechanism, and async component data fetching and component enable/disable while loading data, I wrote the ComponentUpdateThread, a long time ago. It makes it terribly easy to do updates of data and get the right things done in the right thread context.
https://github.com/greggwon/SwingUtil/blob/master/java/main/src1.5/org/wonderly/swing/ComponentUpdateThread.java
new ComponentUpdateThread( button1, button2 ) {
}.start();
is the basic premise of how you use it. All listened components will recursively be traversed and disabled by the actions of start(). There are three methods that you can implement.
The first one, setup(), is invoked by an AWT event thread, and should do anything to components (aside from disabling things that the cons parameters will make happen). This maybe simple things like emptying a list model etc.
The construct() method is invoked by an async, random thread. This method should "go get the data" to be used to populate controls, and put it into an appropriate container structure that it will return.
Finally, finished() is invoked by an AWT Event thread after construct() returns, and it should call getValue() to get the returned value from construct() activities, and then push that data into models/components as appropriate. finished() needs to call super.finished() at the right moment to "enable" the components passed into the cons. You can then disable things conditionally such as last selection in a list, options in checkboxes etc, and then return.
Here's an example of these methods taken from the javadocs. This shows the use of older APIs and doesn't include the fact that with generics, you can now make construct() a generic method with getValue() returning the same type. I have a version of this code that does all kinds of things that have been added more lately into Java.
This code is just to demonstrate the concepts around separation of thread use into separate methods so that you don't have to use SwingWorker directly, all over the place, but can use a more generic mechanism such as this.
My latest version of this code, includes the ability to chain together and next invocations so that more complex data retrieval and population can occur.
Ultimately, it would be really nice to just provide a ModelUpdater class that you could provide the component and any related model details to so that there was a compartmentalized use of data sourcing from remote access mechanisms.
public void setup() {
super.setup();
list.setEnabled(false);
list.clearSelection();
}
public Object construct() {
try {
Vector v = remote.getData();
Collections.sort( v );
return v;
} catch( Exception ex ) {
reportException(ex);
}
return null;
}
public void finished() {
try {
Vector v = (Vector)getValue();
list.setListData(v);
} finally {
super.finished();
list.setEnabled(true);
edit.setEnabled(false);
del.setEnaled(false);
}
}

Java: How can I time simple events to happen after X seconds?

I'm playing around with Java and I've got myself a class for an NPC in a game. One method is called when they collide with another object:
public void collided_in_to(Entity ent) {
if(ent.equals(game.player)) {
this.speak = "Ouch!";
}
}
What I want to do, which I figured was going to be simple, is set this.speak to "" after a given amount of seconds. Coming from a web background, I was looking for an equivalent of Javascripts setTimeout().
I've tried using various timer snippets, such as using Swing timers, but in that case it seemed like every timer would call the same public void actionPerformed(ActionEvent e) method, and so with multiple timers for different events I had no way to differentiate between them. Others used inline anonymous classes, but then I have no way to pass non-final parameters to it.
Is there something I'm missing for this use case, where I want very small simple things to happen after a set time? (Instance method called, variable set, etc.)
Thanks!
How about writing you own simple Timer? I would think of something like this :
public class Timer {
long start = 0;
long delay;
public Timer(long delay) {
this.delay = delay;
}
public void start() {
this.start = System.currentTimeMillis();
}
public boolean isExpired() {
return (System.currentTimeMillis() - this.start) > this.delay;
}
}
Then instantiate the Timer class as a class member and call start() when you want to start the timer.
In your method you call
public void collided_in_to(Entity ent) {
if(ent.equals(game.player)) {
if(this.timer.isExpired()) this.speak = "";
else this.speak = "Ouch!";
}
}
If you're using a game loop you could simply make a seconds passed verification.
Have you considered threads? Thread.sleep() can be used fairly effectively to time it.

Categories