org.jclarion.clarion.runtime.CWinImpl Maven / Gradle / Ivy
/**
* Copyright 2010, by Andrew Barnham
*
* The contents of this file are subject to
* GNU Lesser General Public License (LGPL), v.3
* http://www.gnu.org/licenses/lgpl.txt
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
*/
package org.jclarion.clarion.runtime;
import java.awt.AWTException;
import java.awt.AWTKeyStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyVetoException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JWindow;
import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.EmptyBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jclarion.clarion.AbstractWindowTarget;
import org.jclarion.clarion.ClarionApplication;
import org.jclarion.clarion.ClarionEvent;
import org.jclarion.clarion.ClarionNumber;
import org.jclarion.clarion.ClarionObject;
import org.jclarion.clarion.ClarionQueue;
import org.jclarion.clarion.ClarionRandomAccessFile;
import org.jclarion.clarion.ClarionString;
import org.jclarion.clarion.KeyedClarionEvent;
import org.jclarion.clarion.PropertyObject;
import org.jclarion.clarion.PropertyObjectListener;
import org.jclarion.clarion.control.AbstractControl;
import org.jclarion.clarion.control.ControlIterator;
import org.jclarion.clarion.control.SheetControl;
import org.jclarion.clarion.constants.*;
import org.jclarion.clarion.file.ClarionFileFactory;
import org.jclarion.clarion.file.FilenameFactory;
import org.jclarion.clarion.file.InputStreamWrapper;
import org.jclarion.clarion.memory.CMem;
import org.jclarion.clarion.print.AWTPrintContext;
import org.jclarion.clarion.print.Page;
import org.jclarion.clarion.swing.AWTPause;
import org.jclarion.clarion.swing.ClarionContentPane;
import org.jclarion.clarion.swing.ClarionDesktopPane;
import org.jclarion.clarion.swing.ClarionEventQueue;
import org.jclarion.clarion.swing.ClarionFocusTraversalPolicy;
import org.jclarion.clarion.swing.ClarionLayoutManager;
import org.jclarion.clarion.swing.ClarionLookAndFeel;
import org.jclarion.clarion.swing.ClarionStatusPane;
import org.jclarion.clarion.swing.FramePropertyListener;
import org.jclarion.clarion.swing.MnemonicConfig;
import org.jclarion.clarion.swing.OpenMonitor;
import org.jclarion.clarion.swing.ShadowCanvas;
import org.jclarion.clarion.swing.ShadowGlass;
import org.jclarion.clarion.swing.SwingAccept;
import org.jclarion.clarion.swing.SwingKeyCodes;
import org.jclarion.clarion.swing.WaitingImageObserver;
import org.jclarion.clarion.swing.MnemonicConfig.Mode;
import org.jclarion.clarion.swing.gui.CommandList;
import org.jclarion.clarion.swing.gui.GUIModel;
import org.jclarion.clarion.swing.gui.RemoteWidget;
import org.jclarion.clarion.swing.gui.RemoteTypes;
import org.jclarion.clarion.swing.gui.ResponseRunnable;
import org.jclarion.clarion.util.SharedOutputStream;
public class CWinImpl implements RemoteWidget {
public static Logger log = Logger.getLogger(CWinImpl.class.getName());
private static class WindowStack
{
private LinkedList windows = new LinkedList();
private AbstractWindowTarget target;
private Thread thread;
public String toString()
{
return "WS:["+target+" :: "+windows+"]";
}
}
private ClarionApplication guiApp;
private ClarionApplication svrApp;
private static class Stack
{
private Map threads =new HashMap();
public synchronized WindowStack get(Thread t)
{
WindowStack ws = threads.get(t.getId());
if (ws==null) {
ws=new WindowStack();
ws.thread=t;
threads.put(t.getId(),ws);
}
return ws;
}
public WindowStack get()
{
return get(Thread.currentThread());
}
public String toString()
{
return threads.toString();
}
}
private Stack stack=new Stack();
public CWinImpl()
{
ClarionEventQueue.getInstance().init();
ClarionLookAndFeel.init(System.getProperty("laf"));
}
private long lastLog=0;
public void log(String entry)
{
if (lastLog+5000 di = ws.windows.descendingIterator();
return new AbstractWindowTarget[] { di.next(), di.next() };
}
}
public AbstractWindowTarget getTarget(Thread t)
{
synchronized(stack) {
WindowStack ws = stack.get(t);
return ws.target;
}
}
public ClarionApplication getServerApp()
{
return svrApp;
}
public ClarionApplication getGuiApp()
{
return guiApp;
}
public void open(final AbstractWindowTarget target)
{
WindowStack ws = stack.get();
target.setClarionThread(Thread.currentThread());
synchronized(stack) {
if (ws.target!=null) {
ws.target.setActiveState(false);
}
if (!ws.windows.isEmpty()) {
ws.windows.getLast().setActiveState(false);
}
ws.windows.add(target);
ws.target=target;
stack.notifyAll();
}
if (target instanceof ClarionApplication) {
if (svrApp!=null) {
throw new RuntimeException("Application already open");
}
svrApp=(ClarionApplication)target;
}
open();
target.clearAllEvents();
int event=Event.OPENWINDOW;
if (target.isProperty(Prop.MDI)) {
ClarionApplication ca = getServerApp();
if (ca!=null && !ca.isActive()) {
event=Event.CLOSEDOWN;
}
}
target.post(event);
}
public void shutdown()
{
ClarionApplication ca=getServerApp();
if (ca!=null) ca.post(Event.CLOSEDOWN);
closeApp(false);
}
private void closeApp()
{
closeApp(true);
}
private void closeApp(boolean mdiOnly)
{
AbstractWindowTarget awt;
while ( true ) {
awt=null;
Thread t = null;
WindowStack ws=null;
synchronized(stack) {
for (WindowStack stacks : stack.threads.values() ) {
if (stacks.thread==Thread.currentThread()) continue;
if (!stacks.thread.isAlive()) continue;
if (!stacks.windows.isEmpty()) {
awt=stacks.windows.getLast();
if (mdiOnly && !awt.isProperty(Prop.MDI)) {
awt=null;
} else {
ws=stacks;
if (stacks.windows.size()<=1) {
t=stacks.thread;
}
break;
}
}
}
}
if (awt==null) {
if (t==null) {
if (svrApp!=null) {
Iterator it = svrApp.getThreads().iterator();
if (it.hasNext()) {
t=it.next();
}
}
}
if (t==null) break;
}
if (awt!=null) {
ClarionEvent ce = new ClarionEvent(Event.CLOSEDOWN,null,false);
awt.post(ce);
ce.getConsumeResult();
long until = System.currentTimeMillis()+5000;
synchronized(stack) {
while ( !ws.windows.isEmpty() && ws.windows.getLast()==awt ) {
long wu = until-System.currentTimeMillis();
if (wu<=0) break;
try {
stack.wait(wu);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
if (t!=null) {
try {
t.join(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void programmaticClose(AbstractWindowTarget target)
{
close(target);
closeAcceptLoop(target);
}
public void closeAcceptLoop(AbstractWindowTarget target)
{
WindowStack ws=stack.get();
synchronized(stack) {
if (!ws.windows.isEmpty() && ws.windows.getLast()==target) {
ws.windows.removeLast();
if (ws.windows.isEmpty()) {
ws.target=null;
} else {
ws.target=ws.windows.getLast();
}
}
stack.notifyAll();
}
target.setActiveState(false);
if (target==svrApp) {
svrApp=null;
}
}
public void close(AbstractWindowTarget target)
{
WindowStack ws=stack.get();
synchronized(stack) {
if (ws.windows.isEmpty()) return;
AbstractWindowTarget awt = ws.windows.getLast();
if (awt!=target) return;
ws.target=target;
stack.notifyAll();
}
if (target==svrApp) {
target.setActiveState(false);
closeApp();
}
close();
}
public final boolean accept()
{
return accept((AbstractWindowTarget)getTarget());
}
public final void consumeAccept()
{
consumeAccept((AbstractWindowTarget)getTarget());
}
public void lazyOpen(final AbstractWindowTarget target)
{
OpenMonitor monitor = target.getOpenMonitor();
if (monitor == null) return;
run(this,LAZY_OPEN,target);
monitor.waitForOpen();
target.setOpenMonitor(null);
delay(target);
}
//@Override
public boolean accept(AbstractWindowTarget target) {
if (target == null)
return false;
lazyOpen(target);
target.runAcceptTasks();
ClarionObject timer = target.getRawProperty(Prop.TIMER);
while (true) {
if (target.isClosed()) break;
ClarionEvent cycled = target.consumePendingEvent();
if (cycled != null) {
cycled.consume(false);
if (cycled.getEvent() == Event.CLOSEDOWN) {
close(target);
continue;
// not allowed to cycle a close down event
}
if (cycled.getEvent() == Event.OPENWINDOW) {
close(target);
continue;
}
}
ClarionEvent next = target.getNextEvent(timer == null ? 0 : timer
.intValue());
if (next != null) {
if (next.getEvent() == 0) {
target.consumePendingEvent();
continue;
}
return true;
} else {
target.post(Event.TIMER);
}
}
programmaticClose(target);
return false;
}
public void setDefaultButton(final AbstractWindowTarget parent)
{
if (parent==null) return;
parent.setDefaultButton(null);
}
private void restoreWindow(final AbstractWindowTarget parent)
{
if (parent == null) return;
run(this,RESTORE_WINDOW,parent);
}
protected void close() {
AbstractWindowTarget last2[] = getLast2Targets();
final AbstractWindowTarget target = last2[0];
final AbstractWindowTarget parent = last2[1];
if (target.isClosed()) return;
target.setActiveState(false);
target.setClosed();
runNow(this,CLOSE,parent,target);
run(this,DISPOSE,target);
GUIModel.getClient().dispose(target);
delay(target);
if (parent!=null) {
parent.purgeEvents();
restoreWindow(parent);
}
target.setClarionThread(null);
target.clearMetaData();
target.removeAllListeners();
for (AbstractControl c : target.getControls()) {
clean(c);
}
}
private void delay(AbstractWindowTarget awt)
{
if (!AbstractWindowTarget.suppressWindowSizingEvents) return;
if (awt.getProperty(Prop.MDI).boolValue()) return;
try {
Thread.sleep(500);
} catch (InterruptedException ex) { }
}
private void clean(AbstractControl c) {
c.clearMetaData();
c.removeAllListeners();
for (AbstractControl child : c.getChildren()) {
clean(child);
}
}
//@Override
public void consumeAccept(AbstractWindowTarget target) {
ClarionEvent ev = target.consumePendingEvent();
if (ev == null)
return;
ev.consume(true);
if (ev.getEvent() == Event.OPENWINDOW) {
}
if (ev.getEvent() == Event.CLOSEDOWN) {
close(target);
}
if (ev.getEvent() == Event.ACCEPTED) {
AbstractControl ctl = target.getControl(ev.getField());
if (ctl != null) {
ClarionObject std = ctl.getRawProperty(Prop.STD, false);
if (std != null) {
int istd = std.intValue();
if (istd == Std.CLOSE) {
target.post(Event.CLOSEWINDOW);
}
if (istd == Std.PRINTSETUP) {
CWin.printerDialog(new ClarionString("Printer Setup"),null);
}
}
}
}
if (!ev.isWindowEvent()) {
if (ev.getEvent() == Event.CLOSEWINDOW) {
close(target);
}
}
}
//@Override
public int focus() {
AbstractControl ac = getTarget().getCurrentFocus();
if (ac == null) return 0;
return ac.getUseID();
}
private static class MessageKeyListener implements KeyListener {
private Map buttons = new HashMap();
public void addButton(JButton button, String text) {
int c = text.charAt(0);
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
buttons.put(c, button);
buttons.put(c + 0x400, button);
button.addKeyListener(this);
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
int key = SwingKeyCodes.getInstance().toClarionCode(e);
JButton button = buttons.get(key);
if (button != null) {
button.doClick();
}
}
}
private class MessageFocusTraversalPolicy extends
LayoutFocusTraversalPolicy {
private static final long serialVersionUID = 8392703113661202447L;
private Component def;
public void setDefaultComponent(Component def) {
this.def = def;
}
@Override
public Component getDefaultComponent(Container container) {
if (def != null)
return def;
return super.getDefaultComponent(container);
}
}
private void addButton(JRootPane pane, JPanel panel, int button, int def,
int code, String name, Action a, MessageKeyListener listener) {
if ((button & code) != code)
return;
final JButton b;
b=new JButton(a);
b.setText(name);
b.setDisplayedMnemonicIndex(0);
listener.addButton(b, name);
panel.add(b);
b.setActionCommand(String.valueOf(code));
if (def == code) {
((MessageFocusTraversalPolicy) pane.getFocusCycleRootAncestor()
.getFocusTraversalPolicy()).setDefaultComponent(b);
}
b.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()=='\n' && e.getModifiersEx()==0) {
b.doClick();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
});
Set forward = new HashSet();
forward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_RIGHT, 0));
forward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_DOWN, 0));
forward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0));
b.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
forward);
Set backward = new HashSet();
backward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_LEFT, 0));
backward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_UP, 0));
backward.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
KeyEvent.SHIFT_DOWN_MASK));
b.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
backward);
}
private static class MessageAction extends AbstractAction {
private static final long serialVersionUID = -7756388166603189307L;
private JDialog dialog;
private MessageOutcome outcome;
public MessageAction(JDialog dialog,MessageOutcome outcome) {
this.dialog = dialog;
this.outcome=outcome;
}
@Override
public void actionPerformed(ActionEvent e) {
final int result = Integer.parseInt(e.getActionCommand());
outcome.setOutcome(result);
dialog.dispose();
}
}
private int getSize(Component c)
{
if (c==null) return 0;
return c.getY()+c.getHeight();
}
private static class MessageOutcome
{
private boolean finish=false;
private int outcome=0;
public void setOutcome(int outcome)
{
synchronized(this) {
finish=true;
this.outcome=outcome;
this.notifyAll();
}
}
public int getOutcome()
{
synchronized(this) {
while (!finish) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return outcome;
}
}
}
//@Override
public int message(final ClarionString message,final ClarionString header,
final String icon,final int button,final int defButton,final int style) {
AbstractWindowTarget target = CWin.getWindowTarget();
if (target!=null) {
target.setActiveState(false);
}
int r = (Integer)runNow(this,MESSAGE,
message==null ? null : message.toString(),
header==null ? null :
header.toString(),icon,button,defButton,style);
if (target!=null) {
target.setActiveState(true);
}
return r;
}
private class Root {
private Frame frame;
private Dialog dialog;
private Frame holdingFrame;
}
private Root getRoot() {
return getRoot(getLast2Targets()[1]);
}
private Root getRoot(AbstractWindowTarget parent) {
Root r = new Root();
if (parent != null) {
Component c = (Component) parent.getWindow();
if (c instanceof Dialog) {
r.dialog = (Dialog) c;
}
if (c instanceof Frame) {
r.frame = (Frame) c;
}
}
if (r.frame == null && r.dialog == null) {
ClarionApplication base = getGuiApp();
if (base != null) {
r.frame = (Frame) base.getWindow();
}
if (r.frame == null) {
r.frame = new JFrame();
r.holdingFrame=r.frame;
}
}
return r;
}
public static void run(final RemoteWidget w,final int command,final Object ...params)
{
GUIModel.getClient().send(w,command,params);
}
public static void run(final RemoteWidget w,final ResponseRunnable nextTask,final int command,final Object ...params)
{
GUIModel.getClient().send(w,nextTask,command,params);
}
public static Object runNow(final RemoteWidget w,final int command,final Object ...params)
{
return GUIModel.getClient().sendRecv(w,command,params);
}
private Color desktopColor= new Color(0xc0c0c0);
private Map fontStats = new HashMap();
//@Override
protected void open() {
AbstractWindowTarget last2[] = getLast2Targets();
final AbstractWindowTarget target = last2[0];
final AbstractWindowTarget parent = last2[1];
final OpenMonitor monitor = new OpenMonitor();
target.setOpenMonitor(monitor);
if (target.isProperty(Prop.MDI) && getServerApp()==null) {
target.setProperty(Prop.MDI,0);
}
target.opened();
runNow(this,OPEN,target,parent,monitor);
}
private void setupContainer(Container win) {
win.setLayout(new ClarionLayoutManager());
}
public void createControl(AbstractControl ac, Container parent)
{
ac.constructSwingComponent(parent);
}
private boolean isActionKey(KeyEvent e)
{
if ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK)!=0) return true;
if (e.getKeyChar()!=KeyEvent.CHAR_UNDEFINED) {
if (e.getKeyChar()=='\n') return true;
return false;
} else {
if (e.getKeyCode()=='\n' && e.getModifiersEx()==0) return true;
return e.isActionKey();
}
}
public void setKey(final AbstractWindowTarget ctl, final Component comp,
final boolean allowSimple, final boolean postAlways,
final AbstractControl start)
{
comp.addKeyListener(new KeyListener() {
public void handleEvent(KeyEvent e) {
SwingKeyCodes skc = SwingKeyCodes.getInstance();
int key = skc.toClarionCode(e);
int keyChar = skc.toClarionChar(e);
int state = skc.toClarionState(e);
// following is unnecessary (i think) and will not work in network mode
ctl.setKeyCode(key);
ctl.setKeyState(state);
ctl.setKeyChar(keyChar);
// end of unnecessary code
if (e.isConsumed()) return;
if (e.getKeyCode()==KeyEvent.VK_F2 && (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK)!=0) {
new org.jclarion.clarion.swing.winedit.EditTool(ctl);
e.consume();
return;
}
if (e.getKeyCode()==KeyEvent.VK_F3 && (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK)!=0) {
org.jclarion.clarion.crash.Crash.getInstance().crashDetailed();
e.consume();
return;
}
boolean alert = false;
AbstractControl atarget = null;
if (start != null && start.isAlertKey(key)) {
alert = true;
atarget = start;
}
if (!alert) {
if (ctl.isAlertKey(key)) {
alert = true;
}
}
if (alert) {
KeyedClarionEvent kce;
kce = new KeyedClarionEvent(
Event.PREALERTKEY,atarget,true,key,keyChar,state);
kce.setNetworkSemaphore(true);
ctl.post(kce);
if (!kce.getConsumeResult()) {
} else {
e.consume();
}
kce = new KeyedClarionEvent(
Event.ALERTKEY,atarget,true,key,keyChar,state);
ctl.post(kce);
return;
}
// check for hot keys
if (handleMnemonic(e)) return;
// check for other specials
if (e.getKeyChar() == 27) {
e.consume();
ctl.post(Event.CLOSEWINDOW);
return;
}
if (postAlways) {
if (isActionKey(e)) return;
e.consume();
// clarion doco says it is NEWSELECTION, but
// test 5.5 code actually generates alert key events
KeyedClarionEvent kce = new KeyedClarionEvent(
Event.ALERTKEY,start,true,key,keyChar,state);
ctl.post(kce);
}
}
private boolean handleMnemonic(KeyEvent e) {
MnemonicConfig md = getMnemonic(ctl, false);
if (md == null) return false;
int mkey = SwingKeyCodes.getInstance().toClarionCode(e);
if ( (mkey >= 'A' && mkey <= 'Z') || (mkey>='0' && mkey <= '9')) {
if (!allowSimple) return false;
}
if (!md.isKeyOfInterest(mkey)) {
return false;
}
ControlIterator ci = null;
if (start != null) {
ci = new ControlIterator(start, false);
} else {
ci = new ControlIterator(ctl);
}
while (ci.hasNext()) {
AbstractControl candidate = ci.next();
MnemonicConfig.Entry entry = md.match(candidate, mkey);
if (entry != null) {
if (entry.offset > 0) {
ControlIterator si = new ControlIterator(candidate,
false);
si.setScanSheets(true);
for (int scan = 0; scan < entry.offset; scan++) {
candidate = si.next();
}
}
if (candidate != null) {
if (entry.mode == Mode.SELECTONLY) {
select(candidate);
} else {
selectAndAccept(candidate);
}
e.consume();
return true;
}
}
}
return false;
}
public void keyPressed(KeyEvent e)
{
if (isActionKey(e)) {
handleEvent(e);
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
if (!isActionKey(e)) {
handleEvent(e);
}
}
});
setMouseAlerts(start, comp);
}
private void setMouseAlerts(final AbstractControl control, final Component c) {
if (control == null)
return;
registerMouseAlerts(control, c);
control.addListener(new PropertyObjectListener() {
@Override
public Object getProperty(PropertyObject owner, int property) {
return null;
}
@Override
public void propertyChanged(PropertyObject owner, int property,
ClarionObject value) {
if (property == Prop.ALRT) {
registerMouseAlerts(control, c);
}
}
});
}
private void registerMouseAlerts(final AbstractControl control,
final Component c)
{
if (!control.isMouseAlert()) return;
if (control.isMouseAlertsEnabled()) return;
control.setMouseAlertsEnabled(true);
MouseListener ml = new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
int code = 0;
switch (e.getClickCount()) {
case 1:
switch (e.getButton()) {
case MouseEvent.BUTTON1:
code = Constants.MOUSELEFT;
break;
case MouseEvent.BUTTON2:
code = Constants.MOUSECENTER;
break;
case MouseEvent.BUTTON3:
code = Constants.MOUSERIGHT;
break;
}
break;
case 2:
switch (e.getButton()) {
case MouseEvent.BUTTON1:
code = Constants.MOUSELEFT2;
break;
case MouseEvent.BUTTON2:
code = Constants.MOUSECENTER2;
break;
case MouseEvent.BUTTON3:
code = Constants.MOUSERIGHT2;
break;
}
break;
}
if (code == 0)
return;
if (control.isAlertKey(code)) {
KeyedClarionEvent k = new KeyedClarionEvent(Event.PREALERTKEY,control,true,code,0,0);
k.setNetworkSemaphore(true);
control.getWindowOwner().post(k);
if (k.getConsumeResult()) {
e.consume();
}
GUIModel.getServer().dispose(k);
k = new KeyedClarionEvent(Event.ALERTKEY,control,true,code,0,0);
control.getWindowOwner().post(k);
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
};
c.addMouseListener(ml);
}
public void select(int control) {
select(getTarget().getControl(control));
}
private static class SelectProcess implements Runnable
{
private AbstractControl control;
public SelectProcess(AbstractControl control)
{
this.control=control;
}
public void run()
{
doScanLoop(control);
}
private void doScanLoop(AbstractControl sheet,int pos)
{
if (sheet==null || sheet.getProperty(Prop.SELSTART).intValue() != pos) return;
doScanLoop(sheet);
}
private void doScanLoop(AbstractControl scan)
{
AbstractControl last=null;
while (scan != null) {
if (scan instanceof SheetControl) {
if (last != null) {
final int pos = scan.getChildIndex(last) + 1;
int cpos = scan.getProperty(Prop.SELSTART).intValue();
if (cpos != pos) {
final SheetControl sc = (SheetControl)scan;
sc.forceUpdate();
sc.changeValue(pos,new Runnable() {
@Override
public void run() {
doScanLoop(sc,pos);
} });
return;
}
}
}
last = scan;
scan = scan.getParent();
}
control.select();
}
}
public void select(final AbstractControl control)
{
AbstractWindowTarget awt = control.getWindowOwner();
if (awt.getOpenMonitor()!=null) {
awt.setInitialSelectControl(control);
}
(new SelectProcess(control)).run();
}
//@Override
public void selectAndAccept(AbstractControl control) {
final AbstractControl prior = control.getWindowOwner().getCurrentFocus();
if (prior != null) {
SwingAccept a = prior.getAccept();
if (a != null) {
if (!a.accept(false)) return;
}
}
control.accept();
}
public void configureColor(JWindow jw, PropertyObject target) {
Color c;
c = getColor(target, Prop.FONTCOLOR);
if (c != null)
jw.setForeground(c);
c = getColor(target, Prop.BACKGROUND);
if (c != null)
jw.setBackground(c);
}
public void configureColor(JDialog jw, PropertyObject target) {
Color c;
c = getColor(target, Prop.FONTCOLOR);
if (c != null)
jw.setForeground(c);
c = getColor(target, Prop.BACKGROUND);
if (c != null)
jw.setBackground(c);
}
public void configureColor(JComponent jw, PropertyObject target) {
Color c;
c = getColor(target, Prop.FONTCOLOR);
if (c != null)
jw.setForeground(c);
c = getColor(target, Prop.BACKGROUND);
if (c != null)
jw.setBackground(c);
}
public Color getColor(PropertyObject object, int property) {
return getColor(object.getRawProperty(property));
}
public Color getNestedColor(PropertyObject object, int property) {
while ( object!=null ) {
Color c = getColor(object,property);
if (c!=null) return c;
object=object.getParentPropertyObject();
}
return null;
}
public Color getColor(ClarionObject color) {
if (color == null)
return null;
int val = color.intValue();
return getColor(val);
}
public static Color getUIColor(String... colors)
{
for (int scan=0;scan> 0) & 0xff) << 16) + (((val >> 8) & 0xff) << 8)
+ (((val >> 16) & 0xff) << 0);
return new Color(rval);
}
public void configureFont(final Component component, final PropertyObject o) {
o.addListener(new PropertyObjectListener() {
@Override
public Object getProperty(PropertyObject owner, int property) {
return null;
}
@Override
public void propertyChanged(PropertyObject owner, int property,
ClarionObject value) {
switch (property) {
case Prop.FONTNAME:
case Prop.FONTSIZE:
case Prop.FONTSTYLE:
changeFont(component, o);
}
}
});
changeFont(component, o);
}
public void changeFont(final Component component, final PropertyObject o) {
Font f= getFontOnly(component,o);
if (f!=null) {
component.setFont(f);
}
}
private static double fontResize;
static {
//fontResize="gnome".equals(System.getProperty("sun.desktop"))?1.5:1.0;
fontResize=1.4;
String fr = System.getProperty("clarion.fontsize");
if (fr!=null) {
fontResize=Double.valueOf(fr);
}
};
public Font getFontOnly(final Component component, final PropertyObject o) {
return getFontOnly(component,o,fontResize);
}
public Font getFontOnly(final Component component, final PropertyObject o,double scale) {
Font f = null;
if (component!=null) f = component.getFont();
ClarionObject p_face = o.getInheritedProperty(Prop.FONTNAME);
ClarionObject p_size = o.getInheritedProperty(Prop.FONTSIZE);
ClarionObject p_style = o.getInheritedProperty(Prop.FONTSTYLE);
if (p_face == null && p_size == null && p_style == null)
return null;
String face = null;
int size = 0;
int style = 0;
if (p_face != null) {
face = p_face.toString();
} else if (f!=null) {
face = f.getFontName();
} else {
face="Monospaced";
}
if (p_size != null) {
size = (int) (p_size.intValue() * scale );
} else if (f!=null) {
size = f.getSize();
} else {
size=(int)(10*scale);
}
if (p_style != null) {
int cl_style = p_style.intValue();
style = 0;
if ((cl_style & org.jclarion.clarion.constants.Font.BOLD) == org.jclarion.clarion.constants.Font.BOLD)
style |= Font.BOLD;
if ((cl_style & org.jclarion.clarion.constants.Font.ITALIC) == org.jclarion.clarion.constants.Font.ITALIC)
style |= Font.ITALIC;
} else if (f!=null) {
style = f.getStyle();
} else {
style = Font.PLAIN;
}
face = convertFace(face);
Font nf = new Font(face, style, size);
return nf;
}
boolean logged = false;
private Map fontFaces;
public String convertFace(String face) {
if (fontFaces==null) {
fontFaces=new HashMap();
Font fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font font : fonts ) {
fontFaces.put(font.getFontName().toLowerCase().trim(),font.getFontName());
}
}
String oface=face;
face = face.toLowerCase();
if (face.equals("ms sans serif")) face="microsoft sans serif";
String result = fontFaces.get(face.trim().toLowerCase());
if (result!=null) return result;
while ( true ) {
if (face.indexOf("sans") > -1 && face.indexOf("serif") > -1) {
result="SansSerif";
break;
}
if (face.indexOf("sans") > -1) {
result="Sans";
break;
}
if (face.indexOf("serif") > -1) {
result="Serif";
break;
}
if (face.indexOf("courier") > -1) {
result="Monospaced";
break;
}
result=oface;
break;
}
log.warning("Font Unknown :"+oface+" using: "+result);
fontFaces.put(face,result);
return result;
}
public static Point toPixels(AbstractWindowTarget win, int x, int y) {
Point p = new Point(x, y);
return toPixels(win, p);
}
public static Point toPixels(AbstractWindowTarget win, Point p) {
p.x = win.widthDialogToPixels(p.x);
p.y = win.heightDialogToPixels(p.y);
return p;
}
public static Point toPixels(AbstractControl c, Point p) {
return toPixels(c.getWindowOwner(), p);
}
public void post(AbstractWindowTarget awt, int event,AbstractControl field) {
awt.post(new ClarionEvent(event, field, true));
}
public void postAsUser(AbstractWindowTarget awt, int event,AbstractControl field) {
awt.post(new ClarionEvent(event, field, false));
}
public boolean postAndWait(AbstractWindowTarget awt, int event,AbstractControl field) {
ClarionEvent ce = new ClarionEvent(event, field, true);
awt.post(ce);
return ce.getConsumeResult();
}
public MnemonicConfig getMnemonic(AbstractWindowTarget po, boolean create)
{
return po.getMnemonic(create);
}
private Map cursorMap;
//@Override
public void setCursor(String cursor) {
if (cursorMap == null) {
cursorMap = new HashMap();
cursorMap.put("\u00ff\u0001\u0001\u007f", null);
cursorMap.put("\u00ff\u0001\u0002\u007f", Cursor.TEXT_CURSOR);
cursorMap.put("\u00ff\u0001\u0003\u007f", Cursor.WAIT_CURSOR);
cursorMap.put("\u00ff\u0001\u0004\u007f", Cursor.CROSSHAIR_CURSOR);
// cursorMap.put("\u00ff\u0001\u0005\u007f",Cursor.???); // up arrow
cursorMap.put("\u00ff\u0001\u0081\u007f", Cursor.MOVE_CURSOR);
// cursorMap.put("\u00ff\u0001\u0082\u007f",Cursor.CUSTOM_CURSOR);
// // icon
cursorMap.put("\u00ff\u0001\u0083\u007f", Cursor.NW_RESIZE_CURSOR); // SIZE
// NW
// +
// SE
cursorMap.put("\u00ff\u0001\u0084\u007f", Cursor.NE_RESIZE_CURSOR); // SIZE
// NE
// +
// SW
cursorMap.put("\u00ff\u0001\u0085\u007f", Cursor.E_RESIZE_CURSOR); // SIZE
// W
// +
// E
cursorMap.put("\u00ff\u0001\u0086\u007f", Cursor.N_RESIZE_CURSOR); // SIZE
// N
// +
// S
cursorMap.put("\u00ff\u0002\u0001\u007f", Cursor.MOVE_CURSOR); // drag
// cursorMap.put("\u00ff\u0002\u0002\u007f",Cursor.???); // drop
cursorMap.put("\u00ff\u0002\u0003\u007f", Cursor.HAND_CURSOR); // no
// drop
// cursorMap.put("\u00ff\u0002\u0004\u007f",Cursor.???); // zoom
}
Cursor c = null;
if (cursor != null) {
Integer id = cursorMap.get(cursor);
if (id != null) {
c = Cursor.getPredefinedCursor(id.intValue());
}
}
AbstractWindowTarget target = getTarget();
if (target!=null) {
Container con = (Container)target.getWindow();
if (con!=null) con.setCursor(c);
}
}
public java.awt.Image getImageFromBinaryData(ClarionObject content)
{
CMem sos = CMem.create();
content.serialize(sos);
byte[] buffer = new byte[sos.getSize()];
sos.readBytes(buffer,0,buffer.length);
return Toolkit.getDefaultToolkit().createImage(buffer);
}
public Object imgSendRecv(int command,Object... params)
{
AWTPause pause=new AWTPause();
GUIModel.getServer().send(this,pause,command,params);
return pause.getResult();
//return GUIModel.getServer().sendRecv(this,command,params);
}
public java.awt.Image getImage(String name, int prefx, int prefy)
{
if (name.startsWith("print:/")) {
name=name.trim();
int scalePos = name.indexOf("#");
int scale=100;
if (scalePos>-1) {
scale=Integer.parseInt(name.trim().substring(scalePos+1));
name=name.substring(0,scalePos);
}
Page p = (Page)imgSendRecv(GET_PAGE,name);
Dimension d = p.getGraphicsSize();
while ( true ) {
try {
BufferedImage bi=null;
bi = new BufferedImage(d.width*scale/100,d.height*scale/100,
Runtime.getRuntime().totalMemory()>32*1048576 ?
BufferedImage.TYPE_3BYTE_BGR : BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = (Graphics2D)bi.getGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0,0,d.width*scale/100,d.height*scale/100);
g2d.scale(scale/100f,scale/100f);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
p.print(new AWTPrintContext(g2d));
return bi;
} catch (OutOfMemoryError ex ) {
scale=scale/2;
}
}
}
String cache = getImageURL(name)+"_p"+prefx+"_p"+prefy;
Image i=getImageFromCache(cache);
if (i!=null) {
return i;
}
if (name.equals(Icon.NONE)) return null;
ClassLoader cl = getClass().getClassLoader();
InputStream is = cl.getResourceAsStream(getImageURL(name));
if (is == null) {
cache = (String)imgSendRecv(GET_CACHE_FILE_NAME,name);
if (cache!=null) {
i=getImageFromCache(cache);
if (i!=null) return i;
}
is = (InputStream)imgSendRecv(GET_FILE,name);
}
if (is==null) {
Long lm = ClarionFileFactory.getInstance().getClientOnly().lastModified(name);
cache = lm==null || lm==0 ? null : name+"_"+cache;
if (cache!=null) {
i=getImageFromCache(cache);
if (i!=null) return i;
}
try {
ClarionRandomAccessFile caf = ClarionFileFactory.getInstance().getClientOnly().getRandomAccessFile(name);
if (caf!=null) is = new InputStreamWrapper(caf);
} catch (IOException ex) { }
}
if (is==null) {
log.warning("Icon Not Found!:"+name+" ("+getImageURL(name)+")");
return null;
}
i = getMicrosoftIcon(is,name, prefx, prefy);
if (i != null) {
addImagetoCache(cache,i);
return i;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[512];
while (true) {
try {
int count = is.read(buffer);
if (count == -1)
break;
baos.write(buffer, 0, count);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
i=Toolkit.getDefaultToolkit().createImage(baos.toByteArray());
addImagetoCache(cache,i);
return i;
}
private Map imageCache=new HashMap();
private void addImagetoCache(String cache, Image i) {
imageCache.put(cache,i);
}
private Image getImageFromCache(String cache) {
return imageCache.get(cache);
}
public javax.swing.ImageIcon getIcon(String name, int prefx, int prefy)
{
if (name.equals(Icon.NONE)) return null;
Image i = getImage(name,prefx,prefy);
if (i==null) return null;
return new ImageIcon(i);
}
public javax.swing.ImageIcon scale(javax.swing.ImageIcon icon,String name,int sx,
int sy)
{
if (icon==null) return null;
BufferedImage bi = scale(icon.getImage(),name,sx,sy);
if (bi!=null) return new ImageIcon(bi);
return null;
}
public BufferedImage scale(java.awt.Image bi, String name,int sx, int sy) {
if (bi == null) return null;
name=getImageURL(name)+"_sx"+sx+"_sy"+sy;
BufferedImage cache = (BufferedImage)getImageFromCache(name);
if (cache!=null) return cache;
BufferedImage scale = scale(bi,sx,sy);
addImagetoCache(name,scale);
return scale;
}
public BufferedImage scale(java.awt.Image bi,int sx, int sy) {
if (bi == null) return null;
Image i = bi.getScaledInstance(sx, sy, Image.SCALE_AREA_AVERAGING);
BufferedImage scale = new BufferedImage(sx, sy,
BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = scale.createGraphics();
WaitingImageObserver wio=new WaitingImageObserver();
if (!g.drawImage(i, 0, 0, wio)) {
if (!wio.waitTillDone()) {
log.warning("Problem scaling image");
}
g.drawImage(i, 0, 0,null);
}
return scale;
}
private java.awt.Image getMicrosoftIcon(InputStream is,String name, int prefx, int prefy) {
name=name.toLowerCase();
if (name.endsWith(".bmp")) {
try {
return net.sf.image4j.codec.bmp.BMPDecoder.read(is);
} catch (IOException e) {
e.printStackTrace();
}
}
if (name.endsWith(".ico")) {
java.util.List bits;
try {
bits = net.sf.image4j.codec.ico.ICODecoder.read(is);
int sel = 0;
int best = Integer.MAX_VALUE;
if (prefx > 0 && prefy > 0) {
for (int scan = 0; scan < bits.size(); scan++) {
BufferedImage bi = bits.get(scan);
int matchx = bi.getWidth() - prefx;
int matchy = bi.getHeight() - prefy;
int match = matchx * matchx + matchy * matchy;
if (match < best) {
sel = scan;
best = match;
}
}
}
BufferedImage bi = bits.get(sel);
return bi;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private static Map clarionIcons;
static {
clarionIcons = new HashMap();
clarionIcons.put(Icon.APPLICATION, "resources/images/clarion/application.png");
clarionIcons.put(Icon.HAND, "resources/images/clarion/hand.png");
clarionIcons.put(Icon.QUESTION, "resources/images/clarion/question.png");
clarionIcons.put(Icon.EXCLAMATION, "resources/images/clarion/exclamation.png");
clarionIcons.put(Icon.ASTERISK, "resources/images/clarion/asterisk.png");
clarionIcons.put(Icon.PICK, "resources/images/clarion/pick.png");
clarionIcons.put(Icon.SAVE, "resources/images/clarion/save.png");
clarionIcons.put(Icon.PRINT, "resources/images/clarion/print.png");
clarionIcons.put(Icon.PASTE, "resources/images/clarion/paste.png");
clarionIcons.put(Icon.OPEN, "resources/images/clarion/open.png");
clarionIcons.put(Icon.NEW, "resources/images/clarion/new.png");
clarionIcons.put(Icon.HELP, "resources/images/clarion/help.png");
clarionIcons.put(Icon.CUT, "resources/images/clarion/cut.png");
clarionIcons.put(Icon.COPY, "resources/images/clarion/copy.png");
clarionIcons.put(Icon.ZOOM, "resources/images/clarion/zoom.png");
clarionIcons.put(Icon.NEXTPAGE, "resources/images/clarion/nextpage.png");
clarionIcons.put(Icon.PREVPAGE, "resources/images/clarion/prevpage.png");
clarionIcons.put(Icon.JUMPPAGE, "resources/images/clarion/jumppage.png");
clarionIcons.put(Icon.TICK, "resources/images/clarion/tick.png");
clarionIcons.put(Icon.CROSS, "resources/images/clarion/cross.png");
clarionIcons.put(Icon.CONNECT, "resources/images/clarion/connect.png");
clarionIcons.put(Icon.PRINT1, "resources/images/clarion/print1.png");
clarionIcons.put(Icon.ELLIPSIS, "resources/images/clarion/ellipsis.png");
clarionIcons.put(Icon.VCRTOP, "resources/images/clarion/vcrtop.png");
clarionIcons.put(Icon.VCRREWIND, "resources/images/clarion/vcrrewind.png");
clarionIcons.put(Icon.VCRPLAY, "resources/images/clarion/vcrplay.png");
clarionIcons.put(Icon.VCRBACK, "resources/images/clarion/vcrback.png");
clarionIcons.put(Icon.VCRFASTFORWARD,
"resources/images/clarion/vcrfastforward.png");
clarionIcons.put(Icon.VCRBOTTOM, "resources/images/clarion/vcrbottom.png");
}
public String getImageURL(String name) {
String result = clarionIcons.get(name);
if (result != null) {
return result;
}
if (name.startsWith("memory:")) return name;
name = name.toLowerCase();
name=name.trim();
int pos = name.lastIndexOf('/') + 1;
int pos2 = name.lastIndexOf('\\') + 1;
if (pos2 > pos)
pos = pos2;
return "resources/images/" + name.substring(pos);
}
public void debugStack() {
log.info(stack.toString());
}
@Override
public CommandList getCommandList() {
return CommandList.create()
.add("FILE_DIALOG",FILE_DIALOG)
.add("LAZY_OPEN",LAZY_OPEN)
.add("RESTORE_WINDOW",RESTORE_WINDOW)
.add("MESSAGE",MESSAGE)
.add("OPEN",OPEN)
.add("CLOSE",CLOSE)
.add("SERVER_CLOSE",SERVER_CLOSE)
.add("PLAYBACK",PLAYBACK)
.add("RECORD",RECORD)
.add("GET_CACHE_FILE_NAME",GET_CACHE_FILE_NAME)
.add("GET_FILE",GET_FILE)
.add("GET_PAGE",GET_PAGE)
.add("DISPOSE",DISPOSE)
;
}
public static final int FILE_DIALOG=1;
public static final int LAZY_OPEN=2;
public static final int RESTORE_WINDOW=4;
public static final int MESSAGE=5;
public static final int OPEN=6;
public static final int CLOSE=7;
public static final int SERVER_CLOSE=8;
public static final int PLAYBACK=9;
public static final int RECORD=10;
public static final int GET_CACHE_FILE_NAME=11;
public static final int GET_FILE=12;
public static final int GET_PAGE=13;
public static final int DISPOSE=14;
@Override
public boolean isGuiCommand(int command)
{
return true;
}
@Override
public boolean isModalCommand(int command)
{
switch(command) {
case OPEN:
//case LAZY_OPEN:
case CLOSE:
case FILE_DIALOG:
case MESSAGE:
return true;
}
return false;
}
@Override
public Object command(int command, Object... params) {
switch(command) {
case GET_PAGE: {
String name = (String)params[0];
int page = Integer.parseInt(name.substring(7));
Page p = (Page)CMemory.resolveAddress(page);
return p;
}
case GET_CACHE_FILE_NAME: {
String name = (String)params[0];
ClassLoader cl = getClass().getClassLoader();
InputStream is = cl.getResourceAsStream(getImageURL(name));
if (is!=null) return name;
Long lastModified=ClarionFileFactory.getInstance().getServerOnly().lastModified(name);
return lastModified==null || lastModified==0 ? null : name+"_"+lastModified;
}
case GET_FILE: {
String name = (String)params[0];
ClassLoader cl = getClass().getClassLoader();
InputStream is = cl.getResourceAsStream(getImageURL(name));
if (is!=null) return is;
try {
ClarionRandomAccessFile f = ClarionFileFactory.getInstance().getServerOnly().getRandomAccessFile(name.trim());
if (f==null) return null;
SharedOutputStream sos = new SharedOutputStream();
sos.readAll(new InputStreamWrapper(f));
f.close();
return sos.getInputStream();
} catch (IOException ex) {
return null;
}
}
case FILE_DIALOG: {
boolean result=doFileDialog((String)params[0],(String)params[1],
(ClarionString)params[2],(String)params[3],(Integer)params[4]);
return new Object[] { result,(ClarionString)params[2] };
}
case MESSAGE: {
return doMessageBox((String)params[0],(String)params[1],(String)params[2],
(Integer)params[3],(Integer)params[4],(Integer)params[5]);
}
case OPEN: {
doOpen((AbstractWindowTarget)params[0],(AbstractWindowTarget)params[1],(OpenMonitor)params[2]);
return null;
}
case PLAYBACK:
ClarionEventQueue.getInstance().setRecordState(false,"Playback");
return null;
case RECORD:
ClarionEventQueue.getInstance().setRecordState(false,"Playback");
return null;
case DISPOSE: {
AbstractWindowTarget target = (AbstractWindowTarget)params[0];
GUIModel.getServer().dispose(target);
return null;
}
case CLOSE: {
AbstractWindowTarget parent = (AbstractWindowTarget)params[0];
AbstractWindowTarget target = (AbstractWindowTarget)params[1];
target.setGuiActive(false);
if (parent!=null) {
parent.setGuiActive(true);
} else {
ClarionEventQueue.getInstance().setRecordState(false,"Thread finished");
}
int x = target.getProperty(Prop.XPOS).intValue();
int y = target.getProperty(Prop.YPOS).intValue();
int wi = target.getProperty(Prop.WIDTH).intValue();
int he = target.getProperty(Prop.HEIGHT).intValue();
int max = target.getProperty(Prop.MAXIMIZE).intValue();
Component w = (Component) target.getWindow();
if (w != null) {
if (w instanceof Window) {
((Window) w).dispose();
} else {
((JInternalFrame) w).dispose();
}
}
if (target.getHoldingFrame()!=null) {
target.getHoldingFrame().dispose();
}
target.clearMetaData();
target.removeAllListeners();
for (AbstractControl c : target.getControls()) {
clean(c);
}
target.setProperty(Prop.XPOS,x);
target.setProperty(Prop.YPOS,y);
target.setProperty(Prop.WIDTH,wi);
target.setProperty(Prop.HEIGHT,he);
target.setProperty(Prop.MAXIMIZE,max);
return null;
}
case RESTORE_WINDOW: {
final AbstractWindowTarget parent = (AbstractWindowTarget)params[0];
if (parent==null) return null;
if (parent.getShadow()==null) return null;
final JDesktopPane desktopPane = getGuiApp().getDesktopPane();
Component shadow = parent.getShadow();
JInternalFrame window = (JInternalFrame) parent.getWindow();
window.putClientProperty("shadow",null);
window.removeVetoableChangeListener(FramePropertyListener.getInstance());
window.getGlassPane().setVisible(false);
desktopPane.remove(shadow);
try {
window.setSelected(true);
} catch (PropertyVetoException e) {
}
parent.setShadow(null);
AbstractControl ac=parent.getCurrentFocus();
setDefaultButton(parent);
if (ac!=null) {
Component t = ac.getComponent();
ClarionFocusTraversalPolicy ftp = (ClarionFocusTraversalPolicy)window.getFocusTraversalPolicy();
if (!ftp.accept(t,null)) {
t=ftp.getComponentAfter(window,t);
}
if (t!=null) {
if (!t.hasFocus()) {
t.requestFocusInWindow();
}
}
}
return null;
}
case LAZY_OPEN: {
final AbstractWindowTarget target = (AbstractWindowTarget)params[0];
final Container c = (Container) target.getWindow();
if (c==null) {
System.out.println("C IS NULL!!!!");
return null;
}
c.addComponentListener(new ComponentListener() {
private Point last_known_location = c.getLocation();
@Override
public void componentHidden(ComponentEvent e) {
}
@Override
public void componentMoved(ComponentEvent e) {
if (!target.isGuiActive()) return;
Point np = e.getComponent().getLocation();
if (np.x == last_known_location.x
&& np.y == last_known_location.y)
return;
last_known_location = np;
target.notifyMoved();
}
@Override
public void componentResized(ComponentEvent e) {
if (!target.isGuiActive()) return;
target.notifySized();
}
@Override
public void componentShown(ComponentEvent e) {
}
});
boolean max =false;
ClarionObject maximize = target.getRawProperty(Prop.MAXIMIZE,false);
if (maximize!=null && maximize.boolValue()) max=true;
if ((c instanceof Frame) && max) {
((Frame) c).setExtendedState(Frame.MAXIMIZED_BOTH);
}
if ((c instanceof JInternalFrame) && max) {
try {
((JInternalFrame) c).setMaximum(true);
} catch (PropertyVetoException e) {
}
}
c.setVisible(true);
return null;
}
}
return null;
}
private int doMessageBox(String message, String header, String icon,
int button, int defButton, int style) {
MessageOutcome outcome = new MessageOutcome();
Root r = getRoot();
final JDialog dialog;
List icons = null;
if (r.dialog != null) {
dialog = new JDialog(r.dialog,true);
icons = r.dialog.getIconImages();
} else {
dialog = new JDialog(r.frame,true);
icons = r.frame.getIconImages();
}
// dialog.setResizable(true);
if (icons != null && !icons.isEmpty()) {
dialog.setIconImage(icons.get(0));
}
dialog.setFocusTraversalPolicy(new MessageFocusTraversalPolicy());
if (header != null) {
dialog.setTitle(header.toString());
}
dialog.setModalityType(ModalityType.APPLICATION_MODAL);
Container c = dialog.getContentPane();
c.setLayout(new BorderLayout(15, 15));
JPanel panel = new JPanel(new ResizingBoxLayout());
Component last = null;
String msg = message.toString().trim();
int len = 0;
while (len < msg.length()) {
int end_n = msg.indexOf('\n', len);
int end_r = msg.indexOf('\r', len);
if (end_n == -1)
end_n = msg.length();
if (end_r == -1)
end_r = msg.length();
String line;
if (end_r + 1 == end_n) {
line = msg.substring(len, end_r);
len = end_n + 1;
} else {
if (end_r < end_n)
end_n = end_r;
line = msg.substring(len, end_n);
len = end_n + 1;
}
boolean first = true;
StringTokenizer words = new StringTokenizer(line, " \t");
if (!words.hasMoreTokens()) {
JLabel label = new JLabel(" ");
label.putClientProperty("newline", Boolean.TRUE);
panel.add(label);
}
while (words.hasMoreTokens()) {
JLabel label = new JLabel(words.nextToken());
if (first) {
label.putClientProperty("newline", Boolean.TRUE);
first = false;
}
panel.add(label);
last = label;
}
}
// c.add(new
// JLabel(message.toString(),JLabel.CENTER),BorderLayout.CENTER);
c.add(panel, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
c.add(buttons, BorderLayout.SOUTH);
MessageAction a = new MessageAction(dialog, outcome);
MessageKeyListener mkl = new MessageKeyListener();
JRootPane root = dialog.getRootPane();
root.setBorder(new EmptyBorder(10, 10, 10, 10));
addButton(root, buttons, button, defButton, Button.OK, "OK", a, mkl);
addButton(root, buttons, button, defButton, Button.YES, "Yes", a, mkl);
addButton(root, buttons, button, defButton, Button.NO, "No", a, mkl);
addButton(root, buttons, button, defButton, Button.ABORT, "Abort", a,
mkl);
addButton(root, buttons, button, defButton, Button.RETRY, "Retry", a,
mkl);
addButton(root, buttons, button, defButton, Button.CANCEL, "Cancel", a,
mkl);
addButton(root, buttons, button, defButton, Button.IGNORE, "Ignore", a,
mkl);
addButton(root, buttons, button, defButton, Button.HELP, "Help", a, mkl);
if (icon != null) {
ImageIcon ii = getIcon(icon, 0, 0);
if (ii != null) {
JLabel img = new JLabel(ii);
c.add(img, BorderLayout.WEST);
}
}
dialog.validate();
dialog.pack();
dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
dialog.validate();
Dimension size = dialog.getSize();
int ils = getSize(last);
int offset = size.height - ils;
if (size.width > size.height * 3) {
int resize = size.width / 2;
while (resize > 0) {
int diff = size.width - size.height * 3;
if (diff < 10 && diff > -10)
break;
if (diff > 0) {
size.width -= resize;
} else {
size.width += resize;
}
dialog.setSize(size);
dialog.validate();
resize = (resize - 1) / 2;
int ls = getSize(last);
size.height = ls + offset;
dialog.setSize(size);
dialog.validate();
size = dialog.getSize();
}
}
Rectangle screen = dialog.getGraphicsConfiguration().getBounds();
dialog.setLocation((screen.width - size.width) / 2,
(screen.height - size.height) / 2);
Object lock=new Object();
ClarionEventQueue.getInstance().setRecordState(false, "enter message",lock);
dialog.setVisible(true);
outcome.getOutcome();
if (r.holdingFrame != null) {
r.holdingFrame.dispose();
}
ClarionEventQueue.getInstance().setRecordState(true, "exit message",lock);
return outcome.getOutcome();
}
private boolean doFileDialog(String path,String title,ClarionString target,String ifiles,int options)
{
File directory=null;
File select=null;
if (!target.equals("")) {
String name = target.toString().trim();
if (!CFile.isAbsolute(name)) name=path+"\\"+name;
select=FilenameFactory.getInstance().getFile(name);
directory=select;
while (directory!=null && !directory.isDirectory()) {
directory=directory.getParentFile();
}
}
if (directory==null) {
directory=FilenameFactory.getInstance().getFile(path);
}
JFileChooser chooser = new JFileChooser(directory, CWin.getView());
chooser.setDialogTitle(title.trim());
if (select!=null && !select.isDirectory()) {
chooser.setSelectedFile(select);
}
String files=ifiles;
if (files == null || files.trim().length() == 0) {
files = "All Files|*.*";
}
StringTokenizer tok = new StringTokenizer(files, "|");
while (tok.hasMoreTokens()) {
final String name = tok.nextToken().trim();
if (!tok.hasMoreTokens())
break;
String pattern = tok.nextToken().trim();
if (pattern.equals("*.*")) {
chooser.addChoosableFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return true;
}
@Override
public String getDescription() {
return name;
}
});
continue;
}
List bits = new ArrayList();
StringTokenizer bits_tok = new StringTokenizer(pattern, ";");
while (bits_tok.hasMoreTokens()) {
String filter = bits_tok.nextToken().trim();
if (!filter.startsWith("*."))
throw new IllegalArgumentException("Filter Invalid");
bits.add(filter.substring(2));
}
chooser.addChoosableFileFilter(new FileNameExtensionFilter(
name, (String[]) bits.toArray(new String[bits
.size()])));
}
if ((options & 1) == 1) {
chooser.setDialogType(JFileChooser.SAVE_DIALOG);
} else {
chooser.setDialogType(JFileChooser.OPEN_DIALOG);
}
if ((options & 4) == 4) {
} else {
// setup open to warn/error if file does not exist
// setup save to warn/error if file does exist
}
if ((options & 8) == 8) {
chooser.setMultiSelectionEnabled(true);
} else {
chooser.setMultiSelectionEnabled(false);
}
if ((options & 64) == 0) { // extension - files or directories
if ((options & 32) == 32) {
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
} else {
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
}
} else {
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
}
int result;
GraphicsConfiguration gc = null;
AbstractWindowTarget parent = CWin.getWindowTarget();
if (parent != null) {
parent.setActiveState(false);
if (getGuiApp() != null) {
gc = ((java.awt.Window) getGuiApp()
.getWindow()).getGraphicsConfiguration();
}
if (parent.getWindow() != null
&& (parent.getWindow() instanceof java.awt.Window)) {
gc = ((java.awt.Window) parent.getWindow())
.getGraphicsConfiguration();
}
}
if (gc == null) {
gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
}
Rectangle r = gc.getBounds();
chooser.setPreferredSize(new Dimension((r.width - r.x) * 2 / 3,
(r.height - r.y) * 2 / 3));
Object lock=new Object();
ClarionEventQueue.getInstance().setRecordState(false,"Entering fileDialog",lock);
if ((options & 1) == 1) {
result = chooser.showSaveDialog(null);
} else {
result = chooser.showOpenDialog(null);
}
ClarionEventQueue.getInstance().setRecordState(true,"Exiting fileDialog",lock);
if (result != JFileChooser.APPROVE_OPTION) {
return false;
}
File pwd = null;
StringBuilder out = new StringBuilder();
if (chooser.isMultiSelectionEnabled()) {
File f[] = chooser.getSelectedFiles();
if (f.length > 0) {
pwd = f[0].getAbsoluteFile();
out.append(f[0].getAbsolutePath());
}
if (f.length > 1) {
for (int scan = 1; scan < f.length; scan++) {
out.append('|');
out.append(f[scan].getName());
}
}
} else {
pwd = chooser.getSelectedFile().getAbsoluteFile();
out.append(chooser.getSelectedFile().getAbsolutePath());
}
target.setValue(out.toString());
if ((options & 2) == 2) {
} else {
if (pwd != null) {
// TODO not implemented
//CFile.pwd = pwd.getParentFile();
}
}
return true;
}
private void doOpen(final AbstractWindowTarget target,final AbstractWindowTarget parent,final OpenMonitor monitor)
{
if (parent!=null) parent.setGuiActive(false);
target.setGuiActive(true);
final Container win;
final Container content;
final JRootPane root;
boolean desktop = false;
if (target instanceof ClarionApplication) {
guiApp=(ClarionApplication)target;
final JFrame frame = new JFrame();
frame.setTitle(target.getProperty(Prop.TEXT).toString());
if (target.isProperty(Prop.ICON)) {
frame.setIconImage(getImage(target.getProperty(Prop.ICON)
.toString(), -1, -1));
}
JDesktopPane dt = new ClarionDesktopPane();
dt.setBackground(desktopColor);
JScrollPane jsp = new JScrollPane(dt);
jsp
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jsp
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
ClarionStatusPane csp = new ClarionStatusPane(target, jsp);
target.setStatusPane(csp);
frame.getContentPane().add(csp);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
if (target.isProperty(Prop.MAXIMIZE)) {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
root = frame.getRootPane();
content = frame.getContentPane();
win = frame;
((ClarionApplication) target).setDesktopPane(dt);
desktop = true;
} else if (target.isProperty(Prop.MDI)) {
final JDesktopPane desktopPane = getGuiApp().getDesktopPane();
if (parent != null && parent.getShadow() == null) {
final JInternalFrame c = (JInternalFrame) parent.getWindow();
JComponent canvas = new ShadowCanvas();
canvas.putClientProperty("shadow", true);
canvas.setSize(c.getSize());
canvas.setLocation(c.getLocation());
// desktopPane.add(canvas);
// desktopPane.moveToFront(canvas);
parent.setShadow(canvas);
c.addVetoableChangeListener(FramePropertyListener.getInstance());
ShadowGlass glass = new ShadowGlass();
c.setGlassPane(glass);
c.putClientProperty("shadow", Boolean.TRUE);
glass.setVisible(true);
}
final JInternalFrame jif = new JInternalFrame();
jif.setClosable(target.isProperty(Prop.SYSTEM));
jif.setMaximizable(target.isProperty(Prop.MAX));
jif.setResizable(target.isProperty(Prop.RESIZE));
// jif.setIconifiable(target.isProperty(Prop.ICON));
if (target.isProperty(Prop.ICON)) {
String icon = target.getProperty(Prop.ICON).toString();
jif.setFrameIcon(scale(getIcon(icon, 16, 16), icon, 16, 16));
}
String title = target.getProperty(Prop.TEXT).toString();
if (title.length() > 0) {
jif.setTitle(title);
} else {
jif.setTitle(null);
}
jif.setVisible(false);
jif.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
root = jif.getRootPane();
content = new ClarionContentPane();
jif.setContentPane(content);
Color bg = getColor(target, Prop.BACKGROUND);
if (bg != null) {
content.setBackground(bg);
}
win = jif;
desktopPane.add(jif);
jif.addInternalFrameListener(new InternalFrameListener() {
@Override
public void internalFrameActivated(InternalFrameEvent e) {
getGuiApp().getStatusPane().setChild(target);
}
@Override
public void internalFrameClosed(InternalFrameEvent e) {
//post(target, 0, null);
getGuiApp().getStatusPane().setChild(parent);
}
@Override
public void internalFrameClosing(InternalFrameEvent e) {
if (jif.getClientProperty("shadow") == null) {
postAsUser(target, Event.CLOSEWINDOW, null);
}
}
@Override
public void internalFrameDeactivated(InternalFrameEvent e) {
getGuiApp().getStatusPane().clearChild(target);
}
@Override
public void internalFrameDeiconified(InternalFrameEvent e) {
}
@Override
public void internalFrameIconified(InternalFrameEvent e) {
}
@Override
public void internalFrameOpened(InternalFrameEvent e) {
target.notifySized();
monitor.setOpened();
getGuiApp().getStatusPane().setChild(target);
}
});
} else {
String text = target.getProperty(Prop.TEXT).toString();
Root r = getRoot(parent);
target.setHoldingFrame(r.holdingFrame);
content = new ClarionContentPane();
Container con;
if (text.length() == 0) {
JWindow jw;
if (r.dialog != null) {
jw = new JWindow(r.dialog);
} else {
jw = new JWindow(r.frame);
}
win = jw;
configureColor(jw, target);
con = jw.getContentPane();
root = jw.getRootPane();
} else {
JDialog jd;
if (r.dialog != null) {
jd = new JDialog(r.dialog, text);
jd.setModalityType(ModalityType.APPLICATION_MODAL);
} else {
jd = new JDialog(r.frame, text);
}
win = jd;
jd
.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
jd.setResizable(target.isProperty(Prop.RESIZE));
con = jd.getContentPane();
configureColor(jd, target);
root = jd.getRootPane();
}
// con.setLayout(new BorderLayout(0,0));
ClarionStatusPane csp = new ClarionStatusPane(target, content);
target.setStatusPane(csp);
con.add(csp);
}
if (win instanceof Window) {
((Window) win).addWindowListener(new WindowListener() {
boolean first = true;
@Override
public void windowActivated(WindowEvent e) {
if (!first) return;
first = false;
Window w = e.getWindow();
if (w instanceof Frame) {
Frame f = (Frame) w;
f.setAlwaysOnTop(true);
f.toFront();
w.setAlwaysOnTop(false);
if (!AbstractWindowTarget.suppressWindowSizingEvents) {
try {
Robot r = new Robot();
Point location = MouseInfo.getPointerInfo()
.getLocation();
Point locationOnScreen = w
.getLocationOnScreen();
r.mouseMove(locationOnScreen.x + 100,
locationOnScreen.y + 10);
r.mousePress(InputEvent.BUTTON1_MASK);
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(location.x, location.y);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
target.notifySized();
monitor.setOpened();
}
});
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
postAsUser(target, Event.CLOSEWINDOW, null);
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowOpened(WindowEvent e) {
e.getWindow().toFront();
}
});
}
if (target.isProperty(Prop.MODAL)) {
if (win instanceof Window) {
((Window) win)
.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
}
}
if (target.getRawProperty(Prop.FONTSTYLE, false) == null) {
target.setProperty(Prop.FONTSTYLE, Font.PLAIN);
}
configureFont(content, target);
Font f = content.getFont();
Dimension fs;
synchronized (fontStats) {
fs = fontStats.get(f);
}
if (fs == null) {
FontMetrics fm = win.getFontMetrics(f);
int fw[] = fm.getWidths();
int wsum = 0;
int wcount = 0;
int width = 0;
for (int scan = 0; scan < fw.length; scan++) {
if (fw[scan] <= 1)
continue;
wsum += fw[scan];
wcount++;
}
width = (wsum + wcount - 1) / wcount;
fs = new Dimension(width, fm.getAscent() + fm.getDescent());
synchronized (fontStats) {
fontStats.put(f, fs);
}
}
target.setFontDimensions(fs.width, fs.height);
Insets ins;
if (win instanceof Window) {
((Window) win).pack();
ins = win.getInsets();
} else {
Component s = content;
int left = 0, right = 0, top = 0, bottom = 0;
while (true) {
left += s.getX();
top += s.getY();
ins = ((Container) s).getInsets();
left += ins.left;
right += ins.right;
top += ins.top;
bottom += ins.bottom;
if (s == win)
break;
s = s.getParent();
}
ins = new Insets(top, left, bottom, right);
}
target.setInsets(ins);
{
ClarionObject x = target.getRawProperty(Prop.XPOS);
ClarionObject y = target.getRawProperty(Prop.YPOS);
if (x == null && parent != null)
x = parent.getProperty(Prop.XPOS).add(10);
if (y == null && parent != null)
y = parent.getProperty(Prop.YPOS).add(10);
if (x != null && y != null) {
win.setLocation(toPixels(target, x.intValue(), y.intValue()));
}
ClarionObject w = target.getRawProperty(Prop.WIDTH);
ClarionObject h = target.getRawProperty(Prop.HEIGHT);
if (w == null || h == null) {
int maxX = 0;
int maxY = 0;
ControlIterator ci = new ControlIterator(target);
ci.setScanDisabled(true);
ci.setScanHidden(true);
ci.setScanSheets(true);
while (ci.hasNext()) {
AbstractControl ac = ci.next();
int sum;
ClarionObject inc;
sum = 0;
inc = ac.getRawProperty(Prop.XPOS, false);
if (inc != null)
sum += inc.intValue();
inc = ac.getRawProperty(Prop.WIDTH, false);
if (inc != null)
sum += inc.intValue();
if (sum > maxX)
maxX = sum;
sum = 0;
inc = ac.getRawProperty(Prop.YPOS, false);
if (inc != null)
sum += inc.intValue();
inc = ac.getRawProperty(Prop.HEIGHT, false);
if (inc != null)
sum += inc.intValue();
if (sum > maxY)
maxY = sum;
}
if (w == null)
w = new ClarionNumber(maxX);
if (h == null)
h = new ClarionNumber(maxY);
}
if (w != null && h != null) {
Point p = toPixels(target, w.intValue(), h.intValue());
p.x += ins.left + ins.right;
p.y += ins.top + ins.bottom;
win.setSize(p.x, p.y);
if (target.isProperty(Prop.CENTER)) {
if (target.isProperty(Prop.MDI)) {
Dimension r = getGuiApp().getDesktopPane().getSize();
win.setLocation((r.width - p.x) / 2,
(r.height - p.y) / 2 - 10);
} else {
Rectangle r = win.getGraphicsConfiguration()
.getBounds();
win.setLocation((r.width - p.x) / 2,
(r.height - p.y) / 2);
}
}
}
}
target.setWindow(win);
target.setRootPane(root);
target.setContentPane(content);
if (!desktop)
setupContainer(content);
win.setFocusTraversalPolicy(new ClarionFocusTraversalPolicy(target));
setKey(target, win, true, false, null);
setKey(target, root, true, false, null);
for (AbstractControl ac : target.getControls()) {
createControl(ac, content);
}
setDefaultButton(target);
}
@Override
public Map getChangedMetaData() {
return null;
}
@Override
public Iterable extends RemoteWidget> getChildWidgets() {
return null;
}
private int id;
@Override
public int getID() {
return id;
}
@Override
public void setID(int id) {
this.id=id;
}
@Override
public void setMetaData(Map data) {
}
@Override
public void disposeWidget() {
this.id=0;
}
@Override
public RemoteWidget getParentWidget()
{
return null;
}
@Override
public int getWidgetType() {
return RemoteTypes.CWIN;
}
@Override
public void addWidget(RemoteWidget child) {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy