Revision 922

View differences:

org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/pom.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3

  
4
	<modelVersion>4.0.0</modelVersion>
5
	<artifactId>org.gvsig.scripting.thing</artifactId>
6
	<packaging>jar</packaging>
7
	<name>${project.artifactId}</name>
8
	<parent>
9
		<groupId>org.gvsig</groupId>
10
		<artifactId>org.gvsig.scripting</artifactId>
11
		<version>2.3.50</version>
12
	</parent>
13
	<dependencies>
14
		<dependency>
15
			<groupId>net.sourceforge.thinlet</groupId>
16
			<artifactId>thinlet</artifactId>
17
			<scope>compile</scope>
18
		</dependency>
19
	</dependencies>
20
</project>
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/package.html
1
<body>
2
<p>
3
This package contains some common gui widgets such as a directory chooser,
4
a font chooser, a generic message dialog box etc.
5
</p>
6

  
7
<p>
8
All widgets are Thinlet widgets.
9
</p>
10

  
11
<p>
12
Note that the <code>thinletcommons</code> package does not depend on the
13
<code>thing</code> package, so these widgets could be used in other
14
applications.
15
</p>
16
</body>
17

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/LoggingThinlet.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.util.logging.Level;
8
import java.util.logging.Logger;
9

  
10
import thinlet.Thinlet;
11

  
12

  
13
/**
14
 * A <code>Thinlet</code> component that logs exceptions to the JDK logging
15
 * facility.
16
 *
17
 * @author Dirk Moebius
18
 */
19
public class LoggingThinlet extends Thinlet
20
{
21

  
22
    //{{{ logging
23
    private static final Logger log = Logger.getLogger("thinletcommons");
24
    private static final boolean debug() { return log.isLoggable(Level.FINE); }
25
    //}}}
26

  
27

  
28
    public LoggingThinlet()
29
    {
30
        super();
31
    }
32

  
33

  
34
    /**
35
     * Log exceptions to a logger named "thinletcommons" with log level SEVERE.
36
     *
37
     * @param throwable the thrown exception by the bussiness logic
38
     */
39
    protected void handleException(Throwable throwable)
40
    {
41
        log.log(Level.SEVERE, "Exception in business logic", throwable);
42
        //throw new RuntimeException("Exception in business logic", throwable);
43
    }
44

  
45

  
46
}
47

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/colorchooser.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!-- jEdit settings: :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: -->
3

  
4
<panel columns="3" top="10" left="10" right="10" bottom="10" gap="4" init="init(sl_red, sl_green, sl_blue, sb_red, sb_green, sb_blue, tf_hue, tf_saturation, tf_brightness, pb_hue, pb_saturation, pb_brightness, rgb_label)">
5
	<label text="Red, green, and blue values" colspan="3" />
6

  
7
	<label text="Red:" alignment="right" for="sb_red" mnemonic="0" />
8
	<slider name="sl_red" minimum="0" maximum="255" valign="center" action="sliderChanged(this.value, sb_red)" />
9
	<spinbox name="sb_red" minimum="0" maximum="255" text="0" columns="3" action="spinboxChanged(this.text, sl_red)" />
10

  
11
	<label text="Green:" alignment="right" for="sb_green" mnemonic="0" />
12
	<slider name="sl_green" minimum="0" maximum="255" valign="center" action="sliderChanged(this.value, sb_green)" />
13
	<spinbox name="sb_green" minimum="0" maximum="255" text="0" columns="3" action="spinboxChanged(this.text, sl_green)" />
14

  
15
	<label text="Blue:" alignment="right" for="sb_blue" mnemonic="0" />
16
	<slider name="sl_blue" minimum="0" maximum="255" valign="center" action="sliderChanged(this.value, sb_blue)" />
17
	<spinbox name="sb_blue" minimum="0" maximum="255" text="0" columns="3" action="spinboxChanged(this.text, sl_blue)" />
18

  
19
	<separator colspan="3" />
20

  
21
	<label text="Hue, saturation, and brightness values" colspan="3" />
22

  
23
	<label text="Hue:" alignment="right" />
24
	<textfield name="tf_hue" text="0.0" editable="false" />
25
	<progressbar name="pb_hue" valign="center" />
26

  
27
	<label text="Saturation:" alignment="right" />
28
	<textfield name="tf_saturation" text="0.0" editable="false" />
29
	<progressbar name="pb_saturation" valign="center" />
30

  
31
	<label text="Brightness:" alignment="right" />
32
	<textfield name="tf_brightness" text="0.0" editable="false" />
33
	<progressbar name="pb_brightness" valign="center" />
34

  
35
	<separator colspan="3"/>
36

  
37
	<label colspan="3" name="rgb_label" valign="fill" weighty="1" background="#000000" text="ThinG!" font="40 bold italic" alignment="center"/>
38

  
39
    <panel colspan="3" gap="10" halign="right" top="12" weightx="1">
40
        <button action="ok()" icon="/thinletcommons/icons/ok.gif" mnemonic="0" name="b_ok" text="Ok" type="default"/>
41
        <button action="close()" icon="/thinletcommons/icons/cancel.gif" mnemonic="0" name="b_cancel" text="Cancel" type="cancel"/>
42
    </panel>
43

  
44
</panel>
45

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/dirchooser.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!-- jEdit settings: :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: -->
3

  
4
<panel
5
	columns="1"
6
	gap="6"
7
	top="6"
8
	left="6"
9
	right="6"
10
	bottom="6"
11
	width="300"
12
	height="400"
13
	init="init(tree)"
14
>
15
	<tree
16
		name="tree"
17
		angle="true"
18
		line="false"
19
		weightx="1"
20
		weighty="1"
21
		perform="ok(this)"
22
		expand="nodeExpanded(this, item)"
23
	/>
24
	<panel gap="6" top="12" weightx="1">
25
		<panel weightx="1"/>
26
		<button name="ok" text="Ok" icon="/thinletcommons/icons/ok.gif" mnemonic="0" type="default" action="ok(tree)"/>
27
		<button name="cancel" text="Cancel" icon="/thinletcommons/icons/cancel.gif" mnemonic="0" type="cancel" action="close()"/>
28
	</panel>
29
</panel>
30

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/filechooser.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!-- jEdit settings: :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1: -->
3

  
4
<panel bottom="12" columns="1" gap="12" left="12" right="12" top="12" weightx="1" weighty="1">
5
    <panel gap="6" weightx="1">
6
        <label for="cbPath" mnemonic="0" text="Look In:"/>
7
        <combobox action="cbPathChanged()" editable="false" name="cbPath" weightx="1"/>
8
        <button action="goUp()" icon="/thinletcommons/icons/up.gif" name="bUp" tooltip="Go to parent directory"/>
9
        <button action="goHome()" icon="/thinletcommons/icons/home.gif" name="bHome" tooltip="Go to home directory"/>
10
        <togglebutton action="toggleShowHiddenFiles(this.selected)" icon="/thinletcommons/icons/hidden_files.gif" name="bShowHidden" tooltip="Toggle display of hidden files."/>
11
    </panel>
12

  
13
    <table action="tableRowSelected()" height="300" line="false" name="tbFilelist" perform="tableRowDoubleClicked()" weightx="1" weighty="1" width="420">
14
        <header action="tableHeaderChanged(colName, colType, colSize, colMod)">
15
            <column name="colName" sort="ascent" text="Name" width="170"/>
16
            <column name="colType" text="Type" width="140"/>
17
            <column name="colSize" text="Size" width="80"/>
18
            <column name="colMod" text="Last Modified" width="120"/>
19
        </header>
20
    </table>
21

  
22
    <panel columns="4" gap="6">
23
        <label for="tFilename" mnemonic="0" text="File name:"/>
24
        <textfield name="tFilename" perform="ok()" weightx="1"/>
25

  
26
        <!-- some free space between filename field and ok/cancel buttons -->
27
        <panel left="12" rowspan="2"/>
28

  
29
        <button action="ok()" icon="/thinletcommons/icons/ok.gif" mnemonic="0" name="bOk" text="Ok" type="default"/>
30
        <label for="cbFilter" halign="right" mnemonic="1" text="Filter:"/>
31
        <combobox action="cbFilterChanged(this.selected)" editable="false" name="cbFilter" weightx="1"/>
32
        <button action="close()" icon="/thinletcommons/icons/cancel.gif" mnemonic="0" name="bCancel" text="Cancel" type="cancel"/>
33
    </panel>
34
</panel>
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/ExtensionFileFilter.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.io.File;
8

  
9

  
10
/**
11
 * A file filter for {@link FileChooser} that accepts files based on file
12
 * name endings (<i>extensions</i>).
13
 *
14
 * <p>
15
 * Note that the file filter is case sensitive. That is a file filter instance
16
 * created with <code>new ExtensionFileFilter("xml", "XML files")</code>
17
 * accepts <code>file.xml</code> but not <code>FILE.XML</code>.
18
 *
19
 * @author Dirk Moebius
20
 */
21
public class ExtensionFileFilter implements FileFilter
22
{
23

  
24
    private String extension;
25
    private String description;
26

  
27

  
28
    /**
29
     * Create a new ExceptionFileFilter.
30
     *
31
     * @param extension  the extention, for example "xml", "jpg", etc.
32
     * @param description  the description.
33
     */
34
    public ExtensionFileFilter(String extension, String description)
35
    {
36
        this.extension = "." + extension;
37
        this.description = description;
38
    }
39

  
40

  
41
    /**
42
     * Whether the given file is accepted by this filter.
43
     */
44
    public boolean accept(File file)
45
    {
46
        return file.getName().endsWith(extension);
47
    }
48

  
49

  
50
    /**
51
     * A human readable description of this file filter.
52
     */
53
    public String getDescription()
54
    {
55
        return description;
56
    }
57

  
58
}
59

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/messagedialog.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!-- jEdit settings: :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: -->
3

  
4
<panel
5
	columns="2"
6
	gap="12" top="12" left="12" right="12" bottom="12"
7
	init="init(iconLabel, message, button1, button2, button3)"
8
>
9
	<label
10
		name="iconLabel"
11
		icon="/thinletcommons/icons/inform.gif"
12
		valign="top"
13
		rowspan="2"
14
	/>
15
	<textarea
16
		name="message"
17
		editable="false"
18
		border="false"
19
		wrap="true"
20
		weightx="1"
21
		weighty="1"
22
	/>
23
	<panel gap="12" halign="right">
24
		<button name="button1" text="..." action="buttonPressed(this)"/>
25
		<button name="button2" text="..." action="buttonPressed(this)"/>
26
		<button name="button3" text="..." action="buttonPressed(this)"/>
27
	</panel>
28
</panel>
29

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/FileFilter.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.io.File;
8

  
9

  
10
/**
11
 * A file filter for {@link FileChooser}.
12
 *
13
 * @author Dirk Moebius
14
 */
15
public interface FileFilter
16
{
17
    /**
18
     * Whether the given file is accepted by this filter.
19
     */
20
    public boolean accept(File file);
21

  
22
    /**
23
     * A human readable description of this file filter.
24
     */
25
    public String getDescription();
26
}
27

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/ThinletDialog.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.awt.BorderLayout;
8
import java.awt.Component;
9
import java.awt.Dialog;
10
import java.awt.Dimension;
11
import java.awt.Frame;
12
import java.awt.Graphics;
13
import java.awt.Image;
14
import java.awt.event.WindowAdapter;
15
import java.awt.event.WindowEvent;
16
import java.util.logging.Level;
17
import java.util.logging.Logger;
18

  
19
import thinlet.Thinlet;
20

  
21

  
22
/**
23
 * <code>ThinletDialog</code> is a <i>modal</i> double buffered dialog
24
 * containing a <i>thinlet</i> component.
25
 *
26
 * @author Dirk Moebius
27
 */
28
public class ThinletDialog extends Dialog
29
{
30
    //{{{ logging
31
    private static final Logger log = Logger.getLogger("thinletcommons");
32
    private static final boolean debug() { return log.isLoggable(Level.FINE); }
33
    //}}}
34

  
35

  
36
    private transient Thinlet content;
37
    private transient Image doublebuffer;
38

  
39

  
40
    public ThinletDialog(Frame owner)
41
    {
42
        super(owner, true);
43
        addWindowListener(new WindowHandler());
44
    }
45

  
46

  
47
    public ThinletDialog(Frame owner, String title)
48
    {
49
        super(owner, title, true);
50
        addWindowListener(new WindowHandler());
51
    }
52

  
53

  
54
    public ThinletDialog(Dialog owner)
55
    {
56
        super(owner);
57
        setModal(true);
58
        addWindowListener(new WindowHandler());
59
    }
60

  
61

  
62
    public ThinletDialog(Dialog owner, String title)
63
    {
64
        super(owner, title, true);
65
        addWindowListener(new WindowHandler());
66
    }
67

  
68

  
69
    public void setContent(Thinlet content)
70
    {
71
        this.content = content;
72
        removeAll();
73
        setLayout(new BorderLayout());
74
        _addImpl(content, BorderLayout.CENTER);
75
        pack();
76
    }
77

  
78

  
79
    public Thinlet getContent()
80
    {
81
        return content;
82
    }
83

  
84

  
85
    /**
86
     * Call the paint method to redraw this component without painting a
87
     * background rectangle.
88
     */
89
    public void update(Graphics g)
90
    {
91
        paint(g);
92
    }
93

  
94

  
95
    /**
96
     * Create a double buffer if needed, the <i>thinlet</i> component paints
97
     * the content.
98
     */
99
    public void paint(Graphics g)
100
    {
101
        if(doublebuffer == null)
102
        {
103
            Dimension d = getSize();
104
            doublebuffer = createImage(d.width, d.height);
105
        }
106
        Graphics dg = doublebuffer.getGraphics();
107
        dg.setClip(g.getClipBounds());
108
        super.paint(dg);
109
        dg.dispose();
110
        g.drawImage(doublebuffer, 0, 0, this);
111
    }
112

  
113

  
114
    /**
115
     * Clear the double buffer image (because the frame has been resized), the
116
     * overriden method lays out its components (centers the <i>thinlet</i>
117
     * component).
118
     */
119
    public void doLayout()
120
    {
121
        if(doublebuffer != null)
122
        {
123
            doublebuffer.flush();
124
            doublebuffer = null;
125
        }
126
        super.doLayout();
127
    }
128

  
129

  
130
    /**
131
     * Redirects all calls to <code>add(...)</code> to
132
     * {@link #setContent(Thinlet)}.
133
     */
134
    protected void addImpl(Component comp, Object constraints, int index)
135
    {
136
        setContent((Thinlet)comp);
137
    }
138

  
139

  
140
    private void _addImpl(Component comp, String constraints)
141
    {
142
        super.addImpl(comp, constraints, -1);
143
    }
144

  
145

  
146
    private class WindowHandler extends WindowAdapter
147
    {
148
        public void windowClosing(WindowEvent e)
149
        {
150
            // dialog stays visible if the thinlet returns 'false' in destroy(),
151
            // otherwise it is closed and control is returned to calling frame.
152
            setVisible(content != null && !content.destroy());
153
        }
154
    }
155

  
156
}
157

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/thing.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!-- jEdit settings: :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: -->
3

  
4
<panel columns="1" gap="4">
5

  
6
	<menubar weightx="1">
7
		<menu text="File" mnemonic="0">
8
			<menuitem text="New" mnemonic="0" icon="icons/empty_menu.gif" accelerator="ctrl N" action="menu_file_new()"/>
9
			<menuitem text="Open..." mnemonic="0" icon="icons/empty_menu.gif" accelerator="ctrl O" action="menu_file_open()"/>
10
			<separator/>
11
			<menuitem text="Reload" mnemonic="0" icon="icons/empty_menu.gif" accelerator="ctrl R" action="menu_file_reload()"/>
12
			<separator/>
13
			<menuitem text="Save" mnemonic="0" icon="icons/empty_menu.gif" accelerator="ctrl S" action="menu_file_save()"/>
14
			<menuitem text="Save As..." mnemonic="5" icon="icons/empty_menu.gif" action="menu_file_save_as()"/>
15
			<separator/>
16
			<menuitem text="Exit" mnemonic="0" icon="icons/empty_menu.gif" accelerator="alt F4" action="menu_file_exit()"/>
17
		</menu>
18
		<menu text="Edit" mnemonic="0">
19
			<menuitem text="Cut" name="menu_edit_cut" mnemonic="0" accelerator="ctrl X" icon="icons/edit_cut.gif" action="menu_edit_cut()"/>
20
			<menuitem text="Copy" name="menu_edit_copy" mnemonic="1" accelerator="ctrl C" icon="icons/edit_copy.gif" action="menu_edit_copy()"/>
21
			<menuitem text="Paste" name="menu_edit_paste" mnemonic="0" accelerator="ctrl V" icon="icons/edit_paste.gif" action="menu_edit_paste()"/>
22
			<menuitem text="Paste from system clipboard" name="menu_edit_paste_systemcb" mnemonic="1" accelerator="ctrl shift V" icon="icons/empty_menu.gif" action="menu_edit_paste_systemcb()"/>
23
			<menuitem text="Delete" name="menu_edit_delete" mnemonic="0" icon="icons/edit_delete.gif" action="menu_edit_delete()"/>
24
			<separator/>
25
			<menuitem text="Settings..." mnemonic="0" icon="icons/empty_menu.gif" action="menu_edit_settings()"/>
26
		</menu>
27
		<menu text="Tools" mnemonic="0">
28
			<menuitem text="Generate Handler Stub Source..." name="menu_tools_generate" mnemonic="0" accelerator="ctrl G" icon="icons/empty_menu.gif" action="menu_tools_generate()"/>
29
		</menu>
30
		<menu text="Help" mnemonic="0">
31
			<menuitem text="About Thing..." mnemonic="0" icon="icons/thing_small.gif" action="menu_help_about()"/>
32
		</menu>
33
	</menubar>
34

  
35
	<panel name="toolbar" weightx="1" gap="-1">
36

  
37
		<!-- top level components -->
38
		<button name="tb_add_panel" property="classname=panel" icon="icons/panel.gif" tooltip="Create new panel" action="addComponent(this)"/>
39
		<button name="tb_add_dialog" property="classname=dialog" icon="icons/dialog.gif" tooltip="Create new dialog" action="addComponent(this)"/>
40
		<button name="tb_add_desktop" property="classname=desktop" icon="icons/desktop.gif" tooltip="Create new desktop" action="addComponent(this)"/>
41
		<button name="tb_add_splitpane" property="classname=splitpane" icon="icons/splitpane.gif" tooltip="Create new splitpane" action="addComponent(this)"/>
42
		<button name="tb_add_tabbedpane" property="classname=tabbedpane" icon="icons/tabbedpane.gif" tooltip="Create new tabbedpane" action="addComponent(this)"/>
43

  
44
		<!-- menu components -->
45
		<button name="tb_add_menubar" property="classname=menubar" icon="icons/menubar.gif" tooltip="Create new menubar" action="addComponent(this)"/>
46
		<button name="tb_add_menu" property="classname=menu" icon="icons/menu.gif" tooltip="Create new menu" action="addComponent(this)"/>
47
		<button name="tb_add_menuitem" property="classname=menuitem" icon="icons/menuitem.gif" tooltip="Create new menuitem" action="addComponent(this)"/>
48
		<button name="tb_add_checkboxmenuitem" property="classname=checkboxmenuitem" icon="icons/checkboxmenuitem.gif" tooltip="Create new checkboxmenuitem" action="addComponent(this)"/>
49

  
50
		<!-- components -->
51
		<button name="tb_add_label" property="classname=label" icon="icons/label.gif" tooltip="Create new label" action="addComponent(this)"/>
52
		<button name="tb_add_button" property="classname=button" icon="icons/button.gif" tooltip="Create new button" action="addComponent(this)"/>
53
		<button name="tb_add_togglebutton" property="classname=togglebutton" icon="icons/togglebutton.gif" tooltip="Create new togglebutton" action="addComponent(this)"/>
54
		<button name="tb_add_checkbox" property="classname=checkbox" icon="icons/checkbox.gif" tooltip="Create new checkbox" action="addComponent(this)"/>
55
		<button name="tb_add_textfield" property="classname=textfield" icon="icons/textfield.gif" tooltip="Create new textfield" action="addComponent(this)"/>
56
		<button name="tb_add_combobox" property="classname=combobox" icon="icons/combobox.gif" tooltip="Create new combobox" action="addComponent(this)"/>
57
		<button name="tb_add_passwordfield" property="classname=passwordfield" icon="icons/passwordfield.gif" tooltip="Create new passwordfield" action="addComponent(this)"/>
58
		<button name="tb_add_spinbox" property="classname=spinbox" icon="icons/spinbox.gif" tooltip="Create new spinbox" action="addComponent(this)"/>
59
		<button name="tb_add_progressbar" property="classname=progressbar" icon="icons/progressbar.gif" tooltip="Create new progressbar" action="addComponent(this)"/>
60
		<button name="tb_add_slider" property="classname=slider" icon="icons/slider.gif" tooltip="Create new slider" action="addComponent(this)"/>
61
		<button name="tb_add_separator" property="classname=separator" icon="icons/separator.gif" tooltip="Create new separator" action="addComponent(this)"/>
62
		<button name="tb_add_list" property="classname=list" icon="icons/list.gif" tooltip="Create new list" action="addComponent(this)"/>
63
		<button name="tb_add_table" property="classname=table" icon="icons/table.gif" tooltip="Create new table" action="addComponent(this)"/>
64
		<button name="tb_add_textarea" property="classname=textarea" icon="icons/textarea.gif" tooltip="Create new textarea" action="addComponent(this)"/>
65
		<button name="tb_add_tree" property="classname=tree" icon="icons/tree.gif" tooltip="Create new tree" action="addComponent(this)"/>
66

  
67
		<!-- list items -->
68
		<button name="tb_add_choice" property="classname=choice" icon="icons/choice.gif" tooltip="Create new choice" action="addComponent(this)"/>
69
		<button name="tb_add_item" property="classname=item" icon="icons/item.gif" tooltip="Create new item" action="addComponent(this)"/>
70
		<button name="tb_add_node" property="classname=node" icon="icons/node.gif" tooltip="Create new node" action="addComponent(this)"/>
71
		<button name="tb_add_tab" property="classname=tab" icon="icons/tab.gif" tooltip="Create new tab" action="addComponent(this)"/>
72

  
73
		<!-- table components -->
74
		<button name="tb_add_row" property="classname=row" icon="icons/row.gif" tooltip="Create new row" action="addComponent(this)"/>
75
		<button name="tb_add_cell" property="classname=cell" icon="icons/cell.gif" tooltip="Create new cell" action="addComponent(this)"/>
76
		<button name="tb_add_header" property="classname=header" icon="icons/header.gif" tooltip="Create new header" action="addComponent(this)"/>
77
		<button name="tb_add_column" property="classname=column" icon="icons/column.gif" tooltip="Create new column" action="addComponent(this)"/>
78

  
79
		<!-- other -->
80
		<button name="tb_add_popupmenu" property="classname=popupmenu" icon="icons/popupmenu.gif" tooltip="Create new popupmenu" action="addComponent(this)"/>
81

  
82
		<!-- later -->
83
		<!--
84
		<button name="tb_add_bean" property="classname=bean" icon="icons/bean.gif" tooltip="Create new bean" action="addComponent(this)" enabled="false"/>
85
		-->
86

  
87
		<!-- placeholder in case there are no buttons add all -->
88
		<separator height="30" width="1"/>
89
	</panel>
90

  
91
	<!-- main workarea -->
92
	<panel left="4" right="4" weightx="1" weighty="1">
93
		<splitpane orientation="horizontal" divider="200" weightx="1" weighty="1">
94

  
95
			<!-- left splitpane: component tree and properties table -->
96
			<splitpane orientation="vertical">
97
				<panel columns="1" weightx="1" weighty="1">
98
					<tree name="tree" angle="true" line="false" selection="single" weightx="1" weighty="1" action="treeSelectionChanged()"/>
99
					<panel top="3" bottom="3" gap="2" scrollable="true">
100
						<button name="tb_edit_copy" icon="icons/edit_copy.gif" tooltip="Copy selected component to internal ThinG clipboard and system clipboard" action="menu_edit_copy()"/>
101
						<button name="tb_edit_cut" icon="icons/edit_cut.gif" tooltip="Cut selected component to internal ThinG clipboard and system clipboard" action="menu_edit_cut()"/>
102
						<button name="tb_edit_paste" icon="icons/edit_paste.gif" tooltip="Paste component from internal ThinG clipboard below selected component" action="menu_edit_paste()"/>
103
						<button name="tb_edit_delete" icon="icons/edit_delete.gif" tooltip="Remove selected component" action="menu_edit_delete()"/>
104
						<separator/>
105
						<button name="tb_edit_moveup" icon="icons/edit_moveup.gif" tooltip="Move selected component up" action="moveComponentUp()"/>
106
						<button name="tb_edit_movedown" icon="icons/edit_movedown.gif" tooltip="Move selected component down" action="moveComponentDown()"/>
107
					</panel>
108
				</panel>
109
				<panel columns="1" gap="5">
110
					<table name="props" selection="single" weightx="1" weighty="1" action="tableSelectionChanged()">
111
						<header>
112
							<column name="props_key" text="Property" width="80" sort="ascent"/>
113
							<column name="props_value" text="Value"/>
114
						</header>
115
					</table>
116
					<panel name="propedit" columns="3" gap="5" weightx="1" border="true" top="5" left="5" bottom="5" right="5">
117
						<label name="propedit_name" text=""/>
118
						<panel name="propedit_panel" gap="5" weightx="1"/>
119
						<button name="propedit_reset" text="Reset" tooltip="Reset to default value" font="10" valign="center" enabled="false" action="propEditReset()"/>
120
					</panel>
121
				</panel>
122
			</splitpane>
123

  
124
			<!-- right splitpane: preview panel -->
125
			<tabbedpane name="tabs" placement="top" selected="1" action="tabSelected(this.selected)">
126
				<!-- Attention: because of an obscure bug in Thinlet.getNextFocusable(), -->
127
				<!-- the tab "XML" must be the first one! If it is not the first panel, Thinlet -->
128
				<!-- runs into an endless loop when the user navigates from the "Preview" tab -->
129
				<!-- to the "XML" tab, trying to set the next focusable component. -->
130
				<tab text="XML" mnemonic="0">
131
					<panel weightx="1" weighty="1">
132
						<textarea name="serialize" editable="false" weightx="1" weighty="1"/>
133
					</panel>
134
				</tab>
135
				<tab text="Preview" mnemonic="0">
136
					<panel name="preview" border="true" scrollable="true" weightx="1" weighty="1"/>
137
				</tab>
138
			</tabbedpane>
139

  
140
		</splitpane>
141
	</panel>
142

  
143
	<!-- status bar at bottom -->
144
	<textfield name="statusbar" editable="false" text="ThinG" weightx="1"/>
145

  
146
</panel>
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/FontChooser.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.awt.Dialog;
8
import java.awt.Dimension;
9
import java.awt.Font;
10
import java.awt.Frame;
11
import java.awt.GraphicsEnvironment;
12
import java.util.Arrays;
13
import java.util.logging.Level;
14
import java.util.logging.Logger;
15

  
16
import thinlet.Thinlet;
17

  
18

  
19
/**
20
 * A Thinlet font chooser dialog.
21
 *
22
 * <p>
23
 * The dialog is modal and blocks the calling frame/dialog. It is therefore
24
 * displayed in a separate window.
25
 *
26
 * @author Dirk Moebius
27
 */
28
public class FontChooser
29
{
30
    //{{{ logging
31
    private static final Logger log = Logger.getLogger("thinletcommons");
32
    private static final boolean debug() { return log.isLoggable(Level.FINE); }
33
    //}}}
34

  
35

  
36
    private ThinletDialog dialog;
37
    private Thinlet thinlet;
38
    private Font selectedFont;
39

  
40

  
41
    public FontChooser(Frame owner, String title)
42
    {
43
        this.dialog = new ThinletDialog(owner, title);
44
        init();
45
    }
46

  
47

  
48
    public FontChooser(Dialog owner, String title)
49
    {
50
        this.dialog = new ThinletDialog(owner, title);
51
        init();
52
    }
53

  
54

  
55
    private void init()
56
    {
57
        thinlet = new AntiAliasedThinlet();
58

  
59
        try
60
        {
61
            Object panel = thinlet.parse("/thinletcommons/fontchooser.xml", this);
62
            thinlet.add(panel);
63
        }
64
        catch(Exception e)
65
        {
66
            log.log(Level.SEVERE, "Error parsing fontchooser.xml", e);
67
        }
68

  
69
        dialog.setContent(thinlet);
70
    }
71

  
72

  
73
    /**
74
     * Show the modal dialog.
75
     * This halts the application until the user dismisses the dialog.
76
     */
77
    public void show()
78
    {
79
        dialog.setSize(new Dimension(320, 360));
80
        dialog.setLocationRelativeTo(dialog.getOwner());
81
        dialog.setVisible(true);
82
    }
83

  
84

  
85
    public void setSelectedFont(Font font)
86
    {
87
        String family = null;
88
        int size = 12;
89
        boolean isBold = false;
90
        boolean isItalic = false;
91

  
92
        if(font != null)
93
        {
94
            family = font.getFamily();
95
            size = font.getSize();
96
            isBold = font.isBold();
97
            isItalic = font.isItalic();
98
            thinlet.setFont(thinlet.find("preview"), "font", font);
99
        }
100

  
101
        thinlet.setString(thinlet.find("fontsize"), "text", String.valueOf(size));
102
        thinlet.setBoolean(thinlet.find("cb_bold"), "selected", isBold);
103
        thinlet.setBoolean(thinlet.find("cb_italic"), "selected", isItalic);
104

  
105
        Object fontlist = thinlet.find("fontlist");
106
        Object[] items = thinlet.getItems(fontlist);
107
        for(int i = 0; i < items.length; ++i)
108
        {
109
            String text = thinlet.getString(items[i], "text");
110
            thinlet.setBoolean(items[i], "selected", text.equals(family));
111
        }
112

  
113
        thinlet.setBoolean(thinlet.find("b_ok"), "enabled", font != null);
114
    }
115

  
116

  
117
    public Font getSelectedFont()
118
    {
119
        return selectedFont;
120
    }
121

  
122

  
123
    //{{{ callbacks for fontchooser.xml
124
    /** Thinlet callback. */
125
    public void init(Object fontlist)
126
    {
127
        if(debug()) log.fine("in init()");
128
        String[] names = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
129
        Arrays.sort(names);
130
        for(int i = 0; i < names.length; ++i)
131
        {
132
            Object item = Thinlet.create("item");
133
            thinlet.add(fontlist, item);
134
            thinlet.setString(item, "text", names[i]);
135
        }
136
    }
137

  
138

  
139
    /** Thinlet callback. */
140
    public void ok(Object fontlist, Object fontsize, Object cbBold, Object cbItalic)
141
    {
142
        this.selectedFont = getFont(fontlist, fontsize, cbBold, cbItalic);
143
        if(debug()) log.fine("selected: " + this.selectedFont);
144
        dialog.setVisible(false);
145
    }
146

  
147

  
148
    /** Thinlet callback. */
149
    public void close()
150
    {
151
        dialog.setVisible(false);
152
    }
153

  
154

  
155
    /** Thinlet callback. */
156
    public void fontChanged(Object fontlist, Object fontsize, Object cbBold, Object cbItalic, Object preview, Object bOk)
157
    {
158
        Font font = getFont(fontlist, fontsize, cbBold, cbItalic);
159
        if(font == null)
160
            thinlet.setBoolean(bOk, "enabled", false);
161
        else
162
        {
163
            thinlet.setBoolean(bOk, "enabled", true);
164
            thinlet.setFont(preview, "font", font);
165
        }
166
    }
167
    //}}}
168

  
169

  
170
    //{{{ private methods
171
    private Font getFont(Object fontlist, Object fontsize, Object cbBold, Object cbItalic)
172
    {
173
        Object item = thinlet.getSelectedItem(fontlist);
174
        if(item == null)
175
            return null;
176

  
177
        String family = thinlet.getString(item, "text");
178
        int size = 12;
179
        String fontsizeText = thinlet.getString(fontsize, "text");
180
        if(fontsizeText.length() > 0)
181
            size = Integer.parseInt(fontsizeText);
182
        boolean isBold = thinlet.getBoolean(cbBold, "selected");
183
        boolean isItalic = thinlet.getBoolean(cbItalic, "selected");
184

  
185
        Font font = new Font(family,
186
            isBold ? (isItalic ? Font.BOLD|Font.ITALIC : Font.BOLD)
187
                : (isItalic ? Font.ITALIC : Font.PLAIN), size);
188

  
189
        return font;
190
    }
191
    //}}}
192

  
193
}
194

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/ThinletTester.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.io.BufferedInputStream;
8
import java.io.FileInputStream;
9
import java.io.InputStream;
10
import java.lang.reflect.InvocationTargetException;
11
import java.lang.reflect.Method;
12

  
13
import thinlet.FrameLauncher;
14
import thinlet.Thinlet;
15

  
16

  
17
public class ThinletTester
18
{
19

  
20
    private static String file = null;
21
    private static String thinletClassname = "thinlet.Thinlet";
22
    private static String handlerClassname = null;
23

  
24

  
25
    public static void main(String[] args) throws Throwable
26
    {
27
        getArgs(args);
28
        run();
29
    }
30

  
31

  
32
    private static void getArgs(String[] args)
33
    {
34
        if(args.length < 1 || args.length > 5)
35
            usage();
36

  
37
        for(int i = 0; i < args.length; ++i)
38
        {
39
            if(args[i].equals("--help"))
40
                usage();
41
            else if(args[i].equals("--thinlet"))
42
            {
43
                if(i == args.length - 1)
44
                    usage();
45
                else
46
                    thinletClassname = args[++i];
47
            }
48
            else if(args[i].equals("--handler"))
49
            {
50
                if(i == args.length - 1)
51
                    usage();
52
                else
53
                    handlerClassname = args[++i];
54
            }
55
            else if(file == null)
56
                file = args[i];
57
            else
58
                usage();
59
        }
60

  
61
        if(file == null)
62
            usage();
63
    }
64

  
65

  
66
    private static void usage()
67
    {
68
        System.out.println("ThinletTester, version 1.0");
69
        System.out.println();
70
        System.out.println("Usage: java [-cp <classpath>] thinletcommons.ThinletTester [--thinlet <classname>]");
71
        System.out.println("         [--handler <classname>] thinletfile.xml");
72
        System.out.println();
73
        System.out.println("  --thinlet  Thinlet classname, e.g. thinlet.Thinlet");
74
        System.out.println("  --handler  Handler classname, e.g. foo.bar.MyHandler");
75
        System.out.println();
76
        System.out.println("  The classpath must include both the Thinlet class and the handler class (if");
77
        System.out.println("  given on the commandline) as well as thinlet.jar.");
78
        System.out.println("  The specified Thinlet class and Handler class must have a default");
79
        System.out.println("  constructor.");
80
        System.out.println();
81
        System.exit(1);
82
    }
83

  
84

  
85
    private static void run() throws Throwable
86
    {
87
        // create Thinlet instance
88
        Class thinletClass = Class.forName(thinletClassname);
89
        Object thinlet = thinletClass.newInstance();
90

  
91
        if(!Thinlet.class.isInstance(thinlet))
92
        {
93
            System.err.println("error: " + thinletClassname + " is not a Thinlet class.");
94
            System.exit(2);
95
        }
96

  
97
        System.out.println("using thinlet class: " + thinletClass.getName());
98

  
99
        // create Handler instance
100
        Object handler = thinlet;
101
        if(handlerClassname != null)
102
        {
103
            Class handlerClass = Class.forName(handlerClassname);
104
            handler = handlerClass.newInstance();
105
            System.out.println("using handler class: " + handlerClass.getName());
106
        }
107

  
108
        InputStream is = getInputStream(file);
109
        System.out.println("parsing file " + file + " ...");
110

  
111
        // "Object result = thinlet.parse(is, handler);"
112
        Method parseMethod = thinletClass.getMethod("parse", new Class[] { InputStream.class, Object.class });
113
        Object result;
114
        try
115
        {
116
            result = parseMethod.invoke(thinlet, new Object[] { is, handler });
117
        }
118
        catch(InvocationTargetException e)
119
        {
120
            throw e.getTargetException();
121
        }
122

  
123
        // "thinlet.add(result);"
124
        Method addMethod = thinletClass.getMethod("add", new Class[] { Object.class });
125
        try
126
        {
127
            addMethod.invoke(thinlet, new Object[] { result });
128
        }
129
        catch(InvocationTargetException e)
130
        {
131
            throw e.getTargetException();
132
        }
133

  
134
        System.out.println("showing frame...");
135

  
136
        /*FrameLauncher frame = new FrameLauncher("ThinletTester", null, (Thinlet)thinlet, 400, 400, false);
137
        frame.pack();
138
        frame.setVisible(true);
139
*/
140
        System.out.println("done.");
141
    }
142

  
143

  
144
    private static InputStream getInputStream(String filename) throws Exception
145
    {
146
        return new BufferedInputStream(new FileInputStream(filename));
147
    }
148

  
149
}
150

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/ColorChooser.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.awt.Color;
8
import java.awt.Dialog;
9
import java.awt.Frame;
10
import java.util.logging.Level;
11
import java.util.logging.Logger;
12

  
13
import thinlet.Thinlet;
14

  
15

  
16
/**
17
 * A Thinlet color chooser dialog.
18
 *
19
 * <p>
20
 * The dialog is modal and blocks the calling frame/dialog. It is therefore
21
 * displayed in a separate window.
22
 *
23
 * @author Dirk Moebius
24
 */
25
public class ColorChooser
26
{
27
    //{{{ logging
28
    private static final Logger log = Logger.getLogger("thinletcommons");
29
    private static final boolean debug() { return log.isLoggable(Level.FINE); }
30
    //}}}
31

  
32

  
33
    private ThinletDialog dialog;
34
    private Thinlet thinlet;
35
    private Color selectedColor;
36

  
37
    // components
38
    private Object sl_red, sl_green, sl_blue;
39
    private Object sb_red, sb_green, sb_blue;
40
    private Object tf_hue, tf_saturation, tf_brightness;
41
    private Object pb_hue, pb_saturation, pb_brightness;
42
    private Object rgb_label;
43

  
44

  
45
    public ColorChooser(Frame owner, String title)
46
    {
47
        this.dialog = new ThinletDialog(owner, title);
48
        init();
49
    }
50

  
51

  
52
    public ColorChooser(Dialog owner, String title)
53
    {
54
        this.dialog = new ThinletDialog(owner, title);
55
        init();
56
    }
57

  
58

  
59
    private void init()
60
    {
61
        thinlet = new AntiAliasedThinlet();
62

  
63
        try
64
        {
65
            Object panel = thinlet.parse("/thinletcommons/colorchooser.xml", this);
66
            thinlet.add(panel);
67
        }
68
        catch(Exception e)
69
        {
70
            log.log(Level.SEVERE, "Error parsing colorchooser.xml", e);
71
        }
72

  
73
        dialog.setContent(thinlet);
74
    }
75

  
76

  
77
    /**
78
     * Show the modal dialog.
79
     * This halts the application until the user dismisses the dialog.
80
     */
81
    public void show()
82
    {
83
        if(debug()) log.fine("in show");
84
        dialog.pack();
85
        dialog.setResizable(false);
86
        dialog.setLocationRelativeTo(dialog.getOwner());
87
        dialog.setVisible(true);
88
    }
89

  
90

  
91
    public void setSelectedColor(Color color)
92
    {
93
        int red = 0, green = 0, blue = 0;
94
        if(color != null)
95
        {
96
            red = color.getRed();
97
            green = color.getGreen();
98
            blue = color.getBlue();
99
            thinlet.setInteger(sl_red, "value", red);
100
            thinlet.setInteger(sl_green, "value", green);
101
            thinlet.setInteger(sl_blue, "value", blue);
102
            thinlet.setString(sb_red, "text", String.valueOf(red));
103
            thinlet.setString(sb_green, "text", String.valueOf(green));
104
            thinlet.setString(sb_blue, "text", String.valueOf(blue));
105
            hsbChanged();
106
        }
107
    }
108

  
109

  
110
    public Color getSelectedColor()
111
    {
112
        return selectedColor;
113
    }
114

  
115

  
116
    //{{{ callbacks for colorchooser.xml
117
    /** Thinlet callback. */
118
    public void init(Object sl_red, Object sl_green, Object sl_blue,
119
        Object sb_red, Object sb_green, Object sb_blue,
120
        Object tf_hue, Object tf_saturation, Object tf_brightness,
121
        Object pb_hue, Object pb_saturation, Object pb_brightness,
122
        Object rgb_label)
123
    {
124
        if(debug()) log.fine("in init");
125
        this.sl_red = sl_red;
126
        this.sl_green = sl_green;
127
        this.sl_blue = sl_blue;
128
        this.sb_red = sb_red;
129
        this.sb_green = sb_green;
130
        this.sb_blue = sb_blue;
131
        this.tf_hue = tf_hue;
132
        this.tf_saturation = tf_saturation;
133
        this.tf_brightness = tf_brightness;
134
        this.pb_hue = pb_hue;
135
        this.pb_saturation = pb_saturation;
136
        this.pb_brightness = pb_brightness;
137
        this.rgb_label = rgb_label;
138
    }
139

  
140

  
141
    /** Thinlet callback. */
142
    public void sliderChanged(int value, Object spinbox)
143
    {
144
        thinlet.setString(spinbox, "text", String.valueOf(value));
145
        hsbChanged();
146
    }
147

  
148

  
149
    /** Thinlet callback. */
150
    public void spinboxChanged(String text, Object slider)
151
    {
152
        try
153
        {
154
            int value = Integer.parseInt(text);
155
            if(value >= 0 && value <= 255)
156
            {
157
                thinlet.setInteger(slider, "value", value);
158
                hsbChanged();
159
            }
160
        }
161
        catch (NumberFormatException ignore)
162
        {
163
        }
164
    }
165

  
166

  
167
    /** Thinlet callback. */
168
    public void ok()
169
    {
170
        int red = thinlet.getInteger(sl_red, "value");
171
        int green = thinlet.getInteger(sl_green, "value");
172
        int blue = thinlet.getInteger(sl_blue, "value");
173
        this.selectedColor = new Color(red, green, blue);
174
        dialog.setVisible(false);
175
    }
176

  
177

  
178
    /** Thinlet callback. */
179
    public void close()
180
    {
181
        dialog.setVisible(false);
182
    }
183
    //}}}
184

  
185

  
186
    //{{{ private methods
187
    private void hsbChanged()
188
    {
189
        int red = thinlet.getInteger(sl_red, "value");
190
        int green = thinlet.getInteger(sl_green, "value");
191
        int blue = thinlet.getInteger(sl_blue, "value");
192

  
193
        float[] hsb = Color.RGBtoHSB(red, green, blue, null);
194

  
195
        thinlet.setColor(rgb_label, "background", new Color(red, green, blue));
196
        thinlet.setString(tf_hue, "text", String.valueOf(hsb[0]));
197
        thinlet.setString(tf_saturation, "text", String.valueOf(hsb[1]));
198
        thinlet.setString(tf_brightness, "text", String.valueOf(hsb[2]));
199

  
200
        thinlet.setInteger(pb_hue, "value", (int) (100f * hsb[0]));
201
        thinlet.setInteger(pb_saturation, "value", (int) (100f * hsb[1]));
202
        thinlet.setInteger(pb_brightness, "value", (int) (100f * hsb[2]));
203
    }
204
    //}}}
205

  
206
}
207

  
org.gvsig.scripting/tags/org.gvsig.scripting-2.3.50/org.gvsig.scripting.thing/src/main/java/thinletcommons/DirChooser.java
1
// jEdit settings:
2
// :tabSize=4:indentSize=4:noTabs=true:folding=explicit:collapseFolds=1:
3

  
4
package thinletcommons;
5

  
6

  
7
import java.awt.Dialog;
8
import java.awt.Frame;
9
import java.awt.Image;
10
import java.awt.image.BufferedImage;
11
import java.io.File;
12
import java.text.Collator;
13
import java.util.Arrays;
14
import java.util.Comparator;
15
import java.util.Stack;
16
import java.util.logging.Level;
17
import java.util.logging.Logger;
18

  
19
import javax.swing.Icon;
20
import javax.swing.ImageIcon;
21
import javax.swing.filechooser.FileSystemView;
22

  
23
import thinlet.Thinlet;
24

  
25

  
26
/**
27
 * A Thinlet directory chooser dialog.
28
 *
29
 * <p>
30
 * The dialog is modal and blocks the calling frame/dialog. It is therefore
31
 * displayed in a separate window.
32
 *
33
 * <p>
34
 * <b>TODO:</b>
35
 * <ul>
36
 *   <li>Button "Create directory"</li>
37
 * </ul>
38
 *
39
 * <p>
40
 * <b>Implementation note:</b> This implementation uses
41
 * <code>javax.swing.filechooser.FileSystemView</code>, because it provides
42
 * directory information that looks more "native". This introduces a dependency
43
 * on Swing, but since ThinG requires JDK 1.4, Swing should be there anyway.
44
 * Only a minimal set of Swing classes is loaded while using
45
 * <code>javax.swing.filechooser.FileSystemView</code>; alas, the loading
46
 * of <code>javax.swing.UIManager</code> and <code>javax.swing.LookAndFeel</code>
47
 * can <i>not</i> be avoided, although no Swing beans are actually used.
48
 *
49
 * @author Dirk Moebius
50
 */
51
public class DirChooser
52
{
53
    //{{{ logging
54
    private static final Logger log = Logger.getLogger("thinletcommons");
55
    private static final boolean debug() { return log.isLoggable(Level.FINE); }
56
    //}}}
57

  
58

  
59
    private ThinletDialog dialog;
60
    private Thinlet thinlet;
61
    private File selectedDir;
62
    private File expandDir;
63
    private boolean isInitialized = false;
64
    private FileSystemView fsv = FileSystemView.getFileSystemView();
65

  
66

  
67
    public DirChooser(Frame owner, String title)
68
    {
69
        this.dialog = new ThinletDialog(owner, title);
70
        init();
71
    }
72

  
73

  
74
    public DirChooser(Dialog owner, String title)
75
    {
76
        this.dialog = new ThinletDialog(owner, title);
77
        init();
78
    }
79

  
80

  
81
    private void init()
82
    {
83
        thinlet = new AntiAliasedThinlet();
84

  
85
        try
86
        {
87
            Object panel = thinlet.parse("/thinletcommons/dirchooser.xml", this);
88
            thinlet.add(panel);
89
        }
90
        catch(Exception e)
91
        {
92
            log.log(Level.SEVERE, "Error parsing dirchooser.xml", e);
93
        }
94

  
95
        dialog.setContent(thinlet);
96
    }
97

  
98

  
99
    /**
100
     * Show the modal dialog.
101
     * This halts the application until the user dismisses the dialog.
102
     */
103
    public void show()
104
    {
105
        selectedDir = null;
106
        if(expandDir != null)
107
        {
108
            expandTreeTo(expandDir);
109
            expandDir = null;
110
        }
111
        dialog.pack();
112
        dialog.setLocationRelativeTo(dialog.getOwner());
113
        dialog.setVisible(true);
114
    }
115

  
116

  
117
    public void setSelectedDirectory(File dir)
118
    {
119
        this.expandDir = dir;
120
    }
121

  
122

  
123
    public File getSelectedDirectory()
124
    {
125
        return selectedDir;
126
    }
127

  
128

  
129
    //{{{ callbacks for dirchooser.xml
130
    /** Thinlet callback. */
131
    public void init(Object tree)
132
    {
133
        if(debug()) log.fine("in init()");
134
        if(!isInitialized)
135
        {
136
            addFiles(fsv.getRoots(), tree);
137
            isInitialized = true;
138
        }
139
    }
140

  
141

  
142
    /** Thinlet callback. */
143
    public void ok(Object tree)
144
    {
145
        Object node = thinlet.getSelectedItem(tree);
146
        if(node != null)
147
            selectedDir = (File) thinlet.getProperty(node, "file");
148
        close();
149
    }
150

  
151

  
152
    /** Thinlet callback. */
153
    public void close()
154
    {
155
        dialog.setVisible(false);
156
    }
157

  
158

  
159
    /** Thinlet callback. */
160
    public void nodeExpanded(Object tree, Object node)
161
    {
162
        File file = (File) thinlet.getProperty(node, "file");
163
        // remove all existing nodes below the selected node (including
164
        // dummy placeholder nodes)
165
        thinlet.removeAll(node);
166
        // re-add subdirectory nodes below current node
167
        File[] files = fsv.getFiles(file, false);
168
        addFiles(files, node);
169
    }
170
    //}}}
171

  
172

  
173
    //{{{ private methods
174
    private void addFiles(File[] files, Object parent)
175
    {
176
        sort(files);
177

  
178
        for(int i = 0; i < files.length; ++i)
179
        {
180
            File file = files[i];
181
            if(fsv.isTraversable(file).booleanValue())
182
            {
183
                // it's  directory; create a node for it
184
                Object node = createNode(file);
185
                thinlet.setBoolean(node, "expanded", false);
186
                thinlet.add(parent, node);
187

  
188
                // create a placeholder node for the (possible) children of
189
                // the directory
190
                Object placeholder = Thinlet.create("node");
191
                thinlet.setBoolean(placeholder, "expanded", false);
192
                thinlet.setString(placeholder, "text", "#Placeholder#");
193
                thinlet.add(node, placeholder);
194
                //thinlet.putProperty(node, "hasDummyChild", Boolean.TRUE);
195
            }
196
        }
197
    }
198

  
199

  
200
    private Object createNode(File file)
201
    {
202
        Object node = Thinlet.create("node");
203
        thinlet.setString(node, "text", fsv.getSystemDisplayName(file));
204

  
205
        Icon icon = fsv.getSystemIcon(file);
206
        if(icon != null)
207
            thinlet.setIcon(node, "icon", convertIconToImage(thinlet, icon));
208

  
209
        thinlet.putProperty(node, "file", file);
210
        return node;
211
    }
212

  
213

  
214
    private void sort(File[] files)
215
    {
216
        if(files.length == 0)
217
            return;
218

  
219
        // don't sort if first file is a special (non-disc) file
220
        File firstFile = files[0];
221
        if(fsv.isComputerNode(firstFile) || fsv.isDrive(firstFile)
222
            || fsv.isFileSystemRoot(firstFile) || fsv.isFloppyDrive(firstFile)
223
            || fsv.isRoot(firstFile))
224
            return;
225

  
226
        Arrays.sort(files, new Comparator()
227
        {
228
            private  Collator collator = Collator.getInstance();
229

  
230
            public int compare(Object obj1, Object obj2)
231
            {
232
                return collator.compare(
233
                    fsv.getSystemDisplayName((File)obj1),
234
                    fsv.getSystemDisplayName((File)obj2)
235
                );
236
            }
237

  
238
            public boolean equals(Object other)
239
            {
240
                // unused
241
                return false;
242
            }
243
        });
244
    }
245

  
246

  
247
    private void expandTreeTo(File file)
248
    {
249
        Stack stack = new Stack();
250
        stack.push(file);
251
        File root = null;
252
        File parent = file;
253

  
254
        // find root, fill stack
255
        do
256
        {
257
            parent = fsv.getParentDirectory(parent);
258
            if(parent != null)
259
            {
260
                stack.push(parent);
261
                root = parent;
262
            }
263
        } while(parent != null);
264

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff