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
ynef
Jun 12, 2002

404notfound posted:

One more thing you can do to clean up the code. I'm assuming you fixed the code by asking for input both before the while loop and also within the loop at the end. While this works, duplicating code is generally frowned upon.
I'd even go as far as suggesting making the if statements have blocks (just to avoid the classical bug where you add another indented statement and don't realize that it will always execute since the compiler does not regard it as having any relation to the if-statement) and changing the System.exit() error code from 1 to 0, since typing a negative number is the "normal" (as in non-erroneous) way of exiting this program. You know, if this will be graded by someone at some point.

Adbot
ADBOT LOVES YOU

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.
So, I guess I discovered something worth sharing with the class. In an attempt to write a kind-of-gross introspective "Bean Converter" :

code:
public <K> convertBean(Object base, Class<K> outputClass) {
 // for every `public <T> T getSomething()` in base with a corresponding `public <U extends T> void setSomething(U something)` in outputClass, 
 // create an instance of outputClass where outputClass.something = base.something
}
I ran into an issue with primitives and typecasting. It turns out:
code:
Collection.class.isAssignableFrom(List.class); // true
int.class.isAssignableFrom(Integer.class); // false
Integer.class.isAssignableFrom(int.class); // also false
But Guava Primitives can help you figure out if something is really safe to cast:
code:
Primitives.wrap(int.class).equals(Primitives.wrap(Integer.class)); //true
Primitives.wrap(Collection.class).isAssignableFrom(Primitives.wrap(List.class)); //also true
Primitives.wrap and Primitives.unwrap return the input class if it's not actually a primitive or it's wrapper.

For my utility function, type erasure is still a significant headache, but luckily I'm able to make some assumptions about instances of K extending an interface which exposes a map of <CollectionFieldName, CollectionFieldType>.


Speaking of type erasure, boy is that inconvenient! I know it's not being addressed in any way in Java 8, but do any of you know if there are murmurings about ever resolving it? To my understanding, it's an artifact of not wanting to change Java Bytecode between 4 & 5, where Generics were introduced. Is this still a concern? Might we see somehthing in Java 9?

TheresaJayne
Jul 1, 2011
We have a Converter that works using getters and setters found by reflection, there is a sort of issue with some of the logic with recursion but it works well,

The 3rd party library we use is net.vidageek.mirror.dsl.Mirror

http://projetos.vidageek.net/mirror/mirror/

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
So is there any kind of at least small consensus on whether using GUI builders is good or not? I look at my raw (and bleeding) code and a sperg in me is biting to rewrite it all from scatch to make it pretty but I don't know if I should stay in Eclipse or move to Netbeans.

Volguus
Mar 3, 2009

supermikhail posted:

So is there any kind of at least small consensus on whether using GUI builders is good or not? I look at my raw (and bleeding) code and a sperg in me is biting to rewrite it all from scatch to make it pretty but I don't know if I should stay in Eclipse or move to Netbeans.

I have never seen a gui builder to generate human readable/maintainable code. Sometimes it is not needed (windows resource files for example), sometimes is critical (swing). The main reason why is critical for the swing code to be easy to read/maintain is because of the multitude of very good IDEs out there, which means that every programmer has a favorite and hates the others. Using a UI builder, you will essentially force whoever maintains your code to use the same IDE/UI Builder as you.

Since it's so trivial (imo) to write nice decent code for your ui in swing, i believe that using a ui builder can only hinder not help. Using something like guice will make it even more trivial, and nice looking.
Of course, this is my opinion, and others will not agree with me. At the end of the day it's your choice. All I can hope is that I will never have to maintain your code :). And, if this is homework or something that nobody else will ever see but you ... then go wild, use any/all of the ui builders in existence.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
Okay, even if it's a personal project, I can't be sure I'd keep on using NetBeans if I switched to it, because last time it ate all my memory. Sooo...

Is there a good way to determine the optimal size of a component (without a GUI builder) when it's fed changing strings (such as stretch the component from one side of the monitor to the other), that doesn't involve trial and error?

Also, I've made a singleton dialog (a static instance through a static method), because under Ubuntu when I switch from my Java app then go back it only brings up the main window from under all the other applications (the dialog is non-modal). But when I close the dialog now, it's naturally kept in the memory, which is not exactly a resource-hog, but looks kind of unprofessional. Can I do anything?

Edit: Goddamit. I haven't tested anything outside Eclipse in ages, and it turns out under Ubuntu when you open a jar the running directory is the home directory, but I need the one where the jar is... Any hints?

supermikhail fucked around with this message at 06:33 on Sep 13, 2013

Volguus
Mar 3, 2009

supermikhail posted:

Okay, even if it's a personal project, I can't be sure I'd keep on using NetBeans if I switched to it, because last time it ate all my memory. Sooo...

