Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
emanresu tnuocca
Sep 2, 2011

by Athanatos
Trying to wrap my head around interfaces and inheritance,

My 'game' (it does nothing at the moment, obviously) has two major interfaces, "GameObject" and "GameNode", GameNode implements GameObject.

I'm creating a static class called "GameUtils" that will have a static method for "ProcessTime(long timeToProcess, GameObject, objectToProcess", this method will check if objectToProcess is instanceof GameNode and if it is it will call a static method for "ProcessTime(long timeToProcess, GameNode nodeToProcess" which will issue "process gameobject" to all gameobjects attached to this node.

So, the questions to this point,
1. GameObject interface only implements a static final long "globalNumberOfObjects" which is supposed to be incremented whenever an object is created and "public void action(long timeToProcess)" which contains the custom actions for every object implementing GameObject. I want GameNode object to have a constant ArrayList<GameObjects> objectCollection = new ArrayList<GameObject>() - the question is, will this create a constant reference to a new ArrayList for every class implementing GameNode?

2. In the future I wish to introduce a "SpatialNode" interface that implements an ArrayList that can only collect "SpatialGameObjects", assuming I implemented "GameNode" interface with constant reference to ArrayList<GameObject>, can I override this reference with a reference to a ArrayList<SpatialGameObject> thus essentially allowing me to preserve all the implementation I wrote for the GameNode interface? (assuming I just catch the exception that arraylist throws if I try to add an incompatible object)

thanks

Adbot
ADBOT LOVES YOU

emanresu tnuocca
Sep 2, 2011

by Athanatos
Ok, let's say I have another interface "GameObjectWithEventQueue", and I want in the future to be able to create a GameObject that implements both GameNode and EventQueue, ideally I would like to avoid copying the GameNode execution code to every class that implements game node.

That's why I thought having instanceof checks could be the right way to go, I also considered having boolean constants implemented in the interface allowing me to work around the instanceof checks.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Multiple inheritance basically.

I might have a GameObject that is both a GameNode and has EventQueue, it might have some additional functionality in addition to that. I would like Nodes and Queues to automatically process all contained objects/queued events using the method defined in the GameObject interface.

basically something like this:
code:
public static void updateObject(long time, GameObject object){
object.action(time); //first call for objects' 'custom actions'  
if(isNode){
//get all objects and send them to updateObject
}
if (hasQueue){
//get all events within range and update them
}
}

emanresu tnuocca
Sep 2, 2011

by Athanatos
1. My design is really not set in stone cause I have no assignment or any specific project I'm working on, currently I'm trying to create a framework containing some of the basic classes and code I'll need to implement a wide variety of games in the future. It's a sort of theoretical excersice at that, I'm primarily concerned with getting better with Java and development in general. The reason I came up with this design was so that I'll always be able to update all the GameObjects in my game through issuing a simple update command to the "root node" object.

2. Yeah I realize that this doesn't make sense now, I thought I could create an object reference in every instance of a class implementing game node but I understand that this is impossible cause an interface can't declare any 'class instance' fields.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Sorry for being slow on the uptake but I'm not sure I understand,

If I have the 'Process Queue' functionality and 'Process Node' functionality each implemented in a separate abstract class how will I be able to inherit both in a single class in the future?

I understand that "is-a" relationship but I was viewing it as "is a GameObject with queue" simply because for each case the update function adds extended functionality. The way I see it it's "If Object has Node, process all objects attached, If object has queue, process all queued events", I meant to use the interfaces to declare that the object is indeed a "GameObject with Queue" or whatever.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Maybe my approach here is indeed all wrong, the reason I originally went for this approach thinking 'an object is object, it might contain other objects, it might need to queue actions'.

Now it of course hits me that just because an object might need to queue events doesn't mean it needs to handle its own queue, it can pass any event it generates to its parent node, which may or may not handle queues on its own, all the way up to the 'rootNode' which will be guranteed to process events.

Essentially the event just needs to contain references to the objects relevant to it or be an inner class (http://forums.somethingawful.com/showthread.php?threadid=2779598&pagenumber=235&perpage=40#post410352326 , thanks nielsm)

With this approach, would it be sensible to define "getQueue"/"sendToQueue(GameEvent event)" methods within my GameObject interface?

And once again, thanks for all the help.

emanresu tnuocca
Sep 2, 2011

by Athanatos
You're right of course,

Essentially I want the 'GameWorld' to be able to schedule an event for every object in the game, but that's basically 'its own thing' and doesn't really concern the objects themselves.

If I'll have an object with its own queue I'll just add a GameQueue object or whatever, maybe coupled with an interface so I could more easily track which objects have queues.

emanresu tnuocca
Sep 2, 2011

by Athanatos
If you simply tile the trees one on top of the other and make sure only the right side pokes out you won't have trouble with their shape and with the door.

emanresu tnuocca
Sep 2, 2011

by Athanatos
I have a dumb question, I'm trying to create a very simple program that uses java.util.Scanner, I'm trying to parse whether the user put in a number in which case I add an object to an arrayList or entered some invalid value or pressed 'Enter' in which case I assume he doesn't want to add more objects.

I've tried something like this:
code:
while(!noMoreToppings){
	try{
		if((userInput.nextLine().length() > 0)){
			selectedToppings.add(toppingsListing.get(userInput.nextInt() - 1));
			System.out.println("Would you like to add another topping?");
			userInput.reset();
		}else{
			noMoreToppings = true;
		}
	}catch (InputMismatchException e) {
		noMoreToppings = true;
	} finally {
		;
	}
Now the problem is that I find that the user has to input the index twice otherwise it's not registered, looking at the code I'm starting to think that I need to parse the scanner (userInput) before I actually go into the if statement but I'm not really sure how to do that, I don't really know how to access the scanner without forcing it to skip a line either. Is there any simple way to just find out if next() is an int or a string?

Yes this is a homework assignment and I know this is generally frowned upon but I got into this mess by trying to do more then the very simple assignment asked for, so I hope this qualifies as a general java question.

emanresu tnuocca
Sep 2, 2011

by Athanatos

carry on then posted:

Well, I can tell you right now that every time you call nextLine() the user has to input something for the program to move on. To see if a string's an int, have a look at the Integer class and see if any of those methods looks helpful.

Okay, that makes sense, I guess I can always assign nextLine to a string and then use this method:
code:
valueOf(String s)
Returns an Integer object holding the value of the specified String.
to interpret it as an int.

Thanks!

edit: for reference:
code:
		while (!noMoreToppings) {
			String input = userInput.nextLine();
			if (input.length() > 0) {
				try {
					Integer index = new Integer(input);
					selectedToppings.add(toppingsListing.get(index - 1));
				} catch (NumberFormatException e) {
					noMoreToppings = true;
				} catch (IndexOutOfBoundsException e){
					noMoreToppings = true;
				}
			} else {
				noMoreToppings = true;
			}

		}
		userInput.close();

emanresu tnuocca fucked around with this message at 18:03 on Feb 26, 2014

emanresu tnuocca
Sep 2, 2011

by Athanatos
Hey, I got this assignment to create a primitive 'to-do list' manager with a text based menu and all sort of junk, there's a certain hierarchy where I must have 'task category' which may contain 'tasks' which may contain 'subtasks', the entire application is contained in a 'todolist' type.

So, due to the way I want my text menu class to work I decided that defining two abstract classes would greatly simplify things, so I created a TodoListElement abstract class and a TodoListContainer abstract class which extends the TodoListElement class.

One of the fields in the 'TodoListElement' class is 'TodoListContainer parentContainer' which basically points one step higher in the hierarchy towards the container this element is contained within. Now, obviously the highest level in the hierarchy which is 'todolist' by definition shouldn't actually have a parentContainer, I am not exactly sure how I can override this field and its setters\getters given that the implementation within the abstract superclass 'todolistelement' is not abstract.

Can I simply declare the field 'parentContainer' (and the setter/getter) as final (= 'null') within the 'todolist' class, will it correctly hide the super classes' field and related methods?

emanresu tnuocca
Sep 2, 2011

by Athanatos
Modifying the getter makes sense.

Yeah there is no real harm as my menu class would never call this method if its current 'focus' is on the top-level container, but this is only due to my hard coded menu logics, I was looking into this from a fool proofing perspective, though I guess you're probably correct and I should just handle this as an exception.

Thanks!

emanresu tnuocca
Sep 2, 2011

by Athanatos
Guys I have a stupid question related to my previous question a few posts back.

Is there any way at all to override a field using field declarations in a subclass or is this something I have to do either by overriding the setter\getter methods or alternatively through defining a constructor in the super class?

i.e I have
code:
Public class Snoop{

private int everyday = 420;

public int getEveryday(){
return this.everyday;}
}
and
code:
Public class Dogg extends Snoop(
private int everyday = 840;
}
so Dogg.getEveryday() always returns 420 in this example, is there anyway to override the field in the declaration?

Thanks in advance

emanresu tnuocca
Sep 2, 2011

by Athanatos
Thanks guys. yeah apologies for the weed jokes I wanted to inject some humor into the question, I guess I failed.

The motivation for thinking about this issue was that I was creating a simple text menu and I was looking for ways to simplify the menu logics as much as possible, I basically wanted my classes to each have a field that references an object from an enum class that specifies the String to display and an array of ints that specify the valid user inputs and indeed it would seem that for this purpose it would be 'more correct' to require this menu object to be initialized in the super's constructor and require the sub-classes to instantiate the super only using the permitted constructor.

Overriding the getters is possible but makes less sense in this context.

So, once again, thanks.

emanresu tnuocca fucked around with this message at 15:00 on Jul 14, 2014

emanresu tnuocca
Sep 2, 2011

by Athanatos
Hey guys, I've got yet another stupid question.

I'm screwing around with Swing a bit, I was trying to create a very simple app that draws circles of different sizes, assigns them a random velocity and direction and just lets them bounce a bit.

http://codepaste.net/ruvug9

Generally it works, but there's some weird behavior when the balls collide with the JPanel's border, my code attempts to detect the collision and then just adds half a pi to the direction, I guess my math is wrong cause the balls don't always bounce back correctly, they often change directions several times before returning at roughly 180 degrees, where I'd expect them to always just add 90 degrees to their course... which admitedly doesn't make much sense.

Here's the relevant snippet
code:
			for (Circle fromArray : listOfCircles) {
				g.setColor(fromArray.circColor);
				if(fromArray.x > getWidth() - fromArray.radius || fromArray.y > getHeight() -fromArray.radius  || fromArray.x < 0 || fromArray.y < 0){
					fromArray.velDirecction = (fromArray.velDirecction - 0.5 * Math.PI);
					
				}
		
				g.fillOval(fromArray.x += Math.pow(fromArray.velocity * Math.sin(fromArray.velDirecction), 1), fromArray.y += Math.pow(fromArray.velocity * Math.cos(fromArray.velDirecction), 1), fromArray.radius,
						fromArray.radius);
			}
		
So, is it because I should check with an if statement whether the direction is positive or negative (I guess, greater than Pi or smaller than Pi?) and add or deduct half a pi accordingly? It's kind of stupid I know, I'd just like to know what I've hosed up.

Edit: oh and ignore that Math.Pow() thing, I realized that the sin and cos should be squared for the Pythagorean formula to maintain the amplitude of the vector but I messed it up a bit. wrong

emanresu tnuocca fucked around with this message at 13:15 on Aug 25, 2014

emanresu tnuocca
Sep 2, 2011

by Athanatos
Yeah we can but my teacher is somewhat pedantic and claims such names are confusing, I agree that it's actually much more legible the way you wrote it.

So I didn't create local variables but I understood from you guys' comments that I should perform the calculations in accordance to the 'collision case', my trigonometry is rusty and the math is all wrong but this makes more sense:
code:
				if (fromArray.x > getWidth()  - fromArray.radius) {
					fromArray.x = getWidth() - fromArray.radius + 1;
					fromArray.velDirecction += 2 * Math.asin(Math.sin(fromArray.velDirecction) * (-1));
				}
				if (fromArray.y > getHeight() - fromArray.radius + 1) {
					fromArray.y = getHeight() - fromArray.radius + 1;
					fromArray.velDirecction += 2 * Math.acos(Math.cos(fromArray.velDirecction) * (-1));
				}
				if (fromArray.x < 1) {
					fromArray.x = 2;
					fromArray.velDirecction += 2 * Math.asin(Math.sin(fromArray.velDirecction) * (-1));
				}
				if (fromArray.y < 1) {
					fromArray.y = 2;
					fromArray.velDirecction += 2 *  Math.acos(Math.cos(fromArray.velDirecction) * (-1));
				}
I probably shouldn't do the arcsin/arccos. The idea was just to reverse the direction on the axis where collision occurred but I still had issues and started messing things up, eventually all circles seem to lock to movement on the horizontal axis only. It's kind of interesting.

Yeah I should definitely figure out the correct math before tinkering with the code.

Thanks for the tips guys.

emanresu tnuocca
Sep 2, 2011

by Athanatos

Spatial posted:

I'll go one further: you shouldn't use angles at all. Angles are a horrendous way to represent direction, the only upside is familiarity with the bare numbers.

Vectors make everything much easier. In the general case you could use the reflection formula for light to bounce vectors around. In this special case where the walls are always at 90 degree angles you can turn your intuition directly into code: just as you said, when a circle hits a wall its motion on the contacting axis is negated. When the motion is a vector that's just negating a variable. :buddy:

Yeah that was kind of unnecessary I guess, I'd still love not sucking at math as much but after switching "velocity" to simply be a double[2] and ignoring the whole 'velDirection' bullshitery everything worked perfectly within 2 minutes.

So yay!

emanresu tnuocca
Sep 2, 2011

by Athanatos
Thanks, I understand the importance of writing a more legible code and sticking to conventions, in this particular example I was just trying to screw around a bit and have colorful balls jumping all over the place so I didn't mind tinkering with 'brute force', I do agree with everything you said though.

And now I have some different questions pertaining to Swing.

We were tasked with designing and implementing a user interface for a 'schedule manager' (personal diary?), I already have the scheduler written and working rather perfectly with a console/text based user interface and I had some 'creative' ideas I wanted to explore in regards to the graphic user interface, so I want to code some transitional animations and have some questions:

1. Say I have a JFrame with several JPanels attached to it, I'm trying to create a method that allows me to expand one Panel while contracting every other panel, so I tried using JFrame.getComponents() and iterating over the panels with a for loop, but even though I have 3 panels attached to the frame getComponents() doesn't seem to work, that is it never enters the loop. Am I missing something? Would it simply be better to create a field (ArralyList<JPanel>) that holds references to all attached panels (can create an add(JPanel) metod that calls add(component) while maintaining this reference list)?

2. As I want to create transitional animations, should I use a TimerTask? Or would it be better to create a simple loop that just uses System.CurrentTimeMilis() to do the transitions?

Please let me know if these questions are not clear and attach some relevant code snippets. And once again, thank you all for your help.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Hey guys,

Different question, I'm trying to load a .png resource and use it as an icon but I'm getting an exception:
code:
Uncaught error fetching image:
java.lang.NullPointerException
	at sun.awt.image.URLImageSource.getConnection(Unknown Source)
	at sun.awt.image.URLImageSource.getDecoder(Unknown Source)
	at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source)
	at sun.awt.image.ImageFetcher.fetchloop(Unknown Source)
	at sun.awt.image.ImageFetcher.run(Unknown Source)
my code is very simple and as far as I can tell the .png is found in the right folder

code:
		URL imgURL = this.getClass().getResource("./images/expand.png");
		Image expImg = Toolkit.getDefaultToolkit().createImage(imgURL);
the image is in the source folder under "images". So I can't figure out what's the problem exactly, any pointers?

emanresu tnuocca
Sep 2, 2011

by Athanatos
Argh, I placed the folder inside project/src/package, apparently it should just be at project/

oh well.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Sorry for spamming this thread with questions, I hope nobody minds too much.

I have a small problem with using an ArrayList, I had an existing project that used arrays to store objects and I wanted to switch all those annoying arrays to ArrayLists, all the classes stored in those arrays inherit from one abstract class, the thing is that one of those inheriting classes implements Comparable, and I'm required to be able to sort the ArrayList containing this inheriting class, but as the abstract superclass isn't comparable and I can't seem to cast between ArrayList<Abstract Class> to ArrayList<inheriting 'comparable' class> I feel like I might be missing something.

I can think of several ways to solve this but I feel like I'm missing something rather trivial and shouldn't start copying arrays or implementing Comparable in the abstract superclass, any hints?

emanresu tnuocca
Sep 2, 2011

by Athanatos

Internet Janitor posted:

emanresu tnuocca: I'm very confused as to why the abstract superclass couldn't implement Comparable- the contract you're expressing with those types is at odds with what you want to do, so it makes sense that it ends up clumsy.

Well, in this case it's basically just a bunch of containers where only the bottom-level object in the hierarchy is comparable, for reference it contains a LocalDate field where all the other objects in the hierarchy don't, so yeah I could implement Comparable on the abstract class but it would be rather meaningless for anything other than single inheriting class with the LocalDate field.

I was originally using Arrays.sort and would indeed like to use Collections.sort.


rhag posted:

Is there a problem with List<? extends Comparable> ? Or List<? extends MyAbstractThing> ?

Also, just as an advice, try to not work with ArrayList directly (requiring it as a parameter to a method, or returning it from a class). Work, if you can, with List or, even better, Collection.

Generally, when you need a container, think about what do you need to do with that container. That should tell you exactly what interface you should require. For example, if all I need with a container is to iterate through its members, then requiring an Iterable is the most I should ask for. If I need methods such as add, clear, remove, size, then I definitely need a Collection. If I need get(index) for example, then I need List. Or, Set for when I need the items to be unique.

When returning a container interface it allows you to change the implementation any time you wish (from ArrayList to LinkedList or to ConcurrentList if the requirements change). By asking from others for a container interface (as a parameter passed to you), you allow them to use whatever implementation they wish.

Thanks for the advice regarding containers, I'll mull over it.

Yeah I was wondering if generics were the way to go here, but I'm still confused as to how to run it through Collections.sort?

code:
public abstract class AbstractElement{
public abstract ArrayList<? extends AbstractElement>;
}
The way I figure it out (which is probably all wrong), if I have an <? extends AbstractElement> arraylist that only contains the 'low level object' (which is comparable) I'm still gonna have to copy it to a new collection with <LowLevelObject> (or otherwise bubble sort through it with casting).

emanresu tnuocca
Sep 2, 2011

by Athanatos
What's the conventional wisdom in regards to implementing ActionListeners? In the spirit of making my questions less obtuse I'll add some screenshots,

So I have my stupid TaskManager application:


At first each one of these panels implemented ActionListener and executed methods in my top-level frame class, I figured that was pretty stupid and changed it so that the toolbar and menubar no longer implement ActionListener and instead use the top-level frame as a Listener, no difficulties here.

However, when you click the add button you get a JDialog frame:


Pressing OK/Cancel, along with obviously disposing of the window, is also supposed to generate a new "TaskManagerElement" (i.e, category, task or subtask) for and add it to my data containing class, there's some logic involved in that such as checking out that there's enough space, sorting out the SubTask (yes the Collections.Sort question from earlier) and updating the JTree display, so most of its functionality relates to the main frame, however, for me to be able to create the window in one action and dispose of it in another, I'll probably need to turn the JDialog into a field in the main frame class.

Now it isn't a big deal but I'm starting to wonder if I'm doing the right thing, should I keep the JDialog's ActionListener implementation and have it execute methods in the main frame class? Is there even any convention here.

Thanks

emanresu tnuocca
Sep 2, 2011

by Athanatos
More questions:
1. I'm trying to give default focus to one text field in a dialog box but even though I've used
code:
descriptionField.requestFocusInWindow();


the focus keeps defaulting to the radio buttons, seems like it just gives focus to the first added button? Any clue about this issue?

2. This is kinda silly but is there any way to give different levels in a JTree a preset icon rather than the default "Folder/Document" thing they've got going on? I just want Level 1 to always be a folder, level 2 something else and level 3 always a document, or something along those lines. I'm really not sure how to go about this.



carry on then posted:

The convention you're looking for is called a callback: http://en.wikipedia.org/wiki/Callback_(computer_programming). Your JDialog should hold a reference to the main frame that created it, and your main frame should have some method like AddTask(TaskManagerElement) that will do everything to get the task added. The JDialog calls this and passes the task over, then closes itself. It sounds like this is close to what you have now, and it's a common pattern in GUI applications.


rhag posted:

In Java this is also known as a "listener" (look at jbutton ActionListener for example).

Thanks guys, this was helpful!

emanresu tnuocca
Sep 2, 2011

by Athanatos

1337JiveTurkey posted:

Is the dialog visible when you make the request or are you doing it when you're laying out the component before you display it?

Well, it wasn't, but now I fixed that and I execute the requestFocusInWindow() right after I set the frame visible, and it still gives focus to the checkbox.

I'm trying to look for stuff that might have gone wrong but as far as I can tell I finish populating the entire frame, then set it visible and only then request focus so it should work? :confused:

emanresu tnuocca
Sep 2, 2011

by Athanatos
Does the app try to load anything from external files? Cause I had a similar thing happen once cause I didn't copy the files to be side-by-side with the JAR file.

Also, exceptions can behave a little differently outside the IDE, an exception that might be safely ignored in the IDE can sometimes just stall things (and not display) when running in an external JAR.

emanresu tnuocca
Sep 2, 2011

by Athanatos
Hey, I have this stupid small issue,

I set up a small window with this maze like thingy that is controlled through the keyboard, there's also a text field input on a toolbar, the problem is that as soon as I click on the text field I can't get the keyboard commands to control my maze thingie, both are focusable, i'm not sure what I'm doing wrong:

code:
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame testWindow = new JFrame();
		MazeWindow mWindow = new MazeWindow(10);
		testWindow.setBounds(10, 10, 500, 500);
		testWindow.getContentPane().setLayout(new BorderLayout());
		
		JToolBar mToolBar = new JToolBar(JToolBar.VERTICAL);
		mToolBar.setMaximumSize(new Dimension(30, 500));
		
		mWindow.setFocusable(true);


		mToolBar.add(mWindow.angleInput);
		

		testWindow.getContentPane().add(mWindow, BorderLayout.CENTER);
		testWindow.getContentPane().add(mToolBar, BorderLayout.EAST);
		mWindow.addKeyListener(mWindow);
		testWindow.addKeyListener(mWindow);

		testWindow.setVisible(true);

	}
