GXT3: How to implement svg buttons - java

Using SVG icons has a lot of advantages over png/gif icons. As a result, I would like to implement a svg button class to act as a gwt widget. Is there already something existing in GXT 3? Or what would be the best option to implement such a widget? Thanks.
More Details:
I need a pure clickable svg icon act like a button widget. It needs to have mouse click handler and the ability to apply different css in three states: normal, hover, disabled. I do not want a button with a svg icon inside.

In browsers that support them, SVG can be used as if it was an image file (png/jpg/etc). GXT/GWT shouldn't make a difference, you just have to apply the image.
Rather than building your own widget (which is, of course, an option), you can use built-in widgets that can be told to use any image or css class (depending on the widget).
For example, GXT's TextButton has a setIcon method which takes an ImageResource. Typically these are created in a ClientBundle, but the code generation for GWT's ClientBundle doesn't know what SVG is.
The ImageResource interface has an implementation built in to GWT, ImageResourcePrototype, allowing you to specify all of the parameters required. The second parameter is a url, the path to an image, which will be rendered as long as the browser supports it. So, we need to get the SVG file you want to use into the ImageResourcePrototype.
ImageResource icon = new ImageResourcePrototype("icon", UriUtils.fromSafeConstant("/path/to/my.svg"), 0, 0, 20, 20, false, false);
TextButton button = new TextButton("square", icon);
RootPanel.get().add(button);
Now, you can do this by just passing in a normal URL, but then we're no better than a normal image, since we still need a round trip to the server - most icon buttons are only a few kb, but the overhead of an HTTP call can be that bad, so your SVG will be just as bad. Thankfully all built-in ImageResources in GWT are already bundled into the app, so no HTTP calls are needed. It turns out we can also bundle our svg file, though we need to get it just right for the browser to handle it.
Put the SVG file in your source with your Java, and we'll make a bundle out of it. I put this very boring icon into a file called icon.svg:
<svg width="50" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
</svg>
Next, use it in our app. I made an entrypoint that just grabs this icon and puts it into a button. We use DataResource here to refer to the file as a data url from inside our app, but we need to specify the mime-type correctly for the browser to understand that it is an image:
public class SampleIconEntryPoint implements EntryPoint {
interface Bundle extends ClientBundle {
#Source("icon.svg")
#MimeType("image/svg+xml")
DataResource icon();
}
#Override
public void onModuleLoad() {
Bundle bundle = GWT.create(Bundle.class);
ImageResource icon = new ImageResourcePrototype("icon", bundle.icon().getSafeUri(), 0, 0, 50, 50, false, false);
TextButton button = new TextButton("square", icon);
RootPanel.get().add(button);
}
}
This could be made easier by adding support for .svg files to the ImageResourceGenerator in GWT, but this turns out to not be a very common use case.
Okay, so what does SVG have over raster images? For large images, a lot! They can be much smaller for the same level of detail since they stretch nicely, but for small icons, it can be hit or miss. It is easier to change some details about them on the fly, but that's really outside the scope of a question addressing how to use SVG in gwt (see GXT's chart/draw library for lots of easy SVG render tools), and doesn't often matter for a single image on a button. Icon images are small, and saving a few bytes here and there is probably not an efficient use of time - plus, SVG takes more time to render in the browser than much-simpler images (though again, the difference will be minimal for very small browsers).
Edit, trying to address the question edit instead of the original point.
SVG elements are nearly normal dom elements, though check what browsers you need to support to ensure that they will work correctly. https://developer.mozilla.org/en-US/docs/SVG_In_HTML_Introduction gives a quick introduction on how the elements need to be built to correct namespace them so that the browser will work with them correctly. Beyond that, they behave roughly as normal dom elements in GWT. I would generally suggest that you treat them like normal dom elements in GWT, and so your widget should not attach handlers to child elements but just use addDomHandler as normal on each widget. Given the ability of svg elements to overlap each other (based on order in the dom), you might consider other ways of seeing which element is on top of others if you need to know exactly what the mouse is over (though for a button, this shouldn't matter).
As mentioned above, GXT's draw tools provide a DrawComponent class which can use SVG and let you get events that happen to each drawn sprite, plus normalize for different browser issues (support canvas if possible, or VML if necessary).

Related

Libgdx - Remove HTML greybackground/recompile button/ load splash