Is there a good way to determine the optimal size of a component (without a GUI builder) when it's fed changing strings (such as stretch the component from one side of the monitor to the other), that doesn't involve trial and error?

Also, I've made a singleton dialog (a static instance through a static method), because under Ubuntu when I switch from my Java app then go back it only brings up the main window from under all the other applications (the dialog is non-modal). But when I close the dialog now, it's naturally kept in the memory, which is not exactly a resource-hog, but looks kind of unprofessional. Can I do anything?

Edit: Goddamit. I haven't tested anything outside Eclipse in ages, and it turns out under Ubuntu when you open a jar the running directory is the home directory, but I need the one where the jar is... Any hints?

Hmm ... I'm not sure I understand the questions, but I'll do my best to answer:
Optimal size of a component:
Why do you need that? Why don't you let the layout tackle that for you? I'm not sure it is such a good idea to resize dialogs/frames automatically (from an usability point of view). A Jlabel can display a string on multiple lines if needed, or, worst case scenario, you can calculate the bounds needed for a particular text using font metrics.

Dialog:
The singleton design pattern is rarely the good choice, but anyway. Once you call dispose() on a dialog (such as when you click OK or Cancel) the memory will be reclaimed by the JVM. Therefore, you don't have to worry about that.
If the Dialog is non-modal, then it should appear like any other window in the window switch list. And then you can choose to bring it to the front or any other window. Make it modal if you want to be on top of your other application's windows.

It may help to consult the official swing tutorial. It may answer a lot of your questions : http://docs.oracle.com/javase/tutorial/uiswing/


edit:
Regarding the jar question: I have no idea what do you actually need. To put a jar on the classpath? Do that in project properties.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
Okay, I guess I'll have to go the easy road, because Java has clearly defeated me here. dispose doesn't work on my dialog because it keeps all the info (and even somehow manages to keep a Swing timer running.)

Also, the dialog doesn't appear in the window switch list, but that's an Ubuntu thing, then. Maybe it doesn't like that it's a dialog, and only wants to watch frames, or dialogs aren't expected to be non-modal, or it doesn't care about separate windows but only applications. Whatever.

The jar I was referring to is the one that your application ends up in. And it calls the wrong place home here.

Volguus
Mar 3, 2009

supermikhail posted:

Okay, I guess I'll have to go the easy road, because Java has clearly defeated me here. dispose doesn't work on my dialog because it keeps all the info (and even somehow manages to keep a Swing timer running.)

Also, the dialog doesn't appear in the window switch list, but that's an Ubuntu thing, then. Maybe it doesn't like that it's a dialog, and only wants to watch frames, or dialogs aren't expected to be non-modal, or it doesn't care about separate windows but only applications. Whatever.

The jar I was referring to is the one that your application ends up in. And it calls the wrong place home here.

Well, if you create/start a timer when you create a dialog, why don't you stop it upon disposing? And then set it to null to tell the GC that it can reclaim the memory. And if you have listeners, anonymous classes inside the dialog, give them a name (assign them to a variable) and remove them when disposing. Also, assigning them to null afterwards wont hurt either. This is java, but not everything is being taken care of.