As I already posted that snippet, I always have issues with getting elements to get bounded up the way I'd want them to, the 'setMaxSize' for the toolbar doesn't seem to do anything, what's the proper method for getting that mofo a little bit slimmer?

thanks

edit: apparently pressing tab does switch focus back to the other panel, dunno why clicking it with the mouse doesn't work, guess I could make it so that pressing enter also makes it lose focus somehow.

emanresu tnuocca fucked around with this message at 11:51 on Jul 18, 2015

emanresu tnuocca
Sep 2, 2011

by Athanatos

carry on then posted:

What about putting a MouseListener on the component you want to take focus and call requestFocus() in that? It sounds like focus is being given to it by the parent window when you tab over from a control that you can focus, but you have no way of your component requesting focus for itself, for instance in response to a mouse event.

Here's a tutorial about the focus system in Swing, especially look at "Making a custom component focusable": https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html

Thank you this was helpful!

btw, do any of you guys know of a way to lock the aspect ratio of a JPanel component? I suppose I could use a component listener to ensure that width/height are the same upon resize but isn't there some more standard way to go about this?

emanresu tnuocca
Sep 2, 2011

by Athanatos
After setting an AffineTransform to invert the Y axis and set (0,0) to be the center of the window is there some method that returns the min/max values for x and y? Obviously it's pretty easy to calculate (+- getWidth / 2 basically), I just wonder if there's a way to get this value from the JPanel, cause it seems like there should be?

