Letters to the Editor (October 20, 1999)

news
Nov 1, 19996 mins

Drag-and-Drop Tutorial

‘How to drag and drop with Java 2, Parts 1 and 2’

Gene De Lisa

http://www.javaworld.com/jw-03-1999/jw-03-dragndrop.html

http://www.javaworld.com/jw-08-1999/jw-08-draganddrop.html

Public domain drag-and-drop software with Windows Explorer functionality

Gene,

Do you know of any software in the public domain that uses drag and drop for Windows Explorer-like functionality? (By Windows Explorer, I refer to Microsoft’s application for managing files and folders.)

Or, if you have pointers to programmers who are working on such a project, I would be grateful if I could get such references from you.

Charlie

Charlie, Yes, I do know of such software. I’ve even written such a program. To do this right, first learn about the JavaBeans Activation Framework (JAF), part of the JavaBean spec. Bean containment and JAF are almost tailor-made for this project. Then, use FileTransferable and the DnDFileList or DnDFIleTree to build the GUI components. (See the Java 2 Drag and Drop component library for more information: https://www.rockhoppertech.com/download.html.) In addition, I think the JavaLobby has one such program in the works too. Gene De Lisa

Java Toolbox

‘User interfaces for object-oriented systems, Parts 1, 2, and 3’

Allen Holub

http://www.javaworld.com/jw-07-1999/jw-07-toolbox.html

http://www.javaworld.com/jw-09-1999/jw-09-toolbox.html

http://www.javaworld.com/jw-10-1999/jw-10-toolbox.html

More on those evil getters and setters

Allen,

I have been following your articles in JavaWorld about object-oriented user interfaces and have a question that I hope you can elaborate on.

In your first article you discussed what an object is, and what it isn’t, and laid out some rules to follow when designing and implementing objects. I was curious about your statement that “get and set functions are evil….” I realize that you are making a case for keeping all data private, and I agree with the concept wholeheartedly, but how is this practical?

Using your example of an Employee with a Salary attribute, my question is: How do you tell an Employee object what its Salary should be? (Barring the constructor, of course.) If an Employee‘s Salary object is to be changed, doesn’t it make more sense to create a new Salary object and use an Employee‘s setSalary() method? The alternative, as far as I can see, is to actually manipulate the Salary object itself (for example: Salary.increaseBy(percentage)), but I think that could be extremely tedious and error prone.

Please note that I have the mindset that a user interface is not being used (if it were, then the rest of the articles would answer my question).

I really like the articles and I am seeking to implement a lot of your ideas into the project I am working on. It makes a lot of sense that an object shouldn’t be manipulated from the outside, yet I can also see a case for when something outside the object decides that one of its attributes will change.

Anthony Weissenberger

Anthony, Of course, the first time an object comes into existence, the Employee‘s constructor would throw up a UI that the user would use to enter the data. Thereafter, if you had an OO database, you’d actually just store Employees in it, and they would come out of the database in whatever state they were in when they were inserted in the database. The trickier issue is when you’re storing the state of an Employee in a relational database. Though a particular instance of Employee could store and load itself, it’s not particularly efficient to issue a query (which I’d expect would contain a moderately large join) just to get a single row out of the database. A few design patterns help solve the problem, though. A Factory, for example, could get many thousands of Employees, cache most of them, and return one. You could use a Proxy to delay the extraction of various fields until they’re actually needed, and so on. Your actual question — How do you tell an Employee what its Salary should be? — is difficult to answer out of context. The easy answer is that you ask Employee to expose a UI through which a human being could modify Salary. I’d really have to see a problem statement and dynamic-model diagram to see if any other strategy would make sense. But let’s say that you wanted to give an employee a raise. You’d send the Employee object a raise_your_salary_by_this_percentage(4.5) message or the equivalent; you would not specify an entirely new Salary. In other words, it doesn’t often happen that Salary is changed by a completely arbitrary amount. Rather, you give employees raises, dock their pay for being late, and so on, and your messaging system would reflect those real-world operations. Allen Holub

Tips ‘n Tricks

‘Java Tips Index’

John Zukowski

http://www.javaworld.com/javatips/jw-javatips.index.html

Help for an XMB image

John,

I was not aware that Java supports X Bitmap files until I read the JavaWorld tips section. Yes, the Java support works, but it’s unfortunately not documented anywhere.

I am facing one problem using XBM files in Java. If I try to get BufferedImage from the image created with XBM files, it comes out all black. The procedure works fine with the JPEG and GIF formats.

Here’s my code:

/*<Applet code=BmpImage.class
width=200 height=200> </Applet>*/
import java.io.*;
import java.applet.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
public class BmpImage extends Applet{
   public BufferedImage bimg;
   public Image myImg;
   public void init()
   {
      myImg = Toolkit.getDefaultToolkit().createImage("chili.xbm");
      MediaTracker tracker = new MediaTracker(this);
      try{
         tracker.addImage(myImg, 0);
         tracker.waitForAll();
         }catch(Exception e){};
      bimg = new BufferedImage(myImg.getWidth(this), myImg.getHeight(this),
         BufferedImage.TYPE_INT_RGB);
      Graphics tempGr = bimg.createGraphics();
      tempGr.drawImage(myImg, 0, 0, this);
   }
   public void paint(Graphics g){
      g.drawImage(bimg, 0, 0, this);   // awt.image.bufferedImage comes all black
      g.drawImage(myImg, myImg.getWidth(null), 
            myImg.getHeight(null), this);   // awt.image comes properly
   }
}

Satish Sangtani

Satish, You need to change one line of your source code. The

BufferedImage

type needs to be

BufferedImage.TYPE_INT_ARGB

, not

BufferedImage.TYPE_INT_RGB

.

      bimg = new BufferedImage(myImg.getWidth(this), myImg.getHeight(this),
                                                BufferedImage.TYPE_INT_ARGB);
                                    

John Zukowski