OK, I've been reading a lot online and I think I can't do this, but I'm really hoping someone has a clever workaround. What I have is a bunch of classes with Color attributes. I'm also storing the red, green, blue, alpha values as integer attributes in those classes because I am using them a lot. What I am doing now is this:

class someclass
{
     Color color;
     int red;
     int green;
     int blue;
     int alpha;

     public void setcolor (Color newcolor)
     {
          red = newcolor.getRed ();
          green = newcolor.getGreen ();
          blue = newcolor.getBlue ();
          alpha = newcolor.getAlpha ();
          color = new Color (red, green, blue, alpha);
     }
}

I have a whole bunch of classes and a whole bunch of colors and what I'd like to do is have a single static function in some class that any of the other classes could call and pass the relevant variables, like you can in C++, like this:

public class aclass
{
    public static Color CopyAttributes (Color newcolor, int red, int green, int blue, int alpha)
    {
          red = newcolor.getRed ();
          green = newcolor.getGreen ();
          blue = newcolor.getBlue ();
          alpha = newcolor.getAlpha ();
          return new Color (red, green, blue, alpha);     
   }
}

A function call from someclass could be:

color = aclass.CopyAttributes (newcolor, red, green, blue, alpha);

This won't work because you can't change red, green, blue, alpha inside the CopyAttributes function and have them change the calling class's attributes since int is a primitive type. However, that is what I WANT to do, so I'm looking for a workaround. Again, there are a whole bunch of classes and a whole bunch of Color variables and some of these color variables and their int counterparts aren't class variables, so I am constantly typing four lines of code like:

redval = acolor.getRed ();
greenval = acolor.getGreen ();
blueval = acolor.getBlue ();
alphaval = acolor.getAlpha ();

for a variety of variables. Am I simply stuck typing this all over the place or doing a big redesign or is there some way? And does the fact that I even WANT to do this mean that I am missing the whole point of Java and need to redesign? Thanks for any input.

Recommended Answers

All 10 Replies

I assume that these classes are all of the same type (or at least all extend the same type)? In that case simply pass the object itself along with the method call;

Instead of

public class aclass
{
    public static Color CopyAttributes (Color newcolor, int red, int green, int blue, int alpha)
    {
          red = newcolor.getRed ();
          green = newcolor.getGreen ();
          blue = newcolor.getBlue ();
          alpha = newcolor.getAlpha ();
          return new Color (red, green, blue, alpha);     
   }
}

do

public class aclass
{
    public static Color CopyAttributes (someclass bclass)
    {
          bclass.setRed(newcolor.getRed ());
          bclass.setGreen(newcolor.getGreen ());
          bclass.setBlue(newcolor.getBlue ());
          bclass.setAlpha(newcolor.getAlpha ());
          return new Color (red, green, blue, alpha);     
   }
}

Or define an interface with those setmethods and have the classes implement that interface, and then make the interface type the argument.

commented: Helpful approach. I hadn't though of passing a class or interface. +10

In Java, everything is passed by value; in case of primitive types, a copy of the value is created and then passed as an argument to the method invoked.

private void mutateItNot(int v) {
  v = 10; // no effect on the original integer value
          // this `v' is just a copy of the `int' being passed
}

In case of references, a copy of the reference variable is created and then passed as an argument to the invoked method. Think of this as a remote control used to regulate the functioning of a T.V. When a reference type is passed to the method, a copy of it i.e. a copy of the remote is created which in the end is used to manipulate the same T.V. You can regulate the T.V. with this cloned remote in the same way as you would do with the original but destroying this remote has no effect on the original.

private void mutateItNot(SomeThing s) {
  // use the reference to manipulate the object it points to
  // [assuming we are not talking about immutable classes here]
  s.setField(someValue); 
  s = null; // the clone is now made to point to nothing
            // with absolutely no effect on the original
}

> I'm also storing the red, green, blue, alpha values as integer
> attributes in those classes because I am using them a lot

Why? Ease of use? Performance? This is no sane reason to duplicate data; your class instance along with the Color class instance now maintains the state of the Color object. Now your class bears the burden of keeping the internal state of the Color object and its own synchronized. Don't optimize unless required.

IMO, create a utility class which holds the utility methods used across your project and those which don't specifically form the responsibility of other classes.

> public static Color CopyAttributes (someclass bclass) C# bites? ;-)

commented: Earlier had created a mess answering a similar question, this was very well put. +4
commented: Good explanation +10