There are some JDialog settings (i forgot now what method exactly) that can tell it to show up in the taskbar (and probably on the switch list).
Edit: I was wrong, JDialog doesnt show on the taskbar. Use a JFrame for that (since it's not modal anyway, there should be no difference).

About the jar:
everything can be set in the project properties in Eclipse (and other ide's). Where the application starts (work directory), where it should put the compiled classes, etc.

Volguus fucked around with this message at 15:59 on Sep 13, 2013

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
In fact I tried stopping the timer on window closing, but it didn't do any good. Neither does setting it to null, and I don't have any anonymous listeners (although, everything is implemented by the dialog itself).

I'll remake it as a window then, thanks for the info.

The project properties thing I still can't figure out, and I don't want to sound like a wuss, but I'm leaning towards putting the location of changeable files into user's hands (via preferences). It's not necessarily less coding, but at least it's something I can work with.

Volguus
Mar 3, 2009
Then maybe there's something else going on, and I can't help without seeing code.

Regarding jar: so you want to load preference files? That you initally was thinking on placing in the jar itself? If that's so, you can load any resource on the classpath using getResourceAsStream(resourcename) from your classloader. Something like: this.getClass().getClassLoader().getResourceAsStream("/my/path/to/the/resource"); . If the path starts with a / it will be absolute to the top of the classpath (your jar or bin folder). Otherwise it will be relative to whatever package "this" is in.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
The dispose doc says that you only need to call setVisible(true) on a disposed window to set it back the way it was, so I'm assuming it's the... Goddamit! Could it be because I add the dialog as an eventlistener to a completely separate object? Ugh. I'm so tired of creating and deleting the windowlistener over and over today. :downs:

rhag posted:

Regarding jar: so you want to load preference files? That you initally was thinking on placing in the jar itself? If that's so, you can load any resource on the classpath using getResourceAsStream(resourcename) from your classloader. Something like: this.getClass().getClassLoader().getResourceAsStream("/my/path/to/the/resource"); . If the path starts with a / it will be absolute to the top of the classpath (your jar or bin folder). Otherwise it will be relative to whatever package "this" is in.

That looks tempting. Maybe I'll reconsider.

What's more intuitive - to tell [my future self] that to carry over saved data I need to copy the application folder, or to check my preferences to see where the data is saved and copy that?

Volguus
Mar 3, 2009

supermikhail posted:

The dispose doc says that you only need to call setVisible(true) on a disposed window to set it back the way it was, so I'm assuming it's the... Goddamit! Could it be because I add the dialog as an eventlistener to a completely separate object? Ugh. I'm so tired of creating and deleting the windowlistener over and over today. :downs:


This looks a bit weird. Why would anyone care what happens with the dialog? If they do, why don't they add their own listener to the dialog to be notified when that something is happening?

supermikhail posted:

What's more intuitive - to tell [my future self] that to carry over saved data I need to copy the application folder, or to check my preferences to see where the data is saved and copy that?

This is an answer that only you have. Personally I would store paths and stuff in the user's preference folder. You don't know if you can write the folder where the application resides, and you don't know where the user would like to store their data (could be /tmp, could be /home, could be an usb ... could be whatever other weird mounted path where they have enough space).
And preferences ... let the JVM take care of that. In windows they're store in the registry, in *NIX-es are store in the user's home folder.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."

rhag posted:

This looks a bit weird. Why would anyone care what happens with the dialog? If they do, why don't they add their own listener to the dialog to be notified when that something is happening?
You know, you may be right. I didn't exactly understand what you said, but trying to formulate a coherent justification of my code led me to believe that maybe I don't need transient eventlisteners in my class that is simply a piece of data. I keep forgetting what I'm using them for at all, and where.

rhag posted:

ve. Personally I would store paths and stuff in the user's preference folder. You don't know if you can write the folder where the application resides, and you don't know where the user would like to store their data (could be /tmp, could be /home, could be an usb ... could be whatever other weird mounted path where they have enough space).
And preferences ... let the JVM take care of that. In windows they're store in the registry, in *NIX-es are store in the user's home folder.
I have my own nitpicky reasons for wanting to manually handle window positioning, resizing, etc. information storage (which is what I mainly mean by preferences here). Like remembering where a window should go if it's un-maximized again, having been closed and opened.

mister_gosh
May 24, 2002

Can someone point me in the right direction? I don't know where to start, what terms or libraries to look at...

I have a Swing application.

I have tree like objects within it. I want to be able to click and drag an object from my application to a third-party application (not Java). That third party application has it's own C++ like proprietary language that I'm going to do something with the "Java object".

I'll probably want to get the contents of the clipboard from my application which means that I want a click and drag from my application to cause a my object to put something on the system clipboard if dragged outside the bounds of the application...


I'm not sure if this third party application is going to be able to change the pointer from the "no" symbol, but that may be beyond the scope of this thread.

The Transferable class(es) seem like the wrong implementation as that is from Java to Java application, I believe. I'm not sure where to begin.

Volguus
Mar 3, 2009

mister_gosh posted:

Can someone point me in the right direction? I don't know where to start, what terms or libraries to look at...

I have a Swing application.

I have tree like objects within it. I want to be able to click and drag an object from my application to a third-party application (not Java). That third party application has it's own C++ like proprietary language that I'm going to do something with the "Java object".

I'll probably want to get the contents of the clipboard from my application which means that I want a click and drag from my application to cause a my object to put something on the system clipboard if dragged outside the bounds of the application...


I'm not sure if this third party application is going to be able to change the pointer from the "no" symbol, but that may be beyond the scope of this thread.

The Transferable class(es) seem like the wrong implementation as that is from Java to Java application, I believe. I'm not sure where to begin.

While I have never done that (DnD from Java to c++), Transferable is what you want. That "should" work. Just gotta set the mime type of the data correctly, and on the other side to know how to accept that kind of data (and read it).
The JVM should take care of the rest.
http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html

Volguus
Mar 3, 2009

supermikhail posted:


I have my own nitpicky reasons for wanting to manually handle window positioning, resizing, etc. information storage (which is what I mainly mean by preferences here). Like remembering where a window should go if it's un-maximized again, having been closed and opened.

You can store anything you want in the users preferences, and window positioning and size and stuff fits perfectly in that. If a window is minimized and restored, let the native UI take care of that. Upon startup though, it may be useful to show the window where it was last closed.

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.
I'm still pretty new to Java and have run into an issue. I'm working on writing a program that will determine the mean value for about 100000 datapoints by performing about 100 random simulations on each datapoint. I decided to mess around and see if I could multithread it to speed things up, so I tried to divide the datapoints up and pass them to separate threads, then perform the simulations for each batch of datapoints. I figured there'd be concurrency issues, and I want a separate instance of the variables for each thread, so I tried using ThreadLocal, but can't seem to make it work. The datapoints are stored in an ArrayList<String> and for the simulations, I've been randomizing the order by shuffling them. Apparently ThreadLocal doesn't like that. Anyways, if anyone has any ideas I'd appreciate them.

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.

Adventure Pigeon posted:

I'm still pretty new to Java and have run into an issue. I'm working on writing a program that will determine the mean value for about 100000 datapoints by performing about 100 random simulations on each datapoint. I decided to mess around and see if I could multithread it to speed things up, so I tried to divide the datapoints up and pass them to separate threads, then perform the simulations for each batch of datapoints. I figured there'd be concurrency issues, and I want a separate instance of the variables for each thread, so I tried using ThreadLocal, but can't seem to make it work. The datapoints are stored in an ArrayList<String> and for the simulations, I've been randomizing the order by shuffling them. Apparently ThreadLocal doesn't like that. Anyways, if anyone has any ideas I'd appreciate them.

It might be simpler to set things up to there just aren't any concurrency issues than it is to duplicate things among threads. The very best thing you can do if you're worried about concurrency issues is not write to a variable that might be under contention. Functions that don't mutate state are always thread-safe. (So List.get is safe, but List.set, List.add, and List.remove are not.)

It's going to be hard to troubleshoot your problem without seeing any code. I'm not really sure what's going on from your description. It sounds like the datapoints are being partitioned out to different threads (so if ThreadA is working on the 3rd datapoint, that means that no other thread will be working on the 3rd datapoint), but then you're trying to create a copy of all of the datapoints and shuffle them within each thread?

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.
Thanks for your thoughts. I want to keep every variable private within each thread. Synchronizing wouldn't work for what I want to do. Anyways, here's my program. Feel free to cross post to the coding horrors thread.




This is the primary class. It works aside from the method where I try to split things into threads using ExecutorService
http://pastebin.com/3b69ZGd1


This is the class I'm trying to multithread. I've left it without any of the modifications I've tried since none have worked and they'd just make it more confusing.
http://pastebin.com/it8ne45a


I've thought of two solutions that might work. They probably won't, but I figured I'd ask anyways.

The less elegant one is just to duplicate the second class for as many threads as I plan to use, change variable names so they're unique within each class, then deep copy every data structure I want to pass in the primary class and send them to their respective threads.

The other possibility is to turn every HashMap or ArrayList I use into an ArrayList of ArrayLists/HashMaps, then create as many deep copies or HashMaps within the ArrayList as I plan on using. After that, assign each thread a unique integer as an ID, which should be much easier to use as a ThreadLocal variable. I could use the ID to reference which position in the data structures is specific to each thread, and it'd allow for a dynamic number of threads unlike the other solution, but it'd result in some ugly code, and I have no idea how I'd perform some of the operations I want to do.

Amarkov
Jun 21, 2010
Why don't you just pass each thread its own copy of the list you're shuffling? (You could also generate a random list of indices rather than explicitly shuffling; that'd be a lot more efficient, albeit a bit more complicated.)

1337JiveTurkey
Feb 17, 2005

The GetSiteCount method I'm not quite sure what it's aiming to do, but it appears to me to be looking through the first count elements of reads, picking percent of them and returning the number of unique values. A couple of common ways to select count elements from an array are to shuffle and pick the first count or to pick elements at random and stick them in a set (which removes duplicates) until it contains count elements. The set is actually implemented in a manner very similar to the map used in the method and I noticed that you're shuffling beforehand, so I figured you're doing something similar. There's also a common way to get roughly a certain percentage of the elements by looping through the array and adding the element if a randomly generated number is less than percent. The number won't be exact like with the counting-based methods, but it's possible to do with no extra memory usage if you're not going to create a new array or anything.

Code doing all of that is certainly possible, but it seems like there's a bit of redundancy in there. For your purposes if you're going to run multiple iterations in their own threads, avoid shuffling the shared list. If you need to shuffle, make a copy for each thread. However it's likely that whatever you're working on can actually be done with no shuffling at all, just random sampling using some other method.

Max Facetime
Apr 18, 2009

The class ThreadLocal has a seductive name but it's actually used only in very specific circumstances, like one occasion per year, or less. If it was more accurately called ThreadGlobal you probably wouldn't have given it a second thought, I'd guess.

What you want to do should be possible with just regular variables, here's a tutorial about the different kinds of variables in Java and how they are used.

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.

1337JiveTurkey posted:

The GetSiteCount method I'm not quite sure what it's aiming to do, but it appears to me to be looking through the first count elements of reads, picking percent of them and returning the number of unique values. A couple of common ways to select count elements from an array are to shuffle and pick the first count or to pick elements at random and stick them in a set (which removes duplicates) until it contains count elements. The set is actually implemented in a manner very similar to the map used in the method and I noticed that you're shuffling beforehand, so I figured you're doing something similar. There's also a common way to get roughly a certain percentage of the elements by looping through the array and adding the element if a randomly generated number is less than percent. The number won't be exact like with the counting-based methods, but it's possible to do with no extra memory usage if you're not going to create a new array or anything.

Code doing all of that is certainly possible, but it seems like there's a bit of redundancy in there. For your purposes if you're going to run multiple iterations in their own threads, avoid shuffling the shared list. If you need to shuffle, make a copy for each thread. However it's likely that whatever you're working on can actually be done with no shuffling at all, just random sampling using some other method.


I'm basically using the shuffle and count method. The reason I have a few strange things in there is that the program is designed to simulate data from DNA sequencing being aligned to the genome. Each of these datapoints, which are called reads, has a percent chance of being a read aligning to a site of interest, but also a high probability for being just noise data. In addition, many of these reads that align to the genome will be repetitive and redundant. Basically, what it does is it takes the total number of reads in the simulation, picks out the number that will be valid, then places them in known valid alignments based on previously known frequency and determines how many unique sites are found.


Max Facetime posted:

The class ThreadLocal has a seductive name but it's actually used only in very specific circumstances, like one occasion per year, or less. If it was more accurately called ThreadGlobal you probably wouldn't have given it a second thought, I'd guess.

What you want to do should be possible with just regular variables, here's a tutorial about the different kinds of variables in Java and how they are used.


Thanks for the advice. I thought that ThreadLocal was designed to localize variables to a thread, but things got weird. I'll give the tutorial a look and hopefully figure something out.

Honestly, I could probably have this program run on a single thread (it would just take a few days to run). Multithreading is something I've wanted to learn, though, so I figured I'd give this a shot.

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.

Adventure Pigeon posted:

This is the primary class. It works aside from the method where I try to split things into threads using ExecutorService
http://pastebin.com/3b69ZGd1


This is the class I'm trying to multithread. I've left it without any of the modifications I've tried since none have worked and they'd just make it more confusing.
http://pastebin.com/it8ne45a

Not horrors; you're new, and still learning.

I'd implement makeThreads as follows:
Java code:
public void makeThreads(Integer threads, ArrayList<String> windows, ArrayList<String> predictions, double stat, Integer simulations) {
  int subSegmentSize = Math.ceil((double)windows.size()/threads); //we'd rather have the last thread work on fewer windows than miss up to (threads-1) windows at the end
  ExecutorService executor = Executors.newFixedThreadPool(theads);
  for (int i=0; i< threads; i++) {
    int start = i * subSegmentSize;
    int end = Math.min( (i + 1) * subSegmentSize, windows.size());
    List<String> subSegment = new ArrayList(windows.subList(start, end));
    List<String> predictionsCopy = new ArrayList(preditions);
    Runnable worker = new RunThreads(subSegment, predictionsCopy, stat, simulations);
    executor.execute(worker);
  }
  executor.shutdown();
}
Since I'm not going to presume that threads/windows.size is always going to be an integer, I put in some logic to guard against dropping your last few windows on the floor. I'm casting windows.size() to a double so that the result is a double; an int divided by an int is an int. (7/3 = 2, but 7.0/3 = 2.3333)

However, the main difference is that we're creating a new copy of things for each thread. new ArrayList(sourceList) creates an entirely separate list in memory, and changing this list doesn't cause the order or contents of any of the other lists to change. One of your bugs is that windowSegment always refers to the same list. When you passed it to a thread, you were almost immediately clearing that list's contents, and overwriting it with new contents.

Java code:
Collections.shuffle(readArray, new Random(seedValue));
This was also causing you a lot of problems. readArray is the same List as predictions and predictions1 in RunThreads, which is the same list as predictions in MakeThreads. This means that whenever any thread shuffled it's preditions list, it also shuffled the predictions list of every other thread, regardless which part of code the other threads were currently running. You might get two threads shuffling the same list at the same time, or you might get a list that's shuffled while you're using it. This is also solved by creating a new copy of the predictions list before handing it off to each thread.

Within each RunThreads instance, I'd consider creating a Random() in the constructor, and using the same Random object for each Collections.shuffle call. (Or just allow shuffle to use the default source of randomness.)

Java code:
try {
  predictionsUnformattedArray = measureSlope.loadFile(predictedFile);
  statsUnformattedArray = measureSlope.loadFile(statsFile);
} catch(Exception e) {
  if(e instanceof IOException) {
    System.out.println("YOU GOOFED");
  }
}
would more commonly be written as:

Java code:
try {
  predictionsUnformattedArray = measureSlope.loadFile(predictedFile);
  statsUnformattedArray = measureSlope.loadFile(statsFile);
} catch(IOException e) {
  System.out.println("YOU GOOFED");
  throw new RuntimeException(e);
}
I'm re-throwing the exception here because it doesn't look like your program can recover from not being able to read the input files. A RuntimeException is a "unchecked" exception. They can be caught if you're looking for them, but they generally just go all the way back up the call-stack and tell your program that it's time to die. You don't have to declare what kinds of RuntimeExceptions you're throwing, nor do you have to put them inside a try block. They're generally looked at as the "unrecoverable" kind of exception, where as checked exceptions are thrown to give the programmer a chance to handle failure gracefully.


From a Java-conventions standard, Classes are named with capitol letters and methods are named with lower-case letters.

Gravity Pike fucked around with this message at 01:02 on Sep 15, 2013

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.
quote != edit

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.

Gravity Pike posted:

Not horrors; you're new, and still learning.


Since I'm not going to presume that threads/windows.size is always going to be an integer, I put in some logic to guard against dropping your last few windows on the floor. I'm casting windows.size() to a double so that the result is a double; an int divided by an int is an int. (7/3 = 2, but 7.0/3 = 2.3333)

However, the main difference is that we're creating a new copy of things for each thread. new ArrayList(sourceList) creates an entirely separate list in memory, and changing this list doesn't cause the order or contents of any of the other lists to change. One of your bugs is that windowSegment always refers to the same list. When you passed it to a thread, you were almost immediately clearing that list's contents, and overwriting it with new contents.


This was also causing you a lot of problems. readArray is the same List as predictions and predictions1 in RunThreads, which is the same list as predictions in MakeThreads. This means that whenever any thread shuffled it's preditions list, it also shuffled the predictions list of every other thread, regardless which part of code the other threads were currently running. You might get two threads shuffling the same list at the same time, or you might get a list that's shuffled while you're using it. This is also solved by creating a new copy of the predictions list before handing it off to each thread.

Within each RunThreads instance, I'd consider creating a Random() in the constructor, and using the same Random object for each Collections.shuffle call. (Or just allow shuffle to use the default source of randomness.)


I'm re-throwing the exception here because it doesn't look like your program can recover from not being able to read the input files. A RuntimeException is a "unchecked" exception. They can be caught if you're looking for them, but they generally just go all the way back up the call-stack and tell your program that it's time to die. You don't have to declare what kinds of RuntimeExceptions you're throwing, nor do you have to put them inside a try block. They're generally looked at as the "unrecoverable" kind of exception, where as checked exceptions are thrown to give the programmer a chance to handle failure gracefully.


From a Java-conventions standard, Classes are named with capitol letters and methods are named with lower-case letters.

Thank you very much. I figured all my threads were referring to the same variables, but I didn't know how to solve it. That's why I tried the stuff with ThreadLocal. So when I say Whatever = new something, I create a new copy of the something that I can pass to threads without any memory conflicts?

1337JiveTurkey
Feb 17, 2005

Adventure Pigeon posted:

Thank you very much. I figured all my threads were referring to the same variables, but I didn't know how to solve it. That's why I tried the stuff with ThreadLocal. So when I say Whatever = new something, I create a new copy of the something that I can pass to threads without any memory conflicts?

In Java, everything's either an object or a primitive. When you create a variable or a field, primitives are stored directly at the location while objects are actually a reference to some other place in memory. When you use new, that's creating a new instance of the object in question and having the variable point to it. Related to that, the places where you're using Integer are actually references to objects rather than simply storing the number there, which is what int means. The JVM can optimize a lot of that away, but for number crunching you probably want int, double and the other primitives rather than the objects. So just using a new list and copying the values is sufficient, you don't need any ThreadLocal stuff. It's common enough that there's a specific constructor for it in most collection classes. new ArrayList<String>(oldList) makes a new list containing all of the values of the old one.

My recommendation is to pick an option which doesn't require shuffling since if it's a very large list, that's probably eating up a large proportion of your time already. If you're only taking a small number of samples from the list, then it's quicker to use one of the alternative methods I mentioned. That also helps avoid changing the list in the first place, which means you don't need to make any copies, which will be faster as well.

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.
Specifically the ArrayList<T>(Collection<? extends T> source) constructor creates a new list which contains the same objects as the source collection, in the same order that the source collection iterates over them. This means that you can create an ArrayList that contains the same elements that a Set contains, or the same elements that a LinkedList contains.

It's worth noting that these are literally the same objects, and while modifying the source list won't modify the new ArrayList, modifying one of the Objects in the source list will modify the Object in every list. Strings are safe, because strings are immutable; they can't change. However, if you had:

Java code:
class MyExample {
  public static void main(String[] args) {
    List<Dog> dogListOne = new ArrayList<Dog>();
    dogListOne.add(new Dog("Scrappy"));
    dogListOne.add(new Dog("Scooby"));
    dogListOne.add(new Dog("Snoopy"));
    
    List<Dog> dogListTwo = new ArrayList<Dog>(dogListOne);
    
    System.out.println(dogListOne.toString()); //{Scrappy, Scooby, Snoopy}
    System.out.println(dogListTwo.toString()); //{Scrappy, Scooby, Snoopy}
    
    dogListTwo.remove(0);
    
    System.out.println(dogListOne.toString()); //{Scrappy, Scooby, Snoopy}
    System.out.println(dogListTwo.toString()); //{Scooby, Snoopy}
    
    dogListTwo.get(0).setName("Lassie");
    
    System.out.println(dogListOne.toString()); //{Scrappy, Lassie, Snoopy}
    System.out.println(dogListTwo.toString()); //{Lassie, Snoopy}

    //The second object in dogListOne is the same object as the first object in dogListTwo
  }
  
  static class Dog {
    private String name;
    public Dog(String name) {
      this.name = name;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name=name;
    }
  }
}

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.

Gravity Pike posted:

Specifically the ArrayList<T>(Collection<? extends T> source) constructor creates a new list which contains the same objects as the source collection, in the same order that the source collection iterates over them. This means that you can create an ArrayList that contains the same elements that a Set contains, or the same elements that a LinkedList contains.

It's worth noting that these are literally the same objects, and while modifying the source list won't modify the new ArrayList, modifying one of the Objects in the source list will modify the Object in every list. Strings are safe, because strings are immutable; they can't change. However, if you had:


Ah, ok, so basically you can copy a list without copying the elements in the list. One question, though, if I use remove on an element in an arraylist, does the index or whatever for every element above it in the arraylist move down one?

ie if I did

code:

class MyExample {
  public static void main(String[] args) {
    List<Dog> dogListOne = new ArrayList<Dog>();
    dogListOne.add(new Dog("Scrappy"));
    dogListOne.add(new Dog("Scooby"));
    dogListOne.add(new Dog("Snoopy"));
    
    dogListOne.remove(0);

    
  static class Dog {
    private String name;
    public Dog(String name) {
      this.name = name;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name=name;
    }
  }
}

Would dogListOne.get(0) get Scooby and dogListOne.get(1) get Snoopy or would they remain at 1 and 2?

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.
I hate to tell you to RTFM, but Java has really good documentation. You can basically google any classname, and among the first few results will be a detailed description of the class, it's complete hierarchy, and a complete description of all of it's methods.

JavaDocs posted:

public E remove(int index)

Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).

Specified by:
remove in interface List<E>
Overrides:
remove in class AbstractList<E>
Parameters:
index - the index of the element to be removed
Returns:
the element that was removed from the list
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())

Volguus
Mar 3, 2009
Plus, if you use an IDE, the documentation will most likely be displayed when you hover over the method. Not to mention you can usually even look at the source code, to see how it was implemented.

ToxicFrog
Apr 26, 2008


This is not so much a Java question as a JVM deployment on windows question, but I figure it must have come up in this thread a few times.

I am trying to deploy a command-line program as a single self-contained jar. Generating the jar is trivial. On Linux I can be pretty confident that if the JRE is installed, java is in the $PATH, so I can just have a little shell script wrapper for it, or people can run it directly with java -jar foo.jar ...

On windows, though, it gets complicated. They can't just double-click on the jar, because it's a command line program. Ok, no big deal, I just wrap it in a .bat same as the shell script wrapper on linux...except I've been down this road before, and I know what a clusterfuck it is. There's no guarantee that java is in %PATH% at all; it might be in %JAVA_BIN% or %JAVA_HOME%, but you have no guarantee those are set either; and there's at least four places to look for it in the registry. And it's entirely possible for someone to have an installed and apparently working JRE with none of those set. gently caress Java on windows.

The solution that people who don't want to enter this waking nightmare seem to choose is to wrap the jar somehow in an exe. A bit of searching has turned up jsmooth and launch4j as possible solutions. Are either of those particularly recommended? Is there something else I haven't found, but should be using? Am I completely off base and there's actually a really easy, simple way to deploy command line jars on windows?

Volguus
Mar 3, 2009

ToxicFrog posted:

This is not so much a Java question as a JVM deployment on windows question, but I figure it must have come up in this thread a few times.

I am trying to deploy a command-line program as a single self-contained jar. Generating the jar is trivial. On Linux I can be pretty confident that if the JRE is installed, java is in the $PATH, so I can just have a little shell script wrapper for it, or people can run it directly with java -jar foo.jar ...

On windows, though, it gets complicated. They can't just double-click on the jar, because it's a command line program. Ok, no big deal, I just wrap it in a .bat same as the shell script wrapper on linux...except I've been down this road before, and I know what a clusterfuck it is. There's no guarantee that java is in %PATH% at all; it might be in %JAVA_BIN% or %JAVA_HOME%, but you have no guarantee those are set either; and there's at least four places to look for it in the registry. And it's entirely possible for someone to have an installed and apparently working JRE with none of those set. gently caress Java on windows.

The solution that people who don't want to enter this waking nightmare seem to choose is to wrap the jar somehow in an exe. A bit of searching has turned up jsmooth and launch4j as possible solutions. Are either of those particularly recommended? Is there something else I haven't found, but should be using? Am I completely off base and there's actually a really easy, simple way to deploy command line jars on windows?

You don't have those guarantees on linux either. I personally have my jdks installed in /home/<user>/java/jdk-version . Now, I do set PATH, JAVA_HOME, etc. properly in my .bashrc to not have to deal with those issues, but I don't have to.

The programs that you specified appear to be doing a lot of the work for you, so i'd say to give them a try. What other commercial programs do is come with a jre bundled. And then they store it in the program's folder, under a jre subfolder let's say. And then their executable (or bat file or what-have-you) just know where to load the jvm from.
For a console application though, it may not worth the trouble.

If you want to keep things simple, and not go the jsmooth/launch4j way, you can make a bat file, in which you can check for the existence of the required variables, or the java executable. If that's not found, just open the browser and go to java.com . Then the users just have to install that. If they install it from the installer, it will be in the PATH and everything will be fine.

leftist heap
Feb 28, 2013

Fun Shoe
If your assumption on Linux is that java will be on the PATH, why can't you make the same assumption for Windows?

Tesseraction
Apr 5, 2009

Looking through all my Windows environmental variables (User and System) I can't see Java on it anywhere; Java is installed, though, and java -jar works fine. I admit it's hardly a solution, but have you encountered a system where Java is installed but a call to java doesn't work?

Volguus
Mar 3, 2009

Tesseraction posted:

Looking through all my Windows environmental variables (User and System) I can't see Java on it anywhere; Java is installed, though, and java -jar works fine. I admit it's hardly a solution, but have you encountered a system where Java is installed but a call to java doesn't work?

Java is on the PATH, that's why java -jar .... works. If you copy a java installation (the jre or the jdk folder) however, then the PATH will not be automatically updated. Or if you reinstall windows, and do not format the drive where java is installed (doesn't have to be put in Program Files), then again, PATH won't be updated, you have to do it manually.

For me personally it is a regular occurrence, since I have several JDKs installed at any one time, due to the requirements of the various projects i'm working on. I rarely install java from the installer/rpm .

Tesseraction
Apr 5, 2009

Interesting, there's a java.exe in System32 but Cygwin can't find it at all, which I only noticed when trying to do a cmp to see if it was different from the one installed in Program Files. Copying the sys32 file elsewhere allowed me to compare it as exactly identical, which suggests it's a symlink/junction. Anyway enough of that.

My point was really one of "shouldn't the easiest way just be calling 'java -jar'" with the idea being that if you get an error code then your .bat or whatever suggests getting Java? I guess it could be confusing if your jar returns failure exit codes too, so just compare. Having weirdly installed JREs muddies the waters a bit but then I don't know if this jar is aimed at technically competent people or the thoroughly green.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
I'm baack!

I have a JComboBox where I store all sorts of strings, amond them "new string", which, when the user chooses it, brings up a dialog asking to enter the string. However, even if the dialog blocks all the other interaction with the parent window, the dropdown from the combobox still behaves as if it's active (although I obviously don't get any events from it). This is a cosmetic thing but a bit annoying and distracting. How should I go about solving it?

