Skip to Main Content

Java Development Tools

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Client to database connection

870731Jun 22 2011 — edited Nov 10 2011
This should be easy. Machine 1 (Windows 7) is running the database. Machine 2 (also Windows 7) is ONLY running SQL Developer. Where do I put the tnsnames.ora file and what else may I be forgetting on the client? Can't connect - obviously I"m missing some of the network stuff but I'm not sure what and do not want a full Oracle install on the little bitty Machine 2.

Comments

Kayaman
RichF wrote:
1) store each CND in its own plain text file with file names ending in common extension, such as ".cnd". At run time, hunt for .cnd files in current directory and build a GUI selection list dynamically. This would likely be my approach in other languages, and would save space in the jar file. (One byte per character instead of two.) But I do not even know if an applet can read files in its own .jar. If it can, they would be in the current directory, right?
No...they would be in the jar file. You would use getResourceAsStream() to access them.
2) store each CND in its own class. Is there a way to just drop classes into a project, and have the java parent automatically recognize what CND classes there are and adjust the GUI to support it/them?
It's possible, but I wouldn't suggest it here, because you're not actually adding functionality but data. The classes are otherwise identical, aren't they?
3) store all CNDs in one class, as separate 2-d arrays. It could end up as a huge class (the current class, with just one dictionary, is 78k in size), but might be the simplest to implement.
That would just be storing data in a class. Not exactly a good choice design-wise.
Which path would you take? Is there a better way that I haven't thought of?
I'd go with number 1. You can add additional mappers easily by just adding files.
JoachimSauer
RichF wrote:
1) store each CND in its own plain text file with file names ending in common extension, such as ".cnd".
I'd suggest a .properties file for that.
This would likely be my approach in other languages, and would save space in the jar file. (One byte per character instead of two.)
Actually, no it wouldn't. String constants in .class files are stored in UTF-8, not UTF-16! Only at runtime are all characters UTF-16.
But I do not even know if an applet can read files in its own .jar. If it can, they would be in the current directory, right?
Yes, an applet may load files from its own .jar using getClass().getResource(). It can't, however, list all entries in a given "directory" in the .jar
2) store each CND in its own class. Is there a way to just drop classes into a project, and have the java parent automatically recognize what CND classes there are and adjust the GUI to support it/them?
You could use the ServiceLoader mechanism for this. You'd need a list of those classes in a text file (details in the JavaDoc).
Which path would you take? Is there a better way that I haven't thought of?
Personally I'd chose step 1 (or a variation thereof), since I don't see a reason to store that data as executable code. To overcome the "list files" problems, you could either a.) list all entries in a dedicated file or b.) have a predictable naming scheme (e.g. "cnd1.properties", "cnd2.properties", ...) and just try to load as many as possible until you fail to find one.
YoungWinston
Joachim Sauer wrote:
RichF wrote:
1) store each CND in its own plain text file with file names ending in common extension, such as ".cnd".
I'd suggest a .properties file for that.
I think I'd probably advise a combo of yours and Kayaman's suggestions: use a properties file and put it in the jar. Makes things ever so much easier for distribution. An alternative, of course, is XML.

@OP:
1. If you're worried about size, you could always zip the dictionary file before you store/ship it (text usually compresses anywhere up to 10:1); but I'd definitely leave it until you have a need for it.
2. I suspect that what would be useful for users of your colours would be to have some wrapper that bangs them all into a HashMap<String, Color>, where the String is the name of the colour; and offer some "fuzzy logic" methods to help people who may not know the exact colour name (eg, "give me all the browns").

Winston

PS: If you do think you might need to zip at some point, I'd definitely provide custom load() and unload() (or Stream) methods for your dictionary; even if they just deal with plain text at the moment.

Edited by: YoungWinston on Nov 11, 2010 1:38 PM
JoachimSauer
YoungWinston wrote:
Joachim Sauer wrote:
RichF wrote:
1) store each CND in its own plain text file with file names ending in common extension, such as ".cnd".
I'd suggest a .properties file for that.
I think I'd probably advise a combo of yours and Kayaman's suggestions: use a properties file and put it in the jar.
That's actually what I tried to advice, but I realize that I didn't make it explicit, that the .properties files could/should be placed in the .jar file.
RichF
Thanks, everyone. I'll likely go with the .properties files within the .jar.

One other possibility occurs to me, though. The vast majority of visitors won't bother with any CND except the default one. Could I package the default within the .jar, and then download any others from my server upon request? I'm thinking:

1) default CND in the .jar and auto-configured for use by app
2) .properties file within the jar listing other CNDs at the server
3) visitor selects another dictionary, it is downloaded and configured as the active CND

Would this be a good idea and relatively easy to implement?
Kayaman
RichF wrote:
One other possibility occurs to me, though. The vast majority of visitors won't bother with any CND except the default one. Could I package the default within the .jar, and then download any others from my server upon request? I'm thinking:

1) default CND in the .jar and auto-configured for use by app
Better idea, all the CNDs in the .jar and the default one being used by...well, default.
2) .properties file within the jar listing other CNDs at the server
Properties file within the jar, listing other CNDs in the Jar.
3) visitor selects another dictionary, it is downloaded and configured as the active CND
Visitor selects another dictionary, it's already downloaded with the Jar and just set it as the default.
Would this be a good idea and relatively easy to implement?
Yes and yes.
RichF
Kayaman wrote:
Would this be a good idea and relatively easy to implement?
Yes and yes.
Kayaman, just to be clear -- you are saying having the extra CNDs on the server would be a good idea and easy to implement. But having them already in the .jar, even though most users won't access them, would be a better idea, right?
RichF
I'm getting ready to implement. Currently, the single CND is stored as a 2-d array with 1576 entries within a [url http://r0k.us/source/NTC.java]class.
    public static final String names[][] = {
	{"000000", "Black"},
	{"000080", "Navy Blue"},
	{"0000C8", "Dark Blue"},
	{"0000FF", "Blue"},
        ...
	{"FFFF99", "Pale Canary"},
	{"FFFFB4", "Portafino"},
	{"FFFFF0", "Ivory"},
	{"FFFFFF", "White"}
    };
Fortunately, no hex values are repeated, nor will be repeated in other CNDs. To convert this to a properties file, I believe it would look like:
CND.Name = "Hodge Podge"
CND.Count = 1567
000000 = "Black"
000080 = "Navy Blue"
0000C8 = "Dark Blue"
0000FF = "Blue"
...
FFFF99 = "Pale Canary"
FFFFB4 = "Portafino"
FFFFF0 = "Ivory"
FFFFFF = "White"
Does that look correct? As I understand it, the Properties interface would not read them in any particular order.
Roedy Green [url http://mindprod.com/jgloss/properties.htmlwrites:}
Since Properties are Hashtables, they scramble the order of the elements. If you want to preserve order, and don’t need key lookup, you can parse the file yourself with a StreamTokenizer and put it in an array. Do you-all agree this would be the best approach to read them in? Regardless of method, I want them to end back up into a 2-d string array, sorted by hex value. That is the reason for the CND.Count key.

I guess the other alternative is using the properties interface to read them into a temporary array, and sort it into the final array. I should be able to use propertyNames() to get all the keys, store those in the temporary 1-d array, sort it, then loop getProperty(temp[index]) to fill the final 2-d array. Once the 2-d array is full, I would free the Properties object by setting it to null.

Hopefully I'm not sounding needy. This stuff is new to me, and I'd like to avoid walking down a blind alley full of gotchas and structural Rube Goldbergs. ;)
Kayaman
RichF wrote:
But having them already in the .jar, even though most users won't access them, would be a better idea, right?
Yes. Getting them separately from a server would be justified if the files were several megabytes in size. But since it's just text and compresses automatically within the jar, there's no reason not to include them all in the same jar even if the user might never switch to another CND.
Kayaman
>
Fortunately, no hex values are repeated, nor will be repeated in other CNDs. To convert this to a properties file, I believe it would look like:
CND.Name = "Hodge Podge"
CND.Count = 1567
000000 = "Black"
000080 = "Navy Blue"
0000C8 = "Dark Blue"
0000FF = "Blue"
...
FFFF99 = "Pale Canary"
FFFFB4 = "Portafino"
FFFFF0 = "Ivory"
FFFFFF = "White"
Does that look correct?
Looks about right, except you don't need the quotes around your text.
I guess the other alternative is using the properties interface to read them into a temporary array, and sort it into the final array.
You don't need a temporary array. You can read all the contents of the properties (it extends Hashtable so there should be some form of getEntries() method to get key/value pairs) in a 2D array and then sort it afterwards.
I would free the Properties object by setting it to null.
Setting references to null is rarely needed explicitly. I'd expect the Properties to be a local variable that you create when the user is wanting to change the CND, which will fall out of scope by itself.
>
Hopefully I'm not sounding needy. This stuff is new to me, and I'd like to avoid walking down a blind alley full of gotchas and structural Rube Goldbergs. ;)
No worries.
RichF
Kayaman, thanks again.
You don't need a temporary array. You can read all the contents of the properties (it extends Hashtable so there should be some form of getEntries() method to get key/value pairs) in a 2D array and then sort it afterwards.
Between my last post and yours, I implemented the properties stuff. It was quite straight-forward. :) It does read into a temporary ArrayList, obviating the need for a CND.count property. This also provided the infrastructure for filtering-out non-hex properties Here:
public class NTC
{
    public final static String defaultCND = new String("cnd_ntc.properties");
    private static String cnd_name;
    ...
    // encapsulate opening of a properties file.  returns null if problem
    public static Properties loadProperties(String file)
    {
	String me = new String("loadProperties(): ");
	if (file == null) {
	    System.out.println(me + "null filename");
	    return(null);
	}

	Properties p = new Properties();
	FileInputStream fis;
	try {
	    fis = new FileInputStream(file);
	} catch (FileNotFoundException e) {
	    System.out.println(me + "cannot open " + file);
	    return(null);
	}
	try {
	    p.load(fis);
	} catch (IOException e) {
	    System.out.println(me + "cannot load " + file);
	    try {
		fis.close();
	    } catch (IOException ioe) { /* what the heck you gonna do? */ }
	    return(null);
	}
	try {
	    fis.close();
	} catch (IOException e) { /* what the heck you gonna do? */ }

	return(p);
    }

