Jon Swanson

Ranch Hand
+ Follow
since Oct 10, 2011
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Jon Swanson

I thought about that. It sounds like the simplest solution. If I hide the header, I'm not sure anyone would know the difference.

I was playing around with overriding getText and setText in a custom JTextField. If get always returns the value in default units, I can get the value (which will be in default units), change the units as a method of the extended text field and then set the units passing in the default units I just retrieved. A little convoluted, but the current enum just includes the scale between any other unit and the default, and I would prefer not to change that.

I need to try the 1x1 table instead.
8 months ago
What you are describing is similar to what is being done. Currently, everything is done with a table. Each measurement is in a column. Each column has a renderer attached and what is displayed depends on the value of an enum used to describe the possible units. The GUI is interactive, the user can change the units whenever they want and the table will update showing the new units.

A better example might be a table showing the results of measurements made at various times. The first column is a time, the other columns are the results of different tests done at that time.

The new request is to add a text field (or several) that prompt for a time, but only indirectly related to the measurements. For example, an entry for failure time. That requires entering just a time. The units should be consistent with the table. If the user changes units in the table, the text field must also update to show the failure time in the new units.

It is just a few lines of code to make the renderer for the table. The table model has all the values stored in default units, which makes showing converted units and getting data in the default units for calculations very easy.  I got stuck trying to assign a JTextField renderer and that makes me wonder how one would do it and whether there is a better approach.
8 months ago
I am maintaining what is now pretty old code. One aspect is there are a lot of tables that have columns whose values change depending on the setting of a variable for units (e.g. switching from inches to feet to meters). The underlying model maintains the value in the default units, but the view shows the user specified units. This is very handy, as all the calculations done can assume default units that are returned from the underlying table model.

Now of course, the same functionality is being requested for some JTextFields (rather than tables). I was hoping to use the same sort of design, but I am not seeing a way to set the renderer (or cell editor) for a plain JTextField.

Here is an example of what is done for the table column.


I was hoping to set a renderer for the JTextField.

Should I just have a block of of code when I open the dialog to set units using setText() to put in the converted value and then when I close the dialog read the text and convert it back to the default units? In other words, there is no reason to get too fancy?

I suppose I could extend JTextField and override setText and getText.

Is there a better way to handle this sort of case (maintain something in default units and displaying it in some alternate units) for JTextField?
8 months ago
Carey,

Maybe. But I don't have the go ahead to rewrite the existing overloaded methods. These methods are not simple, they involve thousands of lines of code (starting in the class containing the overloaded methods). At least the additional overloaded method will be in the same class with the other methods of the same name and will do nothing more than call the "expected" method after casting the enum to the correct type based on the enum itself.

All the enums are defined in a single static class. Not too many places to look.

And this way none of the code that assumed that one can just pass in an enum for a specific method and get the expected result will break.
2 years ago
Mike,

Sorry. In what I am compiling I tried



and



I could assign



as an element of either array, and in neither case could I use the overloaded methods.

However, you are right, that I could used these overloaded methods



the first method would run for the Enum[] array and the second method would run for the Object[] array.

In either case, it still seems like I need to have a bunch of if (e instanceof) statements and then do explicit casts to the type of enum. That works whether I assign the enums to Object[] or Enum[].
2 years ago
What it sees at compile time and runtime are different.

I added additional overloaded functions to see what I would get.



With this code-



It prints "Weight"

With this code-



It prints "Object"

That is not to say that I cannot have this method-



That prints "WEIGHT" when I open( w[0] ) since it is resolved at runtime

I can also do this-



and it prints "WEIGHT" when I open w[0].

The latter examples are why I have been pounding my head against the idea of getting the overloaded methods to work.

Sorry for the typos- been doing jury duty so have to respond before or after.
2 years ago
Yes, a typo-



Yes, initializing the array when it is created is cleaner. I believe in the actual code the array is used more than once, though.