Hint: it could do something with the possible fact that the dropdown list is a new window. I guess there's no other choice but to write a custom component?

supermikhail fucked around with this message at 18:05 on Sep 16, 2013

Adbot
ADBOT LOVES YOU

Volguus
Mar 3, 2009

supermikhail posted:

I'm baack!

I have a JComboBox where I store all sorts of strings, amond them "new string", which, when the user chooses it, brings up a dialog asking to enter the string. However, even if the dialog blocks all the other interaction with the parent window, the dropdown from the combobox still behaves as if it's active (although I obviously don't get any events from it). This is a cosmetic thing but a bit annoying and distracting. How should I go about solving it?

Hint: it could do something with the possible fact that the dropdown list is a new window. I guess there's no other choice but to write a custom component?

How I would do it, is I would allow the combobox to close before opening my dialog.
So, let's say you have your listener: itemStateChanged(...) (or something like that). In that method I would do an invokeLater, something like:
code:
myComboBox.itemStateChanged(new ItemListener(){
	@Override
    public void itemStateChanged(ItemEvent event) {
       if (event.getStateChange() == ItemEvent.SELECTED) {
          Object item = event.getItem();
          if(item.equals("New String")) { //or however I choose to determine that this is the item i want. Could be from model, to return null, etc.
              SwingUtilities.invokeLater(new Runnable(){
			public void run() {
				//show my dialog.
			}
		});
	  }
       }
});
Of course, your code should be prettier than this, but this is the gist of it.

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