    // read in a properties file containing a color name dictionary (CND)
    public static boolean readCND(String cnd)
    {
	if (cnd == null)  cnd = defaultCND;
	Properties props = loadProperties(cnd);
	if (props == null)  return(false);

	ArrayList sorter = new ArrayList(1000);
	String key;
	Enumeration hexKeys = props.propertyNames();
	while (hexKeys.hasMoreElements()) {
	    key = (String)hexKeys.nextElement();
	    if (isHex(key))
		if (key.length() == 6)  sorter.add(key);
	}
	int count = sorter.size();
	if (count < 1) {
	    System.out.println("readCND(): no hex values in " + cnd);
	    return(false);
	}

	// keys were in hashtable order.  sort them
	Collections.sort(sorter);
	names = new String[count][2];

	String name;
	for (int i = 0; i < count; i++) {
	    name = props.getProperty((String)sorter.get(i), "no name");
	    names[0] = (String)sorter.get(i);
names[i][1] = name;
}

cnd_name = props.getProperty("CND.name", "unknown");
return (true);
}

public static String names[][] = {
{"000000", "Black"},
{"0000FF", "Blue"},
{"00FF00", "Green"},
{"00FFFF", "Cyan"},
{"FF0000", "Red"},
{"FF00FF", "Magenta"},
{"FFFF00", "Yellow"},
{"FFFFFF", "White"}
};
}

I did not factor out the loadProperties() part until this morning, when I realized the outer applet will need the same exact code to load the .properties file containing the list of CND .properties files. I also kept a bare-bones dictionary hard-coded in the event even the default CND could not be loaded.

The one thing I lost is that the names[][] array is no longer final. External classes can modify it. I know I could make it private and provide access methods, but that would force changes to code already using the class.
YoungWinston
RichF wrote:
The one thing I lost is that the names[][] array is no longer final. External classes can modify it. I know I could make it private and provide access methods, but that would force changes to code already using the class.
Seems to me that rather than keeping everything as strings, you might want to think about a NamedColor class that extends java.awt.Color, and encapsulates your dictionary entries as instances.
That has several advantages:
1. They're ready-made for Java Collections or Maps.
2. You can provide Comparators to sort them any way you like.
3. You could provide methods such as 'asHSB()' which return the colour as an HSB value (ordering by Hue, for example, might provide useful visual groupings).

Winston
RichF
Great suggestions, Winston.
several advantages:
1. They're ready-made for Java Collections or Maps.
2. You can provide Comparators to sort them any way you like.
NTC.java is just one part of a larger project. By itself, it is a port of ntc.js by Chirag Mehta, as seen on his [url http://chir.ag/projects/name-that-color/]Name that Color page. My own [url http://r0k.us/source/ColorName.java]ColorName.java expands the scope of NTC in the manner you suggest. While I don't actually extend the Color class, it might be worthwhile to do.
3. You could provide methods such as 'asHSB()' which return the colour as an HSB value (ordering by Hue, for example, might provide useful visual groupings).
As well as alphabetically, or by hex, or by luminance, ... :) See:

* http://r0k.us/graphics/SIHwheel.html
YoungWinston
RichF wrote:
...While I don't actually extend the Color class, it might be worthwhile to do.
The main advantage is that a lot of that stuff (such as HSB conversion) is already written for Color. You could also pass a NamedColor around anywhere that expects a Color.