emanresu tnuocca
Sep 2, 2011

by Athanatos
Is there anyway to do something like this:
code:
Public Class ParticleEmitter<T extends ParticleObject>{
     public void emitParticle(){
       K particle = new K();
    }
}
I thought it would be an elegant way to make some emitter that can emit particles of different types with ease but it looks like Java doesn't agree.

Just curious if there's a way to instantiate from a generic type like that.

emanresu tnuocca
Sep 2, 2011

by Athanatos

carry on then posted:

Is it because you wrote T in the declaration but K in the method?

e: Looks like it wouldn't work even if you did. From what I can see (like http://stackoverflow.com/a/1090488), you could pass the class object itself on construction and store it in your generic class, then call newInstance() on it when you need a new particle.

Thanks. Well it looks like if I do that I'll only be able to use the default constructor. Which I guess could still work.

emanresu tnuocca
Sep 2, 2011

by Athanatos
I am probably missing point but why not just use Character.touppercase() ?

emanresu tnuocca
Sep 2, 2011

by Athanatos
Uhm yeah I was also a little confused but looking at the table: http://unicode-table.com/en/

Unicode A = '65', unicode 'a' - '97', the difference is 32, so 'a' - 'A' != 'A', looks like you need to do 'smallCaps' - 32 = 'largeCap'.

