Professional Documents
Culture Documents
A reference guide
0. A brief introduction
This guide will show you how to write basic fetch modi and widgets. To do more
complicated things than are described in this guide, it is advised that you learn
by example from the code available at github.com/gumptiousCreator/Sylladex-Captchalogue-Deck.
Determine whether the item can be added at all. For the HASHMAP modus,
this means calculating which card the item would be added to and
checking various variables, such as whether the card is empty and
whether detect collisions is enabled. STACK and QUEUE check whether
there is room, and eject a card if there is not.
Create the dock icon (a JLabel), assign it to the card, and add it to
icons. Update the dock icons.
Below is how it works in the STACK modus. The generic functions are suitable
for most modi, but if you want to treat each type of item differently, the
functions you need to override are called addItem(). They take either a File,
Image or String as the parameter, and won't call addGenericItem() if
overridden.
public void addGenericItem(Object o)
{
checkBottomCard();
SylladexCard card = m.getNextEmptyCard();
card.setItem(o);
stack.addFirst(card);
JLabel icon = m.getIconLabelFromObject(o);
icons.add(0, icon);
m.setIcons(icons);
card.setIcon(icon);
arrangeCards();
Note: there is no
reason why
showSelectionWindow()
should actually open a
window. You could, for
example, make a modus
which opens a random
card when the user
clicks on the dock.
This code
1. (internal) Removes the card's dock icon from the ArrayList of icons
2. (internal) Trims this ArrayList to its new size
3. (external) Updates the dock to reflect this change
4. (internal) Removes the card from the stack
5. (internal) Updates the positions of the cards on-screen.
Saving and loading without any other user input must not alter the order
of the items.
The number of cards in the deck is the number of non-blank lines. If this
number exceeds startcards, the modus should be able to grow to
match the number of saved items.
There are two other item files in use: hashmap.txt and tree.txt. These should
not be used by custom fetch modi. However, I have created a file called
array.txt, for which the requirements are:
The order of the items must not be important to a fetch modus using this
file.
The number of cards in the deck is the number of lines in the file, minus
one blank line at the end (added by DeckPreferences). If this number
exceeds startcards, the modus should be able to grow to match the
number of saved items.
If your modus does not meet the requirements for one of the default item files,
you must use your own.
When the program closes, DeckPreferences will request an ArrayList of
Strings, via the getItems() method. Here is what it looks like in the STACK
modus.
public ArrayList<String> getItems()
{
ArrayList<String> items = new ArrayList<String>();
if(stack.size()>0)
{
for(SylladexCard card : stack)
{
items.add(card.getSaveString());
}
}
else { items.add(""); }
return items;
}
}
}
m.setIcons(icons);
card.setIcon(icon);
arrangeCards();
The function which does all the messy work for you here is
Main.getItem(String). It is basically the reverse of
SylladexCard.getSaveString(), and returns a File, Image , String or
Widget object. It also deletes captchalogued_image_xxxxxxxxxxxxxxxxx.png
files and replaces SYLLADEX_NL with the system's line separator.
4. Preferences
preferences is an ArrayList of Strings which is ready by the time the
prepare() method is called. An ArrayList is hard to work with since you have
to keep track of which index refers to which preference. I find it helps to use an
enum for this purpose:
enum PrefLabels
{
SELECTED_MAPPING (0),
DETECT_COLLISIONS (1);
public int index;
PrefLabels(int i)
{ index = i; }
}
5. Animation
5.1 Using the built-in class
The Animation class provides a few basic animations. To use them, you need to
import sylladex.Animation.AnimationType. There are two types of
constructor.
public Animation(JComponent/SylladexCard comp, Point finalposition,
AnimationType type, ActionListener listener, String command)
public Animation(AnimationType type, int duration, ActionListener listener,
String command)
With the first constructor, you can create MOVE, BOUNCE and BOUNCE_SPOT
Version 2.0 (O)
animations. Each of these are two-frame animations which last for 100ms.
The second constructor is for WAIT 'animations'. These are just a simple way to
create timers. Whatever AnimationType you put in will be converted to WAIT;
it's included in the constructor simply to improve code readability.
You can animate any JComponent, or a SylladexCard.
command is the ActionCommand which is sent to the listener when the
animation completes.
Here's an example:
anim = new Animation(box, new Point(0,244), AnimationType.MOVE, this, "box");
anim.run();
run() starts the animation and stop() stops it (and moves the component to
its final position).
Chaining animations together is possible by setting the listener to another
animation, and the command string to run:
new Animation(box, new Point(0,244), AnimationType.MOVE, anim2, "run").run();
Part 2: Widgets
Widgets don't need a very large section. They don't have constructors; m is set
automatically before prepare() is called.
A few things to note:
prepare() is called when the widget is added to the deck by the user.
This is for first-time set-up.
load(String) is called when the widget is loaded (i.e. when the program
starts and loads an already-captchalogued widget).
This means that any initial set-up required every time the widget starts
must be performed by each of these functions. (I'd advise you create
your own set-up function and call it from each of the above.)
open() is called when the user tries to open the widget. If you want to
respond to mouse events on the widget, take a look at the code for
RPObject.
The return value of getString() is used by some modi (e.g. HASHMAP and
TREE) to determine which card to put the widget in. getSaveString()
should return data required to load the widget's current state. It is the
string passed back in again by load(String).
boolean isLinux()
boolean isMac()
boolean isTransparencySupported()
boolean isWindows()
DeckPreferences getPreferences()
Dimension getScreenSize()
int getDockIconYPosition()
JLabel getIconLabelFromObject(Object o)
JWindow getCardHolder()
SylladexCard getCardAtPosition(Point
position)
SylladexCard getCardWithIndex(int
index)
SylladexCard getNextEmptyCard()
void actionPerformed(ActionEvent e)
void addCard()
void
void
void
void
addItem(File file)
addItem(Image image)
addItem(String string)
addItem(Widget widget)
void hideDock()
void openWithoutRemoval(SylladexCard
card)
void refreshCardHolder()
void refreshDock()
void refreshDockIcons()
void setIcons(ArrayList<JLabel>
newicons)
void showDock()
You can call the WindowListener events, but NOTHING GOOD WILL COME OF IT.
SylladexCard
boolean isAccessible()
boolean isEmpty()
File getFile()
Image getImage()
String getString()
Widget getWidget()
int getHeight()
int getId()
int getWidth()
JLabel getIcon()
JPanel getForeground()
Point getPosition()
setAccessible(boolean accessible)
String getItemString()
String getSaveString()
void
void
void
void
void
addToCardHolder()
removeFromCardHolder()
setFile(File file)
setImage(Image image)
setString(String string)
void setItem(Object o)
void setLayer(int layer)
Preferences
ArrayList<String> getModusItems()
ArrayList<String> getModusPreferences()
boolean always_on_top_cards()
boolean always_on_top_dock()
boolean autohide_cards()
boolean autohide_dock()
boolean copy_instead_of_move()
boolean top()
boolean usb_mode()
FetchModus getModus()
void actionPerformed(ActionEvent e)
void createAndShowModusBrowser()
void showPreferencesFrame()
void windowClosing(WindowEvent w)
Animation
new Animation(JComponent comp, Point
finalposition, AnimationType type,
ActionListener listener, String
command),
new Animation(SylladexCard card,...)
JComponent getComponent()
void run()
void stop()
void actionPerformed(ActionEvent e)
Constructors.