package iiuf.swing;
import java.io.Serializable;
import java.io.File;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.Component;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerListener;
import java.awt.event.ContainerEvent;
import java.awt.event.FocusListener;
import java.awt.event.FocusEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.JTree;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
import javax.swing.JViewport;
import javax.swing.JFileChooser;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.Timer;
import javax.swing.plaf.basic.BasicToolBarUI;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
// import iiuf.log.Log;
import iiuf.awt.BorderLayout;
import iiuf.awt.Awt;
import iiuf.util.Util;
import iiuf.util.PrefWatcher;
import iiuf.util.PrefNamer;
import iiuf.util.PrefReanimator;
/**
Swing related preferences watchers and namers.
(c) 2000, 2001, IIUF, DIUF<p>
@author $Author: ohitz $
@version $Name: $ $Revision: 1.1 $
*/
public class Preferences {
private static final int SWING_DELAY = 1000; // delay for async swing updates, should find a better solution once
static class EmptyState implements Serializable {}
static class JToolBarState implements Serializable {
Point location;
boolean floating;
int orientation;
Object constraints;
transient boolean inited;
JToolBarState(JToolBar cmp) {
inited = true;
grab(cmp);
}
void grab(JToolBar cmp) {
floating = false;
orientation = cmp.getOrientation();
Component p = cmp.getParent();
if(p instanceof Container) {
Container ct = (Container)p;
if(ct.getLayout() instanceof BorderLayout) {
constraints = getConstraints(cmp);
floating =
!(BorderLayout.NORTH.equals(constraints) ||
BorderLayout.EAST.equals(constraints) ||
BorderLayout.SOUTH.equals(constraints) ||
BorderLayout.WEST.equals(constraints));
}
}
if(floating)
location = Awt.getWindow(cmp).getLocation();
}
void apply(JToolBar cmp) {
if(inited) return;
inited = true;
cmp.setOrientation(orientation);
if(floating) {
if(cmp.getUI() instanceof BasicToolBarUI) {
Point l = (Point)location.clone();
((BasicToolBarUI)cmp.getUI()).setFloatingLocation(l.x, l.y);
((BasicToolBarUI)cmp.getUI()).setFloating(true, l);
}
if(cmp.getUI() instanceof JWindowToolBarUI) {
Point l = (Point)location.clone();
((JWindowToolBarUI)cmp.getUI()).setFloatingLocation(l.x, l.y);
((JWindowToolBarUI)cmp.getUI()).setFloating(true, l);
}
}
else {
Container p = (Container)cmp.getParent();
p.remove(cmp);
p.add(cmp, constraints);
}
}
public String toString() {
return
"location:" + location +
", floating:" + floating +
", orientation:" + orientation +
", constraints:" + constraints +
", inited:" + inited;
}
private String getConstraints(JToolBar cmp) {
Container ct = (Container)cmp.getParent();
BorderLayout bl = (BorderLayout)ct.getLayout();
if(bl.getChild(ct, BorderLayout.NORTH) == cmp)
return BorderLayout.NORTH;
else if(bl.getChild(ct, BorderLayout.SOUTH) == cmp)
return BorderLayout.SOUTH;
else if(bl.getChild(ct, BorderLayout.EAST) == cmp)
return BorderLayout.EAST;
else if(bl.getChild(ct, BorderLayout.WEST) == cmp)
return BorderLayout.WEST;
return
null;
}
}
static class JFileChooserState implements Serializable {
Point location;
File[] selection;
JFileChooserState(JFileChooser cmp) {
grab(cmp);
}
void grab(JFileChooser jfc) {
location = jfc.getLocation();
if(jfc.isMultiSelectionEnabled())
selection = jfc.getSelectedFiles();
else
selection = new File[] {jfc.getSelectedFile()};
}
void apply(JFileChooser jfc) {
jfc.setLocation(location);
if(selection.length == 1) {
if(selection[0] != null)
jfc.setSelectedFile(selection[0]);
} else
jfc.setSelectedFiles(selection);
}
}
static class JSplitPaneState implements Serializable {
int location;
JSplitPaneState(JSplitPane cmp) {grab(cmp);}
void grab(JSplitPane cmp) {location = cmp.getDividerLocation();}
void apply(JSplitPane cmp) {cmp.setDividerLocation(location);}
public String toString() {return "location:" + location;}
}
static class JTextComponentState implements Serializable {
int dot;
int mark;
int len;
boolean focus;
transient boolean applied;
transient long firstGrab;
JTextComponentState(JTextComponent cmp) {grab(cmp);}
void grab(JTextComponent cmp) {
if(firstGrab == 0)
firstGrab = System.currentTimeMillis();
if(applied || System.currentTimeMillis() - firstGrab > (5 * SWING_DELAY)) {
dot = cmp.getCaret().getDot();
mark = cmp.getCaret().getMark();
len = cmp.getDocument().getLength();
}
focus = cmp.hasFocus();
}
void apply(JTextComponent cmp) {
if(!applied && cmp.getDocument().getLength() >= len) {
if(dot == mark) {
cmp.setCaretPosition(dot);
} else {
cmp.setSelectionStart(mark);
cmp.setSelectionEnd(dot);
cmp.getCaret().setSelectionVisible(true);
}
if(focus) cmp.requestFocus();
applied = true;
}
}
}
static class JTabbedPaneState implements Serializable{
String selected;
transient boolean applied;
transient long firstGrab;
JTabbedPaneState(JTabbedPane cmp) {grab(cmp);}
void grab(JTabbedPane cmp) {
if(firstGrab == 0)
firstGrab = System.currentTimeMillis();
if(applied || System.currentTimeMillis() - firstGrab > (5 * SWING_DELAY)) {
try {
selected = iiuf.util.Preferences.getPath(cmp.getSelectedComponent());
} catch(IllegalArgumentException e) {}
}
}
void apply(JTabbedPane cmp) {
if(!applied) {
try {
Object c = iiuf.util.Preferences.getObjectForPath(selected);
if(c == null || !(c instanceof Component)) return;
cmp.setSelectedComponent((Component)c);
applied = true;
} catch(IllegalArgumentException e) {}
}
}
public String toString() {return "selected:" + selected;}
}
static class JViewportState implements Serializable {
Point position;
transient boolean applied;
JViewportState(JViewport cmp) {grab(cmp);}
void grab(JViewport cmp) {position = cmp.getViewPosition();}
boolean apply(JViewport cmp) {
if(!applied && cmp.getView().getBounds().contains(position)) {
cmp.setViewPosition(position);
applied = true;
}
return applied;
}
public String toString() {return "position:" + position;}
}
static class JTreeExpander
implements
ActionListener,
TreeModelListener
{
JTreeState state;
JTree tree;
JTreeExpander(JTreeState state_, JTree tree_) {
state = state_;
tree = tree_;
}
public void actionPerformed(ActionEvent e) {
state.expandAll(tree);
}
public void treeNodesChanged(TreeModelEvent e) {}
public void treeNodesRemoved(TreeModelEvent e) {}
public void treeStructureChanged(TreeModelEvent e) {
scheduleExpand();
}
public void treeNodesInserted(TreeModelEvent e) {
scheduleExpand();
}
private void scheduleExpand() {
Timer t = new Timer(SWING_DELAY, this); // ughh - find a besser solution
t.setRepeats(false);
t.start();
}
}
static TreePath str2path(String[] path, int[] idxs, TreeModel model) {
Object node = model.getRoot();
TreePath path_ = new TreePath(node);
pathloop:
for(int i = 0; i < path.length; i++) {
Object n = node;
int c = model.getChildCount(node);
if(c == 0) return null;
// first we try with child @ idx.
if(idxs[i] < 0) idxs[i] = 0;
if(idxs[i] >= c) idxs[i] = c - 1;
node = model.getChild(n, idxs[i]);
if(node.toString().equals(path[i])) {
path_ = path_.pathByAddingChild(node);
continue pathloop;
}
// failed -> loop over all childs
// we start the search in a neighborhood of idxs[i]
int stop = (c / 2) + 1;
for(int j = 0; j < stop; j++) {
node = model.getChild(n, (idxs[i] + j) % c);
if(node.toString().equals(path[i])) {
path_ = path_.pathByAddingChild(node);
continue pathloop;
}
node = model.getChild(n, Math.abs(idxs[i] - j) % c);
if(node.toString().equals(path[i])) {
path_ = path_.pathByAddingChild(node);
continue pathloop;
}
}
return null;
}
return path_;
}
static void path2str(Object[] path, String[] strs, int idxs[], TreeModel model) {
for(int i = 0; i < strs.length; i++) {
strs[i] = path[i + 1].toString();
idxs[i] = model.getIndexOfChild(path[i], path[i + 1]);
}
}
static class ButtonTreePathViewState implements Serializable {
String[] path = new String[0];
int[] idxs = new int[0];
ButtonTreePathViewState(ButtonTreePathView btpv) {
grab(btpv);
}
void apply(ButtonTreePathView btpv) {
btpv.setPath(str2path(path, idxs, btpv.getModel()));
}
void grab(ButtonTreePathView btpv) {
Object[] pcs = btpv.getPath().getPath();
path = new String[pcs.length - 1];
idxs = new int[pcs.length - 1];
path2str(pcs, path, idxs, btpv.getModel());
}
}
static class JTreeState implements Serializable {
String[][] expandedPaths = new String[0][];
int[][] expandedPathIdxs = new int[0][];
String[][] selectionPaths = new String[0][];
int[][] selectionPathIdxs = new int[0][];
transient boolean[] expanded = new boolean[0];
synchronized void apply(JTree tree) {
expanded = new boolean[expandedPaths.length];
expandAll(tree);
TreeModel model = tree.getModel();
if(model != null)
model.addTreeModelListener(new JTreeExpander(this, tree));
}
public String toString() {
String result = "{";
for(int i = 0; i < expandedPaths.length; i++) {
result += "[";
for(int j = 0; j < expandedPaths[i].length; j++)
result += expandedPaths[i][j] + " ";
result += "]";
}
result += "}";
return result;
}
void expandAll(JTree tree) {
for(int i = 0; i < expandedPaths.length; i++)
if(!expanded[i]) {
TreePath path = str2path(expandedPaths[i], expandedPathIdxs[i], tree.getModel());
if(path != null) {
expanded[i] = true;
tree.expandPath(path);
}
}
}
void selectAll(JTree tree) {
for(int i = 0; i < selectionPaths.length; i++) {
TreePath path = str2path(selectionPaths[i], selectionPathIdxs[i], tree.getModel());
if(path != null)
tree.addSelectionPath(path);
}
}
boolean equals(String[] path1, int idxs1[], String[] path2, int[] idxs2) {
if(path1.length != path2.length) return false;
for(int i = 0; i < path1.length; i++)
if(!path1[i].equals(path2[i]) || idxs1[i] != idxs2[i])
return false;
return true;
}
boolean has(String[] path, int[] idxs) {
for(int i = 0; i < expandedPaths.length; i++)
if(equals(expandedPaths[i], expandedPathIdxs[i], path, idxs))
return true;
return false;
}
synchronized void add(TreePath path_, JTree tree) {
Object[] pcs = path_.getPath();
String[] path = new String[pcs.length - 1];
int[] idxs = new int[pcs.length - 1];
path2str(pcs, path, idxs, tree.getModel());
if(!has(path, idxs)) {
String[][] tmp = expandedPaths;
expandedPaths = new String[tmp.length + 1][];
System.arraycopy(tmp, 0, expandedPaths, 0, tmp.length);
expandedPaths[tmp.length] = path;
boolean[] btmp = expanded;
expanded = new boolean[btmp.length + 1];
System.arraycopy(btmp, 0, expanded, 0, btmp.length);
int[][] itmp = expandedPathIdxs;
expandedPathIdxs = new int[itmp.length + 1][];
System.arraycopy(itmp, 0, expandedPathIdxs, 0, itmp.length);
expandedPathIdxs[itmp.length] = idxs;
}
}
synchronized void remove(TreePath path_, JTree tree) {
Object[] pcs = path_.getPath();
String[] path = new String[pcs.length - 1];
int[] idxs = new int[pcs.length - 1];
path2str(pcs, path, idxs, tree.getModel());
if(has(path, idxs)) {
String[][] tmp = expandedPaths;
expandedPaths = new String[tmp.length - 1][];
int[][] itmp = expandedPathIdxs;
expandedPathIdxs = new int[itmp.length - 1][];
boolean[] btmp = expanded;
expanded = new boolean[btmp.length - 1];
int j = 0;
for(int i = 0; i < tmp.length; i++) {
if(!equals(path, idxs, tmp[i], itmp[i])) {
expandedPaths[j] = tmp[i];
expandedPathIdxs[j] = itmp[i];
expanded[j] = btmp[i];
j++;
}
}
}
}
void selection(TreePath[] paths, JTree tree) {
if(paths == null) {
selectionPaths = new String[0][];
selectionPathIdxs = new int[0][];
} else {
selectionPaths = new String[paths.length][];
selectionPathIdxs = new int[paths.length][];
for(int i = 0; i < paths.length; i++) {
Object[] pcs = paths[i].getPath();
selectionPaths[i] = new String[pcs.length - 1];
selectionPathIdxs[i] = new int[pcs.length - 1];
path2str(pcs, selectionPaths[i], selectionPathIdxs[i], tree.getModel());
}
}
}
}
static class JDesktopPaneState implements Serializable {
int[] positions;
String[] paths;
transient int applyCnt;
JDesktopPaneState(JDesktopPane jdp) {grab(jdp);}
void grab(JDesktopPane jdp) {
if(applyCnt != 0) return;
JInternalFrame[] frames = jdp.getAllFrames();
positions = new int[frames.length];
paths = new String[frames.length];
for(int i = 0; i < frames.length; i++) {
iiuf.util.Preferences.watch(frames[i]);
positions[i] = jdp.getPosition(frames[i]);
paths[i] = iiuf.util.Preferences.getPath(frames[i]);
}
}
void apply(JDesktopPane jdp) {
applyCnt++;
JInternalFrame[] frames = jdp.getAllFrames();
for(int i = 0; i < frames.length; i++)
iiuf.util.Preferences.watch(frames[i]);
JInternalFrame lastFrame = null;
for(int j = 0; j < positions.length; j++) {
int maxpos = Integer.MIN_VALUE;
int maxidx = j;
for(int i = 0; i < positions.length; i++) {
if(positions[i] > maxpos)
maxidx = i;
}
JInternalFrame frame = (JInternalFrame)iiuf.util.Preferences.getObjectForPath(paths[maxidx]);
if(frame == null) {
Object[] prefs = iiuf.util.Preferences.getMulti(paths[maxidx]);
for(int i = 0; i < prefs.length; i++)
if(prefs[i] instanceof PrefReanimator) {
frame = (JInternalFrame)((PrefReanimator)prefs[i]).reanimate(paths[maxidx], prefs);
if(frame == null) continue;
jdp.add(frame);
iiuf.util.Preferences.watch(frame, paths[maxidx]);
frame.setVisible(true);
lastFrame = frame;
break;
}
} else {
frame.toFront();
lastFrame = frame;
}
positions[maxidx] = Integer.MIN_VALUE;
}
if(lastFrame != null)
try{lastFrame.setSelected(true);} catch(Exception e) {}
applyCnt--;
positions = new int[0];
grab(jdp);
}
}
static class TableColumnState
implements
Serializable,
PropertyChangeListener
{
int[] widths;
int[] order;
TableColumnState(TableColumnModel tcm) {grab(tcm);}
void grab(TableColumnModel tcm) {
order = new int[tcm.getColumnCount()];
int maxidx = -1;
for(int i = 0; i < order.length; i++) {
int idx = tcm.getColumn(i).getModelIndex();
order[i] = idx;
if(idx > maxidx)
maxidx = idx;
}
widths = new int[maxidx + 1];
for(int i = 0; i < order.length; i++)
widths[order[i]] = tcm.getColumn(i).getWidth();
installListeners(tcm);
}
void apply(TableColumnModel tcm) {
int count = Math.min(tcm.getColumnCount(), widths.length);
for(int i = 0; i < count; i++) {
TableColumn col = tcm.getColumn(i);
col.setPreferredWidth(widths[col.getModelIndex()]);
col.setWidth(widths[col.getModelIndex()]);
}
int last = Math.min(tcm.getColumnCount(), order.length) - 1;
int idx = 0;
for(int i = last; i >= 0; i--) {
for(int j = 0; j <= i; j++) {
if(tcm.getColumn(j).getModelIndex() == order[idx]) {
tcm.moveColumn(j, last);
break;
}
}
idx++;
}
installListeners(tcm);
}
void installListeners(TableColumnModel tcm) {
for(int i = 0; i < tcm.getColumnCount(); i++) {
TableColumn col = tcm.getColumn(i);
col.removePropertyChangeListener(this);
col.addPropertyChangeListener(this);
}
}
public void propertyChange(PropertyChangeEvent e) {
TableColumn tc = (TableColumn)e.getSource();
widths[tc.getModelIndex()] = tc.getWidth();
}
}
static class WindowState
implements
Serializable
{
boolean icon;
boolean showing;
long activationTime;
Rectangle bounds;
WindowState(Window w) {grab(true, w);}
void grab(boolean setATime, Window w) {
bounds = w.getBounds();
showing = w.isShowing();
if(w instanceof Frame)
icon = ((Frame)w).getState() == Frame.ICONIFIED;
if(setATime)
activationTime = System.currentTimeMillis();
}
void apply(Window w) {
w.setSize(bounds.width, bounds.height);
w.setLocation(bounds.x, bounds.y);
if(w instanceof Frame)
((Frame)w).setState(icon ? Frame.ICONIFIED : Frame.NORMAL);
w.setVisible(showing);
}
public String toString() {
return "icon:" + icon + ",showing:" + showing + ",activationTime:" + activationTime;
}
}
static class JInternalFrameState
implements
Serializable
{
boolean icon;
boolean showing;
boolean maximized;
Rectangle iconizedBounds;
Rectangle bounds;
JInternalFrameState(JInternalFrame frame) {
grab(false, frame);
}
void grab(boolean grabPosition, JInternalFrame frame) {
icon = frame.isIcon();
showing = frame.isVisible();
maximized = frame.isMaximum();
if(!icon && !maximized) bounds = frame.getBounds();
}
void grab(Component cmp) {
iconizedBounds = cmp.getBounds();
}
void apply(JInternalFrame frame) {
if(bounds != null && !frame.isMaximum() && !frame.isIcon())
frame.setBounds(bounds);
try{frame.setMaximum(maximized);} catch(Exception e) {}
try{frame.setIcon(icon);} catch(Exception e) {}
if(iconizedBounds != null && icon)
frame.getDesktopIcon().setLocation(iconizedBounds.getLocation());
frame.setVisible(showing);
}
}
static class JTreeSelecter
implements
TreeExpansionListener,
Runnable
{
JTreeState state;
JTree tree;
JTreeSelecter(JTreeState state_) {
state = state_;
}
public void treeCollapsed(TreeExpansionEvent event) {
tree = (JTree)event.getSource();
state.remove(event.getPath(), tree);
}
public void treeExpanded(TreeExpansionEvent event) {
tree = (JTree)event.getSource();
if(tree.getParent().getParent() instanceof JScrollPane)
SwingUtilities.invokeLater(this);
state.add(event.getPath(), tree);
}
public void run() {
state.selectAll(tree);
}
}
private static boolean inited;
public synchronized static void init() {
if(inited) return;
inited = true;
iiuf.util.Preferences.register(Object.class, new PrefNamer() {
public String getName(Object o) {return o.getClass().getName();}
});
iiuf.util.Preferences.register(Frame.class, new PrefNamer() {
public String getName(Object o) {return ((Frame)o).getTitle();}
});
iiuf.util.Preferences.register(JInternalFrame.class, new PrefNamer() {
public String getName(Object o) {return ((JInternalFrame)o).getTitle();}
});
iiuf.util.Preferences.register(TableColumn.class, new PrefNamer() {
public String getName(Object o) {return ((TableColumn)o).getHeaderValue().toString();}
});
iiuf.util.Preferences.register(Component.class, new PrefNamer() {
public String getName(Object o) {
String result = ((Component)o).getName();
if(result == null || result.equals("")) return o.getClass().getName();
else return result;
}
});
//------ Window
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
Window window = (Window)o;
final WindowState result = preferences == null ? new WindowState(window) : (WindowState)preferences;
if(preferences != null) result.apply(window);
window.addWindowListener(new WindowAdapter() {
WindowState state = result;
public void windowOpened(WindowEvent e) {state.grab(true, e.getWindow());}
public void windowActivated(WindowEvent e) {state.grab(true, e.getWindow());}
public void windowDeactivated(WindowEvent e) {state.grab(false, e.getWindow());}
public void windowIconified(WindowEvent e) {state.grab(false, e.getWindow());}
public void windowDeiconified(WindowEvent e) {state.grab(false, e.getWindow());}
});
return result;
}
public Class watchedClass() {return Window.class;}
});
//------ JTabbedPane
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JTabbedPane jtp = (JTabbedPane)o;
// ensure that tabs are watched
for(int i = 0; i < jtp.getTabCount(); i++)
iiuf.util.Preferences.watch(jtp.getComponentAt(i));
final JTabbedPaneState result = preferences == null ? new JTabbedPaneState(jtp) : (JTabbedPaneState)preferences;
if(preferences != null) result.apply(jtp);
jtp.addChangeListener(new ChangeListener() {
JTabbedPaneState state = result;
public void stateChanged(ChangeEvent e) {
state.grab((JTabbedPane)e.getSource());
}
});
jtp.addContainerListener(new ContainerListener() {
JTabbedPaneState state = result;
public void componentAdded(ContainerEvent e) {
iiuf.util.Preferences.watch(e.getChild());
state.apply((JTabbedPane)e.getContainer());
}
public void componentRemoved(ContainerEvent e) {}
});
return result;
}
public Class watchedClass() {return JTabbedPane.class;}
});
//------ JSplitPane
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JSplitPane jsp = (JSplitPane)o;
final JSplitPaneState result = preferences == null ? new JSplitPaneState(jsp) : (JSplitPaneState)preferences;
if(preferences != null) result.apply(jsp);
jsp.addPropertyChangeListener(JSplitPane.LAST_DIVIDER_LOCATION_PROPERTY,
new PropertyChangeListener() {
JSplitPaneState state = result;
public void propertyChange(PropertyChangeEvent e) {
state.grab((JSplitPane)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JSplitPane.class;}
});
//------ JTextComponent
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JTextComponent jtc = (JTextComponent)o;
final JTextComponentState result = preferences == null ? new JTextComponentState(jtc) : (JTextComponentState)preferences;
if(preferences != null) result.apply(jtc);
jtc.addFocusListener(new FocusListener() {
JTextComponentState state = result;
public void focusGained(FocusEvent e) {
state.grab((JTextComponent)e.getSource());
}
public void focusLost(FocusEvent e) {
state.grab((JTextComponent)e.getSource());
}
});
jtc.addCaretListener(new CaretListener() {
JTextComponentState state = result;
public void caretUpdate(CaretEvent e) {
state.grab((JTextComponent)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JTextComponent.class;}
});
//------ JViewport
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JViewport jvp = (JViewport)o;
boolean applied;
final JViewportState result = preferences == null ? new JViewportState(jvp) : (JViewportState)preferences;
if(preferences != null) result.apply(jvp);
jvp.addChangeListener(new ChangeListener() {
JViewportState state = result;
public void stateChanged(ChangeEvent e) {
if(state.apply((JViewport)e.getSource()))
state.grab((JViewport)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JViewport.class;}
});
//------ TableColumnModel
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
final TableColumnModel tm = (TableColumnModel)o;
final TableColumnState result = preferences == null ? new TableColumnState(tm) : (TableColumnState)preferences;
if(preferences != null) result.apply(tm);
tm.addColumnModelListener(new TableColumnModelListener() {
TableColumnState state = result;
public void columnAdded(TableColumnModelEvent e) {state.grab((TableColumnModel)e.getSource());}
public void columnMarginChanged(ChangeEvent e) {state.grab((TableColumnModel)e.getSource());}
public void columnMoved(TableColumnModelEvent e) {state.grab((TableColumnModel)e.getSource());}
public void columnRemoved(TableColumnModelEvent e) {state.grab((TableColumnModel)e.getSource());}
public void columnSelectionChanged(ListSelectionEvent e) {}
});
return result;
}
public Class watchedClass() {return TableColumnModel.class;}
});
//------ JInternalFrame
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
final JInternalFrame jif = (JInternalFrame)o;
final JInternalFrameState result = preferences == null ? new JInternalFrameState(jif) : (JInternalFrameState)preferences;
if(preferences != null) result.apply(jif);
jif.addComponentListener(new ComponentAdapter() {
JInternalFrameState state = result;
public void componentMoved(ComponentEvent e) {
state.grab(false, (JInternalFrame)e.getComponent());
}
public void componentResized(ComponentEvent e) {
state.grab(false, (JInternalFrame)e.getComponent());
}
});
jif.addInternalFrameListener(new InternalFrameListener() {
JInternalFrameState state = result;
JInternalFrame.JDesktopIcon icon;
boolean setIconBounds = state.iconizedBounds != null && !state.icon;
boolean setBounds = state.icon;
int dummy = installIconListener(jif);
public void internalFrameClosed(InternalFrameEvent e) {}
public void internalFrameActivated(InternalFrameEvent e) {
state.grab(true, (JInternalFrame)e.getSource());
}
public void internalFrameDeiconified(InternalFrameEvent e) {
JInternalFrame frame = (JInternalFrame)e.getSource();
if(setBounds) {
try{frame.setMaximum(state.maximized);} catch(Exception ex) {}
if(!state.maximized && state.bounds != null)
frame.setBounds(state.bounds);
setBounds = false;
}
state.grab(true, frame);
}
public void internalFrameOpened(InternalFrameEvent e) {
state.grab(true, (JInternalFrame)e.getSource());
}
public void internalFrameClosing(InternalFrameEvent e) {
state.grab(false, (JInternalFrame)e.getSource());
}
public void internalFrameDeactivated(InternalFrameEvent e) {
state.grab(false, (JInternalFrame)e.getSource());
}
public synchronized void internalFrameIconified(InternalFrameEvent e) {
JInternalFrame frame = (JInternalFrame)e.getSource();
state.grab(false, frame);
installIconListener(frame);
state.grab(frame.getDesktopIcon());
}
int installIconListener(JInternalFrame frame) {
if(!state.icon) return 0;
if(icon != frame.getDesktopIcon()) {
icon = frame.getDesktopIcon();
icon.addComponentListener(new ComponentAdapter() {
public void componentMoved(ComponentEvent e) {state.grab(e.getComponent());}
public void componentResized(ComponentEvent e) {state.grab(e.getComponent());}
});
if(setIconBounds) {
icon.setLocation(state.iconizedBounds.getLocation());
setIconBounds = false;
}
}
return 0;
}
});
return result;
}
public Class watchedClass() {return JInternalFrame.class;}
});
//------ JDesktopPane
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JDesktopPane jdp = (JDesktopPane)o;
final JDesktopPaneState result = preferences == null ? new JDesktopPaneState(jdp) : (JDesktopPaneState)preferences;
if(preferences != null) result.apply(jdp);
jdp.addContainerListener(new ContainerListener() {
JDesktopPaneState state = result;
public void componentAdded(ContainerEvent e) {state.grab((JDesktopPane)e.getContainer());}
public void componentRemoved(ContainerEvent e) {state.grab((JDesktopPane)e.getContainer());}
});
return result;
}
public Class watchedClass() {return JDesktopPane.class;}
});
//------ ButtonTreePathView
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
ButtonTreePathView btpv = (ButtonTreePathView)o;
final ButtonTreePathViewState result =
preferences == null ? new ButtonTreePathViewState(btpv) :
(ButtonTreePathViewState)preferences;
if(preferences != null) result.apply(btpv);
btpv.addChangeListener(new ChangeListener() {
ButtonTreePathViewState state = result;
public void stateChanged(ChangeEvent e) {
state.grab((ButtonTreePathView)e.getSource());
}
});
return result;
}
public Class watchedClass() {return ButtonTreePathView.class;}
});
// ----- JFileChooser
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JFileChooser jfc = (JFileChooser)o;
final JFileChooserState result = preferences == null ? new JFileChooserState(jfc) : (JFileChooserState)preferences;
if(preferences != null) result.apply(jfc);
PropertyChangeListener listener = new PropertyChangeListener() {
JFileChooserState state = result;
public void propertyChange(PropertyChangeEvent e) {
state.grab((JFileChooser)e.getSource());
}
};
jfc.addPropertyChangeListener(jfc.SELECTED_FILE_CHANGED_PROPERTY, listener);
jfc.addPropertyChangeListener(jfc.SELECTED_FILES_CHANGED_PROPERTY, listener);
jfc.addAncestorListener(new AncestorListener() {
JFileChooserState state = result;
public void ancestorAdded(AncestorEvent e) {
state.grab((JFileChooser)e.getSource());
}
public void ancestorMoved(AncestorEvent e) {
state.grab((JFileChooser)e.getSource());
}
public void ancestorRemoved(AncestorEvent e) {
state.grab((JFileChooser)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JFileChooser.class;}
});
// ----- JToolBar
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JToolBar jtb = (JToolBar)o;
final JToolBarState result = preferences == null ? new JToolBarState(jtb) : (JToolBarState)preferences;
if(preferences != null) result.apply(jtb);
if(jtb.getParent() instanceof Container) {
((Container)jtb.getParent()).addContainerListener(new ContainerListener() {
JToolBarState state = result;
public void componentAdded(ContainerEvent e) {
state.grab((JToolBar)e.getChild());
}
public void componentRemoved(ContainerEvent e) {}
});
}
jtb.addAncestorListener(new AncestorListener() {
JToolBarState state = result;
public void ancestorAdded(AncestorEvent e) {}
public void ancestorMoved(AncestorEvent e) {
state.grab((JToolBar)e.getSource());
}
public void ancestorRemoved(AncestorEvent e) {
state.grab((JToolBar)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JToolBar.class;}
});
//------ JTree
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
JTree jt = (JTree)o;
final JTreeState result = preferences == null ? new JTreeState() : (JTreeState)preferences;
if(preferences != null) result.apply(jt);
jt.addTreeExpansionListener(new JTreeSelecter(result));
jt.addPropertyChangeListener(jt.TREE_MODEL_PROPERTY, new PropertyChangeListener() {
JTreeState state = result;
public void propertyChange(PropertyChangeEvent e) {
state.apply((JTree)e.getSource());
}
});
jt.addTreeSelectionListener(new TreeSelectionListener() {
JTreeState state = result;
public void valueChanged(TreeSelectionEvent e) {
state.selection(((JTree)e.getSource()).getSelectionPaths(), (JTree)e.getSource());
}
});
return result;
}
public Class watchedClass() {return JTree.class;}
});
//----- Container
iiuf.util.Preferences.register(new PrefWatcher() {
public Serializable watch(Object o, Serializable preferences) {
chkWatch((Container)o, (Container)o);
return new EmptyState();
}
public Class watchedClass() {return Container.class;}
void chkWatch(Container root, Component cmp) {
if(cmp instanceof JSplitPane ||
cmp instanceof JDesktopPane ||
cmp instanceof JTree ||
cmp instanceof JViewport ||
cmp instanceof JTabbedPane ||
cmp instanceof JTextComponent ||
cmp instanceof ButtonTreePathView ||
cmp instanceof JFileChooser ||
cmp instanceof JToolBar ||
cmp instanceof JInternalFrame)
addWatch(root, cmp);
if(cmp instanceof JTable) {
JTable table = (JTable)cmp;
addWatch(root, table);
iiuf.util.Preferences.watch(table, table.getColumnModel());
if(table.getTableHeader() != null)
table.getTableHeader().repaint();
return;
}
if(cmp instanceof Container) {
Component[] cmps = ((Container)cmp).getComponents();
for(int i = 0; i < cmps.length; i++)
chkWatch(root, cmps[i]);
}
}
void addWatch(Container root, Component cmp) {
if(cmp == root) return;
if(iiuf.util.Preferences.isWatched(cmp)) return;
addWatch(root, cmp.getParent());
iiuf.util.Preferences.watch(cmp);
}
});
}
}
/*
$Log: Preferences.java,v $
Revision 1.1 2002/07/11 12:09:52 ohitz
Initial checkin
Revision 1.20 2001/05/11 11:30:26 schubige
fns demo final
Revision 1.19 2001/04/12 11:40:49 schubige
fixed toolbar preferences bug
Revision 1.18 2001/04/12 11:34:46 schubige
fixed toolbar preferences bug
Revision 1.17 2001/04/12 11:17:31 schubige
fixed toolbar preferences bug
Revision 1.16 2001/04/11 14:17:03 schubige
adapted tinja stuff for semantic checks
Revision 1.15 2001/03/30 17:33:25 schubige
modified beat soundlet
Revision 1.14 2001/03/01 10:42:48 schubige
interim checkin for soundium
Revision 1.13 2001/02/13 14:49:06 schubige
started work on gui - engine connection
Revision 1.12 2001/01/12 08:26:21 schubige
TJGUI update and some TreeView bug fixes
Revision 1.11 2001/01/04 16:28:39 schubige
Header update for 2001 and DIUF
Revision 1.10 2001/01/03 08:30:39 schubige
graph stuff beta
Revision 1.9 2000/12/20 10:49:51 schubige
TJGUI update
Revision 1.8 2000/12/20 10:28:44 schubige
TJGUI update
Revision 1.7 2000/11/29 09:45:42 schubige
tinja IDE beta 3 - added focus hack, fixed preferences deadlock
Revision 1.6 2000/11/27 16:10:45 schubige
tinja IDE beta 2
Revision 1.5 2000/11/24 17:50:44 schubige
Tinja IDE beta 1
Revision 1.4 2000/11/23 15:25:13 schubige
intermediate TJGUI checkin
Revision 1.3 2000/11/23 15:15:06 schubige
intermediate TJGUI checkin
Revision 1.2 2000/11/20 17:36:57 schubige
tinja project ide
Revision 1.1 2000/11/09 07:53:08 schubige
early checkin for DCJava
Revision 1.2 2000/10/19 08:03:45 schubige
Intermediate graph component related checkin
*/