Edit: ('SmallCharacter' - (a - A)) = LargeCaps

Edit: yeah this works
code:
		
	StringBuilder builder = new StringBuilder();
	String str = "abcdefghijklmnopqrstuvw_123_ABCDEFGHIJKLMNOPQRSTUV";
	System.out.println("Original string: " + str);
	for(char ch : str.toCharArray()){
		if(ch >= 'a' && ch <= 'z'){
			builder.append((char) (ch - ('a' - 'A')));
		}else{
			builder.append(ch);
		}
	}
	System.out.println("modified string: " + builder.toString());

emanresu tnuocca fucked around with this message at 19:35 on Sep 15, 2015

emanresu tnuocca
Sep 2, 2011

by Athanatos
You guys completely lost me with subtracting to value of 'A' to turn an lowercase letter into an uppercase one. My example with (char) lowerCase - ('a' - A') worked perfectly so... what's going on? How are you guys doing it merely by subtracting 'A'?

emanresu tnuocca
Sep 2, 2011

by Athanatos
I am well aware of that, and yet as I've pointed out last page, subtracting the value of 'A' from 'a' does not return 'A', you need to subtract the difference between 'a' and 'A'.

Like I posted the previous page, the following code works:
code:
if(ch >= 'a' && ch <= 'z'){
			ch = ((char) (ch - ('a' - 'A')));
		}
however the following won't:
code:
if(ch >= 'a' && ch <= 'z'){
			ch = ((char) (ch - 'A')));
		}