In any case, the last line doesn't work. The open method is overloaded, but gets the type Object rather than Color or Shape.
2 years ago
Mike,

Thanks for the detailed and thoughtful answer.  The situation I have is slightly different, but very similar to what you discussed.

I have a class with a set of overloaded methods.



That had been working fine, in the sense that different portions of the code needed similar function, but did not overlap.



That sort of operation is handled without a problem. Where I get the problem is with a new requirement for old code.



I can't use overloading because the open method sees the type passed from the Enum array as Object in every case,



Thanks for that, this compiles. I was trying to trick Java into returning something at runtime that would actually be seen as Color or Shape. Nope, still seen as Object.

So I was thinking I would be stuck with creating a method-

static void open(Object anEnum) {
  if (anEnum instanceof Color) open((Color) anEnum);
  if (anEnum instanceof Shape) open((Shape) anEnum);
}

which is a kludge to keep from making more extensive changes to the code, and works, but seems to go against the reason for overloading in the first place.

I like the MAP idea. I am a little concerned it will run afoul of the same problems I have been having. The methods are in a class focused on carrying out a specific big messy calculation. Exactly how the calculation is carried out depends on which exact "class" of problem is being worked and the exact kind of class. For better or worse, long ago there was one class of problem and an enum created for the kind of "class." Much later, almost the same methods were needed in another class of problem and a second enum was created with its kinds of "class." The top level functions that did the messy bits were overloaded. All was fine until now when there was a request to send the enums in as an array and handle multiple messy bits at  once (as a change to a class that did everything with arrays but until now, did nothing related to the messy bits).


Thanks to everyone. I think the advice will be really helpful going forward to avoid the problem I have fallen into. In the meantime, I am feeling a little better about what I need to do to patch this code to keep it going a bit longer (hopefully some refactoring will be scheduled in at some point).
2 years ago
Follow-up using valueOf



This encapsulates the problem- by placing  the enum in the array, its type is not known at compile time and valueOf() fails to compile. Presumably for the same reason the overloaded methods fail.

method valueOf in class Enum<E> cannot be applied to given types;
     unitPrint( myEnums[ 1 ].valueOf( myEnums[ 1 ].toString() ) );
                            ^
 required: Class<T>,String
 found: String
 reason: cannot infer type-variable(s) T
   (actual and formal argument lists differ in length)
 where T,E are type-variables:
   T extends Enum<T> declared in method <T>valueOf(Class<T>,String)
   E extends Enum<E> declared in class Enum

If I switch to an array of Objects-

error: cannot find symbol
     unitPrint( myEnums[ 1 ].valueOf( myEnums[ 1 ].toString() ) );
                            ^
 symbol:   method valueOf(String)
 location: class Object
1 error

I have not found a way to pass an enum into an overloaded method when the enum comes from an array containing different types of enums except by explicitly casting the enum in the method call, which defeats the purpose of having an overloaded method.
2 years ago
I think the discussion digressed a bit. I have code that uses overloaded functions which take different enum classes that (in part) determine what the method returns.

I have another class expecting arrays to assign instances to rows.

If try to use a generic Enum[] then the methods see the class Object. In the past the methods were only used with specific enums and there is a lot of existing code making use of them.

The array is a new request. I'll try valueOf(), but my function, since it requires implementing an interface, also results in the overloaded functions seeing a type of Object for the enum.

I can explicitly cast the enums from the array, but that removes the generic nature of using an array and deciding what to do at run time. I can also use something like instanceof and have a big if else block. I was hoping to find something cleaner.
2 years ago
I think you have hit on my primary problem.

There is a class, which I cannot modify, that contains methods that are overloaded. The behavior of the method depends on the enum that is passed to the method. I cannot move these methods into the enum, they rely on a lot of data structures and other methods of the class they are currently in.

I tried writing an interface that returned the enum. That approach did not work.








Still gets Object as the class of the enum

I would have to call the external method from inside the enum and pass it the value of the enum (with  the appropriate type) and I do not know how to do that.


2 years ago
Under normal circumstances, I can answer this question myself. My problem is I am updating existing code and am limited in what changes I can make. The two key points are-

I have a class with several overloaded methods that take an enum as an argument. The current code has lines like-


All fine in the current code.

The code has another class for building part of the interface and it takes arrays, one per column. The array size is the number of rows. An example is passing in entry components.



After (many) years a new requirement is to associate an enum with each row. That would be fine if we were talking different values of the same enum, but different rows have different enums associated with them. The need is something like this.



I understand that I am dealing with what Java knows at compile time versus run time, i.e. at compile time the array elements are just Object. These statements work-


presumably because the class is resolved at runtime in these statements.

That allows me to write a big if else clause covering all possible enums (and have to add to it whenever a new enum is defined). I was hoping to find a more elegant solution (within the constraint I need to call the existing overloaded methods). I have more flexibility on passing in the array- just that the association to the other arrays used in the interface is by array index.

I thought I  would ask for comments before committing to something that might be pretty kludgy.
2 years ago
The answer by Guillaume Polet in this link got me what I needed.

JFileChooser Text Field

It's a bit brute force (looking through every object in JFileChooser looking for a JTextField), but it works.

If anyone has a more elegant approach, I would appreciate hearing it.
3 years ago
I have a menu that has two entries: Save as PDF and Save as CSV. I use the same instance of a JFileChooser for both and change the FileNameExtension filter depending on which option is picked. I do this since users generally store these files in the same directory and often under the same or similar base names. So it helpful to them that the information is remembered even if they switch from PDF to CSV.

The ActionListener looks something like this-



The one complaint I have from users is that if the dialog is used to show "test.pdf" and then brought up in CSV mode, the file name is listed as "test.pdf."

I tried to work around this by adding the following method-


Then I put this around the call to the dialog



The setLastSelection is nothing special, it just saves what I get by calling getSelected file method of JFileChooser and then getLastSelection (used above) provides te saved value.



This only partially works. If I enter a File Name in the showSaveDialog and hit Cancel, getSelectedFile() returns null, but when I bring showSaveDialog back up- the file name I typed is there! I could null  it out, but I would prefer not to have a different behavior for this file chooser versus the default behavior of JFileChooser.

If I type "foo.pdf" in the showSaveDialog and then Save,  getSelectedFile() returns "foo.pdf" and I can run my updateLastSelection() to convert it to "foo.csv" if I bring up the showSaveDialog with the file filter changed to CSV.

If I type "foo.pdf" in the showSaveDialog and then Cancel, getSelectedFile() returns null, yet if I bring up the showSaveDialog with the file filter changed to CSV, the dialog has "foo.pdf" as the File Name.

My assumption is that getSelectedFile() is the wrong method to call to determine what showSaveDialog is going to display in the File Name field.

I have not been able to find any mention of what I actually need to query to find that value.

Has anyone tried this or now how to query the showSaveDialog for the value of the File Name: text field?

Thanks.

3 years ago
I could use some help getting started on this problem.

I have a Java program that currently you click a desktop icon and it runs. There is a new requirement that first a login prompt must be displayed and the user authenticated before the program starts.

The program is run on a standalone PC with the requirement that no connections over the internet should be made.

Why logging into the PC is not sufficient is beyond me- I have to implement the requirement, I didn't request it.

I believe that for secure authentication, only an admin should be allowed to create usernames and passwords.

My initial thought was to buy a third party program that started a DLL authentication service on start-up and had a tool to administers passwords.

Then the only Java would be to connect to the DLL and I think I can figure that out.

However, I've been Googling for a vendor of such a program and have come up short. Does anyone have a suggestion?

If that is not a good way to go, could I get some tips on how to build my own? I'm thinking a database owned by admin. I'm just not sure how an average user would query it and whether that is considered sufficient security. Presumably I would store only encrypted usernames and passwords and compare that. I've never had the requirement to lock down a program before.
5 years ago