> public static Color CopyAttributes (someclass bclass) C# bites? ;-)

Whoops, forgot to include the Color argument. Oh well, he should have been able to figure that one out himself (hopefully).

In any case, I agree with you. This duplication of data is stupid, and probably only done to avoid "having" to do getRed and the like, all the time. But, sometimes, I just don't feel like taking the effort to try talking them out of it. It is usually like "talking to a brick wall" and only half as effective.

;-)

I try not to be a brick wall, but sometimes I fail :) I am most brick-wallish when I try to make Java behave like C++ and pass by reference. At least this time I'm not because the advice makes sense and I'm going to take it.

I was storing the four individual components of the colors because I'm doing calculations with them like making a "sunset" effect and slowly melding two colors together (i.e. if the red components of the two colors are 100 and 200, I have a loop where I slowly change the colors). I figured constantly calling getRed (), getGreen () over and over again wasted time, so masijade, you are correct, that's what I was trying to avoid, but I guess there's no reason to avoid it. I was under the impression (and I now have no idea why I believed that) that calling getRed () really slowed the program down and that there was a lot of overhead with it, but that's not true, is it?

EDIT: I was just typing out an example of how I was using it to show you and then I looked at it more and more and there was no reason to call getRed (), etc. as many times as I did anyway. So I guess I'll just store the Color itself and not the components. That makes more sense. Thanks guys! sos, I like the TV remote analogy.

commented: sorry. But definately happy you didn't (or, at least , so it seems) take offense. ;-) +11

> But, sometimes, I just don't feel like taking the effort to try
> talking them out of it.

Yes, even I get that sort of feeling but seeing that VernonDozier is a Daniweb regular, I took my chances. ;-)

> that calling getRed () really slowed the program down and that
> there was a lot of overhead with it, but that's not true, is it?

No, it isn't, really. If you are still concerned about calling the same method again and again, instead of having your class maintain the state or cache the `red' value, shove the responsibility to the invoked method instead.

private void mutate() {
  int red = color.getRed();
  // some complicated, multi step calculation using `red'
  color.setRed(red);
}

And talking of terms like overhead for a program without any concrete profiling data whatsoever is wrong IMO.

No, it isn't, really. If you are still concerned about calling the same method again and again, instead of having your class maintain the state or cache the `red' value, shove the responsibility to the invoked method instead.

private void mutate() {
  int red = color.getRed();
  // some complicated, multi step calculation using `red'
  color.setRed(red);
}

And talking of terms like overhead for a program without any concrete profiling data whatsoever is wrong IMO.

++ to this.
Premature optimization in the absence of profiling data is a recipe for all kinds of trouble and makes baby Jesus cry.
The overhead of that method call vs the variable is negligible unless it's in a long loop and even then compiler will probably identify it as a loop invariant and use a local variable for it anyway. If not then you can always make one yourself just like s.o.s. showed.

Vernon, no disrespect intended there. I didn't pay any attention to who it was that was posting. Just feeling a little pissy, I guess. It happens. Sorry.

It's cool, masijade, no worries, and I appreciate the advice you gave me.

Point taken on the pitfalls of assuming without data. We all know what they say about people who "assume". I was definitely assuming.

I have another optimization from the same program, a fairly minor one, but one that I think makes sense this time and does optimize, if only a little. This is a GUI program that draws shapes to a JPanel using the drawOval , drawPolygon functions, etc. from the Graphics class, all of which use integers rather then doubles for arguments. I'm doing a lot of motion and resizing and ratios in my calculations and so I am storing the coordinates and sizes as doubles rather than integers to avoid compounding round-off errors. Most of the time, the individual shapes don't change, so I have defined integer variables too for the purpose of drawing. In the example of square:

double x, y, length;
int intX, intY, intLength;

So when x, y, or length change (rarely), I then typecast them to intX, intY, intLength and when I draw them (often), I do this:

g.drawRect (intX, intY, intLength, intLength);

rather than

g.drawRect ((int) x, (int) y, (int) length, (int) length);

thus reducing the number of typecasts. Do you think that's worthwhile or is time spent repeatedly typecasting from double to int so fast as to make it irrelevant as compared to the time spent doing the drawing itself?

I would say it's irrelevant. If your paint method is just rendering shapes that have already been computed, I wouldn't worry about it.

I would say it's irrelevant. If your paint method is just rendering shapes that have already been computed, I wouldn't worry about it.

OK, cool. I'll drop those integer variables and the integer variables of the colors. Thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.