mirror of
https://github.com/badvision/jace.git
synced 2024-06-19 20:29:34 +00:00
289 lines
10 KiB
Java
289 lines
10 KiB
Java
/*
|
|
* Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
package jace.tracker;
|
|
|
|
import jace.core.Utility;
|
|
import java.awt.CardLayout;
|
|
import java.awt.Component;
|
|
import java.awt.Container;
|
|
import java.awt.EventQueue;
|
|
import java.awt.event.FocusEvent;
|
|
import java.awt.event.FocusListener;
|
|
import java.awt.event.KeyAdapter;
|
|
import java.awt.event.KeyEvent;
|
|
import java.awt.event.KeyListener;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.MouseListener;
|
|
import javax.swing.ImageIcon;
|
|
import javax.swing.JComboBox;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JTextField;
|
|
import javax.swing.border.EmptyBorder;
|
|
|
|
/**
|
|
*
|
|
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
|
*/
|
|
public class EditableLabel extends JPanel implements MouseListener, FocusListener {
|
|
|
|
public static EditableLabel FOCUS;
|
|
public static int DEFAULT_GAP = 4;
|
|
Component editComponent;
|
|
JLabel labelComponent;
|
|
CardLayout layout;
|
|
boolean isEditing = false;
|
|
int width = 4;
|
|
Object ownerObject;
|
|
String objectProperty;
|
|
|
|
private void showBlankValue() {
|
|
String s = "...................".substring(0, width);
|
|
labelComponent.setText(s);
|
|
}
|
|
|
|
public static enum cards {
|
|
|
|
label, edit
|
|
};
|
|
|
|
public EditableLabel(JLabel label, Component edit, int width, Object owner, String property) {
|
|
this(label, edit, width, DEFAULT_GAP, DEFAULT_GAP, owner, property);
|
|
}
|
|
|
|
public EditableLabel(JLabel label, Component edit, int width, int horizontalPadding, int verticalPadding, Object owner, String property) {
|
|
ownerObject = owner;
|
|
this.width = width;
|
|
objectProperty = property;
|
|
addMouseListener(this);
|
|
edit.addFocusListener(this);
|
|
addFocusListener(this);
|
|
layout = new CardLayout(horizontalPadding, verticalPadding);
|
|
setLayout(layout);
|
|
add(label, cards.label.toString());
|
|
add(edit, cards.edit.toString());
|
|
labelComponent = label;
|
|
editComponent = edit;
|
|
deactivateEdit();
|
|
setBackground(UserInterface.Theme.background.color);
|
|
label.setForeground(UserInterface.Theme.foreground.color);
|
|
label.setOpaque(false);
|
|
edit.setBackground(UserInterface.Theme.backgroundEdit.color);
|
|
edit.setForeground(UserInterface.Theme.foregroundEdit.color);
|
|
edit.setFocusTraversalKeysEnabled(false);
|
|
edit.addKeyListener(NAV_LISTENER);
|
|
label.addKeyListener(NAV_LISTENER);
|
|
this.addKeyListener(NAV_LISTENER);
|
|
}
|
|
|
|
@Override
|
|
public void mouseClicked(MouseEvent e) {
|
|
mousePressed(e);
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed(MouseEvent e) {
|
|
if (isEditing) {
|
|
return;
|
|
}
|
|
activateEdit();
|
|
// This next bit will generate a second mouse event and pass it on to the edit component so that
|
|
// the edit cursor appears under the mouse pointer, not a the start of the component.
|
|
final MouseEvent e2 = new MouseEvent(editComponent, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton());
|
|
EventQueue.invokeLater(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
editComponent.dispatchEvent(e2);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void mouseReleased(MouseEvent e) {
|
|
}
|
|
|
|
@Override
|
|
public void mouseEntered(MouseEvent e) {
|
|
}
|
|
|
|
@Override
|
|
public void mouseExited(MouseEvent e) {
|
|
}
|
|
|
|
@Override
|
|
public void focusGained(FocusEvent e) {
|
|
if (e.getComponent() == this || e.getComponent() == labelComponent || e.getComponent() == editComponent) {
|
|
activateEdit();
|
|
} else {
|
|
deactivateEdit();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void focusLost(FocusEvent e) {
|
|
deactivateEdit();
|
|
}
|
|
|
|
private void activateEdit() {
|
|
FOCUS = this;
|
|
isEditing = true;
|
|
layout.show(this, cards.edit.toString());
|
|
editComponent.requestFocusInWindow();
|
|
}
|
|
|
|
private void deactivateEdit() {
|
|
isEditing = false;
|
|
if (editComponent instanceof JTextField) {
|
|
String value = ((JTextField) editComponent).getText();
|
|
if (value != null) {
|
|
value = value.trim();
|
|
if (value.length() > width) {
|
|
value = value.substring(0, width);
|
|
}
|
|
}
|
|
Object result = Utility.setProperty(ownerObject, objectProperty, value, true);
|
|
|
|
value = (result == null) ? null : (result instanceof Integer ? Integer.toString((Integer) result, 16) : result.toString());
|
|
if (value != null && value.length() < width) {
|
|
value = value.concat(" ".substring(0, width - value.length()));
|
|
}
|
|
if (value == null || value.equals("")) {
|
|
showBlankValue();
|
|
((JTextField) editComponent).setText(null);
|
|
} else {
|
|
labelComponent.setText(value);
|
|
((JTextField) editComponent).setText(value.trim());
|
|
}
|
|
} else if (editComponent instanceof JComboBox) {
|
|
ImageIcon selection = (ImageIcon) ((JComboBox) editComponent).getSelectedItem();
|
|
labelComponent.setText(selection.getDescription());
|
|
}
|
|
layout.show(this, cards.label.toString());
|
|
}
|
|
|
|
public static EditableLabel generateTextLabel(Object owner, String property, int width, KeyListener listener) {
|
|
EditableLabel label = generateTextLabel(owner, property, width);
|
|
label.editComponent.addKeyListener(listener);
|
|
return label;
|
|
}
|
|
|
|
public static EditableLabel generateTextLabel(Object owner, String property, int width) {
|
|
Object value = Utility.getProperty(owner, property);
|
|
JLabel label = new JLabel(value != null ? value.toString() : null);
|
|
JTextField editor = new JTextField("");
|
|
editor.setCaretColor(UserInterface.Theme.foregroundEdit.color);
|
|
editor.setBorder(new EmptyBorder(0, 0, 0, 0));
|
|
label.setFont(UserInterface.EDITOR_FONT);
|
|
editor.setFont(UserInterface.EDITOR_FONT);
|
|
|
|
EditableLabel output = new EditableLabel(label, editor, width, owner, property);
|
|
if (value == null || value.equals("")) {
|
|
output.showBlankValue();
|
|
}
|
|
return output;
|
|
}
|
|
static KeyListener NAV_LISTENER = new KeyAdapter() {
|
|
@Override
|
|
public void keyReleased(KeyEvent e) {
|
|
switch (e.getKeyCode()) {
|
|
case KeyEvent.VK_TAB:
|
|
if (e.isShiftDown()) {
|
|
moveLeft();
|
|
} else {
|
|
moveRight();
|
|
}
|
|
e.consume();
|
|
break;
|
|
case KeyEvent.VK_UP:
|
|
moveUp();
|
|
e.consume();
|
|
break;
|
|
case KeyEvent.VK_DOWN:
|
|
moveDown();
|
|
e.consume();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
public int getIndex(Component c) {
|
|
System.out.println("Looking for " + c.getClass().getName() + " in parent " + c.getParent().getClass().getName());
|
|
for (int i = 0; i < c.getParent().getComponentCount(); i++) {
|
|
if (c == c.getParent().getComponent(i)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public void focus(final Component c) {
|
|
Runnable r = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (c instanceof EditableLabel) {
|
|
((EditableLabel) c).activateEdit();
|
|
} else {
|
|
c.requestFocusInWindow();
|
|
}
|
|
}
|
|
};
|
|
EventQueue.invokeLater(r);
|
|
}
|
|
|
|
public void moveDown() {
|
|
Component c = FOCUS;
|
|
int col = getIndex(c);
|
|
int row = getIndex(c.getParent()) + 1;
|
|
if (row < c.getParent().getParent().getComponentCount()) {
|
|
System.out.println("Trying to focus on col " + col + " row " + row);
|
|
focus(((Container) c.getParent().getParent().getComponent(row)).getComponent(col));
|
|
}
|
|
}
|
|
|
|
public void moveUp() {
|
|
Component c = FOCUS;
|
|
int col = getIndex(c);
|
|
int row = getIndex(c.getParent()) - 1;
|
|
if (row >= 0) {
|
|
System.out.println("Trying to focus on col " + col + " row " + row);
|
|
focus(((Container) c.getParent().getParent().getComponent(row)).getComponent(col));
|
|
}
|
|
}
|
|
|
|
public void moveLeft() {
|
|
Component c = FOCUS;
|
|
int col = getIndex(c) - 1;
|
|
System.out.println("Trying to focus on col " + col);
|
|
if (col >= 0) {
|
|
focus(c.getParent().getComponent(col));
|
|
}
|
|
}
|
|
|
|
public void moveRight() {
|
|
Component c = FOCUS;
|
|
int col = getIndex(c) + 1;
|
|
System.out.println("Trying to focus on col " + col);
|
|
if (col < c.getParent().getComponentCount()) {
|
|
focus(c.getParent().getComponent(col));
|
|
}
|
|
}
|
|
};
|
|
}
|