Monday, August 16, 2010

Update 5: DnD means Drag and Drop... no character sheets necessary

Thought I'd post a lil' snippet of code here for any wide-eyed web wanderer to use. Its a JTextField that looks like a label until double clicked, or clicked and held for 1 second. When the field looses focus, or enter is pressed it goes back to looking like a label.

Its useful in creating a condensed GUI with high functionality. Disagree? Well Photoshop's got a neat little label just like this ;-). I just wrote a Java implementation. Please subscribe, or at least lemme know if this is useful for you.


/**
* A textfield that appears as a label unless double clicked, or clicked and
* held for 1 second.
*
* @author Will Morrison
*/
public class JTextFieldLabel extends JTextField {
/**
* Default serial version ID, here to remove warnings
*/
private static final long serialVersionUID = 1L;

/**
* The original border this JTextfield used upon first instantiation
*/
private Border origBorder;
private static final Border emptyBorder = BorderFactory.createEmptyBorder();

public JTextFieldLabel() {
this("");
}

public JTextFieldLabel(String text) {
super(text, 10);
setEditable(false);
setOpaque(false);
origBorder = this.getBorder();
privateSetBorder(emptyBorder);

TextFieldLabelListener listener = new TextFieldLabelListener();
addMouseListener(listener);
addMouseMotionListener(listener);
addFocusListener(listener);
addActionListener(listener);
}

public void setBorder(Border b) {
this.origBorder = b;
super.setBorder(b);
}

private void privateSetBorder(Border b) {
super.setBorder(b);
}

public void paintComponent(Graphics g) {
if (!hasFocus()) {
super.setBorder(emptyBorder);
}
super.paintComponent(g);
}

private class TextFieldLabelListener extends MouseAdapter implements
FocusListener, ActionListener {
private Timer timer;
private boolean mouseHasMoved;

public TextFieldLabelListener() {
timer = new Timer(1000, this);
}

public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
setEditable(true);
setOpaque(true);
privateSetBorder(origBorder);
}
}

public void mousePressed(MouseEvent e) {
if (!timer.isRunning() && !mouseHasMoved) {
timer.start();
}
}

public void mouseDragged(MouseEvent e) {
mouseHasMoved = true;
timer.stop();
}

public void mouseReleased(MouseEvent e) {
mouseHasMoved = false;
timer.stop();
}

public void focusGained(FocusEvent e) {
// intentionally left blank
}

public void focusLost(FocusEvent e) {
privateSetBorder(emptyBorder);
setEditable(false);
setOpaque(false);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Timer) {
timer.stop();
privateSetBorder(origBorder);
setEditable(true);
setOpaque(true);
requestFocus();
} else {
privateSetBorder(emptyBorder);
setEditable(false);
setOpaque(false);
}
}
}
}


As far as my editor goes, I just got TileLayer's z values to update properly with GUI panel's ordering. It looks pretty nice. Developing a DnD list with functioning GUI components in Java is a major pain, but I did it. Its even nicer because when I drag and drop components my TileMap is now updated.