Lots of ways to skin a cat :-).

Winston
RichF
The main advantage is that a lot of that stuff (such as HSB conversion) is already written for Color. You could also pass a NamedColor around anywhere that expects a Color.
That was easy enough. Instead of having its own instance variable color, it is one:
public class ColorName extends Color implements Comparable  // <ColorName>
{
    private String	name, hex;
    private int		hsi, lumi, luma, avg, h_rgb, h_lab, h_hsb;
    // private Color      color;
    static private List /* <ColorName> */ colorNames;
    ...
    public ColorName(String name, String hex)
    {
	// I'm a Color now!  (needs to be first statement in constructor)
	super(Integer.valueOf(hex.substring(0,2), 16).intValue(),
	      Integer.valueOf(hex.substring(2,4), 16).intValue(),
	      Integer.valueOf(hex.substring(4,6), 16).intValue());
        ...
    }
}
neat! My one slight concern is the likely large colorNames List. But since it is static and there is only one instance, I shouldn't worry about it. BTW, I think NamedColor would have been a better name for this class, but this is already part of working code, and at least one other person is using it. Also, I'm targeting Java 1.4, which is why the <ColorName> compiler hints are commented out.
YoungWinston
RichF wrote:
BTW, I think NamedColor would have been a better name for this class, but this is already part of working code, and at least one other person is using it. Also, I'm targeting Java 1.4, which is why the <ColorName> compiler hints are commented out.
Well, another wrinkle to think about is to create a NamedColor class that uses all the nice 1.6 goodies, and have your ColorName class wrap (or extend) it. You could then deprecate ColorName reasonably in the future.

PS: I'd also make ColorName final.

Winston
RichF
<sigh> I thought I was ready to deploy. Nope. It turns out that the methodology used to read a properties file from a file system is not the same as from a jar file. Here is my property reader again, with the working file system calls commented out:
    // encapsulate opening of a properties file.  returns null if problem
    public static Properties loadProperties(String file)
    {
	String me = new String("loadProperties(): ");
	if (file == null) {
	    System.out.println(me + "null filename");
	    return(null);
	}

	Properties p = new Properties();
//	FileInputStream fis;
	InputStream fis;
	try {
//	    fis = new FileInputStream(file);
	    fis = NTC.class.getResourceAsStream("cnd_ntc.properties");
	} catch (FileNotFoundException e) {
	    System.out.println(me + "cannot open " + file);
	    return(null);
	}
	try {
	    p.load(fis);
	} catch (IOException e) {
	    System.out.println(me + "cannot load " + file);
	    try {
		fis.close();
	    } catch (IOException e2) { /* what the heck you gonna do? */ }
	    return(null);
	}
	try {
	    fis.close();
	} catch (IOException e) { /* what the heck you gonna do? */ }

	return(p);
    }

--- compilation error on above ---
D:\progming\java\ntc>javac -target 1.4 -source 1.4 NTC.java
NTC.java:245: exception java.io.FileNotFoundException is never thrown in body of
 corresponding try statement
        } catch (FileNotFoundException e) {
          ^
1 error
I stopped there. What I really want is to be able to read properties as either a program from the file system or as an applet from within the jar file. Up to now, I never had to even contemplate having two versions, program and applet. Hopefully there is a workaround, or an actual supported structure.
RichF
marked as unanswered because program does not work as an applet within a jar file
Kayaman
Answer
If you're already using getResource() and you don't intend to randomly place your CND files around the filesystem, there's no reason to mix FileInputStreams there.

Class.getResourceAsStream() is the way to support different kinds of loadings. It even supports having your program as a jar file or an unpacked jar file. You just left the unnecessary catch block there that you need to remove.
Marked as Answer by RichF · Sep 27 2020
RichF
You just left the unnecessary catch block there that you need to remove.
Yes. I just figured that an hour ago. Talk about premature whining ...

I've spent the last hour "going live". Take a peek. :)

* http://r0k.us/graphics/SIHwheel.html

The menu is brand new as well, with the "color name dictionaries" presented as "Color Lists".

You know you have an actual project when it takes an hour to get all your source and resource files ready for release.

(thread once again marked as answered)
walterln
RichF wrote:
You know you have an actual project when it takes an hour to get all your source and resource files ready for release.
No, an actual project would use a build system :). For Java Ant and Maven are popular but there are lots more.
1 - 21
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Dec 8 2011
Added on Jun 22 2011
2 comments
108 views