What is the proper way to remove the grey background that covers the entire screen, the recompile button, and the default libGDX load and/or load splash in a HTML build of my game?
Note: This answer applies only to the gdx-setup tool as of late 2022. The gdx-liftoff tool is similar but has a slightly less boneheaded configuration out of the box. Additionally, I would like to get some of libGDX's HTML backend reworked one day, as there is no point in the padding and it's applied unevenly, plus less obvious things like the way it creates a table for layout.
Grey background
The background colour can be customised by changing background: #222222 in html/webapp/styles.css to some other colour. Or apply it directly to the body in index.html and delete styles.css (plus the link to it) as it doesn't contain anything important once the superdev button has been removed.
Grey border
The border around the game can be removed by editing HtmlLauncher like so:
#Override
public GwtApplicationConfiguration getConfig () {
GwtApplicationConfiguration config = new GwtApplicationConfiguration(true);
config.padHorizontal = 0;
config.padVertical = 0;
return config;
}
Separating GwtApplicationConfiguration into a config variable brings it in line with the other launchers (desktop, Android, iOS) and setting the padding to 0 is self-explanatory. While we're here, passing true into the app config's constructor tells it to render at native resolution on high-DPI/"retina" displays instead of upscaling.
Recompile button
Or the superdev button, as I call it. Just remove the <a class="superdev"... line from html/webapp/index.html. If you need access to it during development, it's recommended you add its link to your bookmark bar. Visibility of the bookmark bar can be toggled using Ctrl+Shift+B in Chrome and Firefox.
Load/splash screen
You're probably best referring to https://libgdx.com/wiki/html5-backend-and-gwt-specifics#changing-the-load-screen-progress-bar for this (which may not have existed when the question was asked). In short, getPreloaderCallback() and adjustMeterPanel() can be overridden in HtmlLauncher. I typically just overwrite logo.png after building instead of using the recommended method for changing the logo.
Other changes
Things you might want to change before a final release:
styles.css isn't very important beyond changing the background colour, as noted earlier.
In index.html, a comma should be added to between device-width and initial-scale for it to be valid HTML.
In index.html, applying align="center" to a div is deprecated behaviour. Probably best remove that alignment. If you need it, apply via CSS instead.
In index.html, handleMouseDown() and handleMouseUp() are completely pointless, as far as I can see. I don't use them for my own projects and have had no complaints.
html/build/dist/assets/assets.txt references some files that may not be necessary. The default font (arial or lsans, depending on libGDX version) is only needed if you use it and the vertex/fragment shaders are only needed if you do 3D stuff, I believe. Removing these can remove load times ever so slightly, especially on HTTP/1.1 connections. But I don't have an automated way to remove those lines (except on Linux - head -n -8).
Setting an asset filter as seen at https://libgdx.com/wiki/html5-backend-and-gwt-specifics#speeding-up-preload-process is an easy way to reduce your load times. I return false for music files to reduce load times greatly - it ends up streaming music instead of preloading it (if using Music, not AssetManager).

setBackgroundColor pdfBox Java

I want to change the background color of an already present pdf to transparent or white,
and I am using pdfBox for performing other tasks on the pdf, I found some documentation here:
setBackroundColor - pdfBox
But I am completely unaware of how to use it as I am not accustomed to java.
Can someone possibly provide some example code on doing it ?
I want to change the background color of an already present pdf to transparent or white
According to the PDF specification ISO 32000-1, section 11.4.7:
Ordinarily, the page shall be imposed directly on an output medium, such as paper or a display screen. The page group shall be treated as an isolated group, whose results shall then be composited with a backdrop colour appropriate for the medium. The backdrop is nominally white, although varying according to the actual properties of the medium. However, some conforming readers may choose to provide a different backdrop, such as a checker board or grid to aid in visualizing the effects of transparency in the artwork.
PDF viewers most often do use this white backdrop. Thus, if your PDF on standard viewers displays a different color in the back, this normally is due to some area filling operation(s) somewhere in the page content stream.
Thus, there is not a simple single attribute of the PDF to set somewhere but instead you have to parse the page content, find the operations which paint what you perceive as background, and change them. There are numerous different operations which may be used for this task, though, and these operations may also be used for other purposes than background coloring. Thus, there is not the method to change backgrounds.
If you have a single specific PDF or PDFs generated alike, please provide a sample document to allow helping you to find find a way to change the perceived background color.
PS: The PDLayoutAttributeObject.setBackgroundColor method you found refers to the creation of so called Layout Attributes which
specify parameters of the layout process used to produce the appearance described by a
document’s PDF content. [...]
NOTE The intent is that these parameters can be used to reflow the content or export it to some other document format with at least basic styling preserved.
(section 14.8.5.4 in the PDF specification ISO 32000-1)
Thus, they are provided only in PDFs intended for content reflow or content export and are not used by regular PDF viewers.

SMS Balloons / Long Chat Boxes

I want to be able to add a text-messaging balloon every time the user revives data from a HttpGet, I want it so that it looks nearly identical to the default Android text messaging UI. I'm fine with all the code, I just need a way to create the UI and create another text balloon every time data comes back from a HttpGet request.
Thanks ever so much, for the answering this questions and I'm sure there's an easy way to do it, yet I've found no way by using the 'ole Google.
I am doing something similar for my app am doing the following to achieve it:
You will need a 9-Patch-Image (a stretchable PNG, see here) that represents the bubble. You want to make the part stretchable that does not include the corners of the bubble. You can create the bubbles using an image editor of your choice (I'd recommend a vector graphics editor like Inkscape). Then use the 9-Patch editor included in the Android Developer Tools to transform the PNG image into a 9-Patch PNG.
Create a custom layout file for one bubble. Create a textview inside it, and add your bubble as a background resource. (android:background)
Use an arraylist with a custom adapter to inflate and fill your items.
So far, this will give you identical bubbles as background for all messages.
If you want to get fancy, you can create different bubbles for participants, and use the setBackgroundResource method in your Adapter to set the correct background.
Further, if you wish to align them left or right, like in the message app, you will need to add spacers to the left and right of your TextView in the layout file. I used FrameLayouts with a fixed width. Make sure to set their visibility to GONE.
As with swapping the different bubble colors, just set the visibility of the left/right spacer.

HTML gallery page in Swing with drag-drop functionality

I was asked to write a JDialog separated into left and right panel. The left panel shows a demo HTML template gallery (small sized), and right panel shows series or list of images. I want to make it such that I can drag image on the list and place it on the gallery (or maybe drag out some image from the gallery). The problem is I don't know where to start with this, can anybody give me some idea?
An HTML gallery typically uses JS to do the 'heavy lifting' (I'm guessing it will require a slideshow as well). While Swing components support HTML (to an extent) they do not support JS.
I recommend not trying to render the HTML/JS in the GUI, instead, provide a JList in the GUI of the image+name objects chosen by the user (using JFileChooser). When each image is selected, you can show the 'preferred name' in a JTextField that allows the user to edit it.
Image order can be shown by the order in the list. To change the order, implement Drag'n'Drop. See the Drag and Drop and Data Transfer lesson for more details.
You will probably need a JLabel in the CENTER of the GUI to display the (full size) selected image, and show the order & timing of the slideshow.
Once the user is happy with the image selections, the order, the names & timing. Offer them a button to write all the details to a single directory including the HTML, script & images (easier). Once the HTML is written, invoke Desktop.open(File) to display the finished product to the user.
As to how you do all that, it is really beyond the scope of an answer on SO. You would need to do the tutorial on each part, and come back with more specific questions.

Alternatives to JEditorPane & HTMLEditorKit - too slow

I'm trying to implement a basic text editor with options for font, bold, italic, underline, and color. I've used JEditorPane and the associated HTMLEditorKit but when I load a 400K document it takes a full minute to load and most editing takes several seconds.
I've had a similar experience and what I did was to get the JEditorPane to only show a page sized window onto the 400K document (if this is possible in your situation) and then manually deal with scrolling issues.
That way I got a lot of cool functionality from the widget without the massive slowdown (cos the widget only saw part of the text), but I had to write a load of scroll code and keep updating the widget contents as users moved around.
Plus I was doing it so I could view 7G files, which were not going to fit in an memory I had anyway.
http://java-sl.com/JEditorPanePerformance.html
May be some of the tips could help you to make it a bit faster. I would also recommend to write your own EditorKit based on e.g. StyledEditorKit with all necessary attributes support (see for example http://java-sl.com/editor_kit_tutorial.html).

Categories

Resources