Say, 'a' - 'A' = 32, which is not 'A'.

Adbot
ADBOT LOVES YOU

emanresu tnuocca
Sep 2, 2011

by Athanatos
I have a follow up question concerning the instantiation of generic classes, I last asked about this question when I wanted to make a particle system for this game exercise I'm working on and I wound up using class.newInstance() as was suggested and it works but I thought it was really unelegant and I was trying to figure out how to use a Factory method to make things a little more straightforward (and possibly avoid the try catch loop), but I am somewhat confused about the whole thing. First here's my an edited snippet of what my abstract particleEmitter<K extends ParticleObject> currently does to produce new particles

code:
	public ParticleEmitter(Class<K> particleClass, double rate, World world) {
		// partSupplier<particleClass> = particleClass::new;
		this.particleClass = particleClass;
		this.rate = rate;
		this.world = world;
		timeBetweenEmissions = 1 / rate;
	}
public void process(double tpf) {
		// TODO Auto-generated method stub
		if (parent != null)
			this.world = parent.getWorld();

		timeSinceLastBurst += tpf;

		int div = (int) (timeSinceLastBurst / timeBetweenEmissions);

		if (div > 1) {
			double modulo = timeSinceLastBurst % timeBetweenEmissions;
			timeSinceLastBurst = modulo;
			ParticleObject[] parts = new ParticleObject[div * particlesPerBurst];
			for (int i = 0; i < parts.length; i++) {
				try {
					parts[i] = particleClass.newInstance();
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if (parent != null) {
					parts[i].translate(this.parent.getWorldPoint(offset));
				} else {
					parts[i].translate(offset);
				}
				this.world.addBody(parts[i]);

			}
			setParticleDynamics(tpf, parts);
		} else {
			timeSinceLastBurst += tpf;
		}

	}
the translate and the such methods all pertain to the dyn4j physics engine and are not too relevant, as you can see when I do this I actually need to receive a Class object in the constructor, which is... weird?

The way I work now I create a class which extends the particle emitter (say, Thruster) and this class calls the super() constructor sending the relevant class to the particle emitter, in which case the generic parameter is actually seemingly never used and I'm not sure why I even bother declaring it, ideally I would have preffered creating something like ParticleEmitter<FireParticle> and not have to put the class object in the constructor, looking at explanations about Factory methods or Supplier interfaces I don't think that will work either... so try to explain in pseudocode what I'm looking for, it would be something like this:

code:
public Thruster extends ParticleEmitter<FireParticle>{
...
}
//which would use the process method in the super class to create new instances of FireParticle without sending the FireParticle.getClass() parameter


Looks like If I were to create a factory method I could do something like

code:
 
private ParticleObject partSupplier<K>(){
if(K instanceof FireParticle)
      return new FireParticle();

if(K instanceof IceParticle)
      return new IceParticle();

... etc
}
But this is also not exactly what I had in mind cause it requires changing the code every time I'd like to add support for a new particle type... so err... is there a proper way to go about this? declare the type only when creating the new ParticleEmitter instance? Or should I just stick with the newInstance() thing? I mean, I guess it isn't too bad, I just thought there should be a way to create new instances from the generic type.

Just for kicks and to show that things actually work fine now, here's what I got so far:
https://www.youtube.com/watch?v=aI8gjAmrEG8

Fake edit: now you guys got me hankering to work with JSON to define my levels and objects as well.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply