-
Notifications
You must be signed in to change notification settings - Fork 0
How do I use this?
Here's how you use this library; please reference the Tutorial.java file in the test package for a specific use case of the library. Some of the library is commented, but these comments may be out of date or non-existent due to the ongoing nature of development and my lack of effort to thoroughly comment it; I will get around to that eventually.
As its base, this library uses the javax.swing suite of java ui tools, but builds on that foundation to obscure the many low-level complexities that have given me hell over the past three years.
To use this, take the svi.jar file and import it into your project. Boom, you're done. (Your IDE should have a place for importing or configuring your build-path, so that's where you should be able to see that it has been imported. Eclipse would be Project > Properties > Java Build Path > Libraries > Add External Jar > Navigate to the svi.jar and select it. Done!).
The library functions, to its user, by allowing the creation of custom Frames and Panels. Frames house Panels, as well as starting the timer object to repaint the component regularly. WindowFrame is the only Frame subclass you can instantiate, and can be used naively by only adding Panels to it with the addPanel(panelName, panel) function, or can be used to its full capacity by making multiple 'Windows' within it that Panels can be assigned to, allowing the hiding and showing of groups of Panels at once (via addPanelToWindow(windowName, panelName, panel). A 'default' window is present by default to whom Panels are added if using the naive approach.
There are two subclasses of Panel, only one of which is really for general use. ElementPanel is a Panel subclass that has many functions for adding Lines, Rectangles, Images, Buttons, Text, Text-Entry, and Animations to its view with their own unique sets of data required to specify how they should behave. These functions generate Element objects which the ElementPanel stores to draw whenever its Frame tells it to repaint. After you add one of these, you can move or remove it by referencing the name you provided; otherwise, the ElementPanel handles everything for you.
There is also a CanvasPanel, which is a very specific behaving Panel for drawing art that I made for an art program I'm working on; it likely has additional uses outside of that, but its specific behavior makes it less suitable for varied purposes.
When using the functions to add Elements to an ElementPanel, several common arguments are present: name, priority, frame, x, and y.
The name is the String representation by which the ElementPanel is able to refer to the Element.
The priority is an integer value used to describe the order in which elements are drawn; lower value priorities are drawn first, making them appear underneath other Elements with higher priorities.
The frame argument is a boolean describing whether or not the Element should have its position offset when the Panel's origin point is moved (such as when a scrollbar is used to navigate a page vertically or horizontally). If frame is true, then the Element will not have its position change. If frame is false, it will be moved when the origin changes; this allows for specific UI elements to always stay in place despite other Elements moving.
The x and y variables are integer values describing the position of this ElementPanel within its encompassing Frame.
These functions also take many other arguments that refer to that Element's appearance, such as the addImage function taking a String or Image object specifying the directory to access the Image from or what Image to use specifically. These functions are also usually overloaded, with variants allowing for different information to specify their appearance; addImage can have the image's drawn width and height be specified, or have a double value be given to scale that image by the given proportion.
Buttons and TextEntry Element objects are important (implementing the Clickable interface), as these can be interacted with by the user. Buttons are placed in a specified location and given a code value that, upon being clicked, will be sent to the ElementPanel object in its function clickEvent to process it for back-end purposes. Most input from a button is then passed to the function clickBehaviour, which YOU HAVE TO OVERRIDE when instantiating your ElementPanel object to provide responsive behaviours to your program. There are several such 'behaviour' functions that allow for the program to react to the user, such as clickBehaviour, clickReleaseBehaviour, clickPressBehaviour, dragBehaviour, keyBehaviour, and mouseWheelBehaviour. These basically field a lower-level implementation of EventListeners so you can easily respond to specific user events. You need to override these during instantiation (see the Tutorial.java file for an example), which is a neat trick, or you can just extend ElementPanel in a new Class in your project and Override the functions that way.
(If they were abstract then you'd have to do an explicit class, and you don't always have to use all of them, so I figured this was an alright compromise as long as I explicitly told you about it).
TextEntry code values aren't explicitly used by you, but are used at a lower level to steal keyboard input when the TextEntry Element is selected (clicked on). Use the function getElementStoredText(name_of_textentry_element) to get whatever text has been passed to it.
Note of warning: Whenever you use an addElement function (addImage, addLine, etc.), if there is already an Element of that name present, it will overwrite that. While you don't have to put your addElement functions into a function that runs 30 times per second, you may want the view to update and change its contents; it's usually fine to add Elements with the same name as replacing them doesn't cause problems, but a TextEntry Element will have its contents erased by this; the moveElement function returns a boolean for whether or not the Element was found in the ElementPanel and will also 'move' your Element to the same or different place, allowing an easy means of only adding an Element if it isn't there or moving Elements without replacing them.
Which is why the composite class HandlePanel provides a simplified version of ElementPanel that always tries to move an Element before adding it. Check out that class for specific arguments; it also uses a default Font if null is passed to it, allowing for very rapid construction of small UIs. It also extends ElementPanel, so all the other functions are also available to you.
To update details of an Element that are not just its position, you will need to remove the element (removeElement(name)) and then add it again; there is also a function removeElementPrefixed(prefix) that will remove every Element whose name matches a regex operation of 'prefix.*'; any Element whose name starts with the given prefix will be removed, so Element naming should be hierarchical to allow you fine control of this. The exception to this is that there is a function setElementStoredText(elementName, newText) that can set the text of certain Elements (TextEntry), primarily for wiping a submission box after it was submitted. You could also remove and re-add it, would be pretty much the same (you can specify default text when adding a TextEntry).
Once you have designed your ElementPanel, you can add it to your WindowFrame by using the function addPanelToWindow(windowName, panelName, panel), or if you are using a single default window, addPanel(panelName, panel). If you are not using the default window, you will have to instruct the WindowFrame to showActiveWindow(windowName) to make those Panels visible; you also have hideActiveWindow(windowName) to make them disappear while still being available.
And that's it! Now you can start working on your project's UI with ease and comfort. The descriptions are long but, having used Java for a while to do visual work, this is a very useful tool to avoid having to get dirty with the user input functionality or keep track of your repaint/paintComponent functions while directly using a Graphics g object to draw basic shapes, let alone making sure that images would be added consistently across within-IDE program functionality and for exported-.jar program functionality.
There is more than just this, such as FileChooser, PopoutWindow, and Config classes that provide more functionality to your project, but for a first instruction on using this, now would be a good time to get used to the basics before looking at the accessory details.
Please have fun with it, test it out, and let me know if there are any issues that you come across! This is far from perfect but there's a lot of good here I wanted to share with folks, hopefully it enables you to make something groovy and maybe even help me make it better.
Ada