JColorChooser and Localization - swing

I'm trying to debug an issue where I'm using a JColorChooser. I'm trying to set the local, but it keeps reverting back to the System's Locale despite what UIManager, Locale.setDefault, or JColorChooser.setLocale I set it to.
The locale that I'm setting the JColorChooser differs from the System locale. The rest of my applet is using the requested UI.
I've tried the following:
JColorChooser colors = new JColorChooser();
colors.setLocale([spanish]);
Locale.setLocale([spanish]);
UIManager.getDefaults().setDefaultLocale([spanish]);
However, none of those options changes the component.

EDIT
as I mentioned earlier (below :-), JColorChooser (and most other localizable pre-fabricated components) locale support is suboptimal (aka: buggy). Setting its locale property directly simply doesn't work. Per-application setting worksforme (my system default is German), though:
Locale.setDefault(new Locale("es"));
Do so very early in the application code, best before creating any component, gives the best chances to get the expected non-system localized texts.
Original answer (having ranted a bit)
Localization support in Swing is half-hearted, to put it mildly.
Part of the problem is an impedance mismatch between the locale resolve mechanism between AWT vs Swing: the former resolves up the parent chain, expecting most of the children to have a null locale property, the latter explicitly sets the default as returned by JComponent.getDefaultLocale() very early in its life (in JComponent constructor). The other part of the problem is that a setLocale fires a change event as appropriate .. but nobody listens. That has dramatic consequences for pre-fabricated containers like f.i. JColorChooser: the ui delegate should update the locale property of all children but simply does nothing. (It's easy to overlook - SwingX components like datePicker had the same problem, hopefully fixed now ;-)
What is even worse: for some reason, the ui doesn't even respect the default as set on JComponent ...
So, the only way to make it completely respect any locale seems to be to set the default locale on Locale and then restore it afterwards (if you want to have only the color chooser in that locale, which I don't think is what you want :-)
Locale old = Locale.getDefault();
Locale.setDefault(new Locale("es"));
JColorChooser chooser = new JColorChooser(Color.RED);
Locale.setDefault(old);
ahhh .. all panels (DefaultXXChooserPanel) installed by the ui are buggy in that they get the localized text by
// wrong:
UIManager.getString(somekey)
instead of
// correct
UIManager.getString(somekey, appropriateLocale)

Related

What should be done to get around or resolve the PrimeFaces exception requiring the definition of a lazy attribute or one that doesn't result in null?

I am in the progress of upgrading a legacy application from PrimeFaces 6.2 to 11.0.0 (which is the newest available with maven - https://mvnrepository.com/artifact/org.primefaces/primefaces). I have had to make a number of changes, including adding Object as the parameter for RowEditEvent and TreeNode objects (which are now generic) and changing instantiations of DefaultStreamedContent to use .builder(). Now, I am facing the following error whenever I try to run the application and navigate to certain pages:
"javax.faces.FacesException: Unable to automatically determine the lazy attribute. Either define the lazy attribute on the component or make sure the value attribute doesn't resolve to null."
It looks like an exception is being thrown rather than a warning as is noted in the conversation here: https://github.com/primefaces/primefaces/issues/8436. It also looks like it was fixed, but for version 12 (which is not on the maven central repository).
I am wondering what my options are, or what could be done about this. Should I go back to an older version?
As a workaround you could create an application factory which sets the lazy attribute to false.
See: https://primefaces.github.io/primefaces/11_0_0/#/core/globalattributes
Is it a lazy DataTable which uses LazyDataModel? If yes, just set lazy=true, otherwhise set lazy=false

Set Locale in Worker

I am using a worker to do some tasks in the background.
When I try to use libraries that depend on the locale (e.g. use spark.formatters.DateTimeFormatter) I notice that they fail, since the locale in the worker is not set at all (e.g. dateTimeFormatter.actualLocaleIDName is null).
How do I set the locale in the worker?
Things I tried that don't work:
FlexGlobals.topLevelApplication.setStyle("locale",LocaleID.DEFAULT);
FlexGlobals.topLevelApplication is null
StyleManager.getStyleManager(null) also returns null, making it impossible to set the property there
StyleManager.getStyleManager(this.moduleFactory) null once more
Things that work but do not solve the problem for me:
Setting the locale style property manually on all DateTimeFormatter etc. instances. This would mean modifying third party library code and maintaining a fork ourselves.
Thanks!
Michael

Is there a way to force the UWP RichEditBox use only UTF encoding when the user types?

I am trying to convert the contents of a UWP RichEditBox to HTML.
For that purpose, I've tried using the RtfPipe library (https://github.com/erdomke/RtfPipe). From the looks of it, this library has a problem on UWP, due to the fact that not all encodings are defined on that target framework. (This is the error you get, if you are interested: Encoding.GetEncoding can't work in UWP app, but the accepted answer seems not to be the best option on all platforms - I haven't even managed to make the suggested fix compile, so it might not be valid anymore)
Now, as a way of avoiding this from happening, I am wondering whether there is a way to force the control to always use one of the UWP-defined UTF-variants for encoding the data when the user types his text.
Because, now, when I type into it, I get things like that:
{\rtf1\fbidis\ansi\ansicpg1253\deff0\nouicompat\deflang1032{
....
\pard\tx720\cf1\f0\fs23\lang1033
...that make the library throw exceptions.
I guess, if I manage to make it not use ASCII code pages, things will be great.
After taking a look at the control properties though, I do not see something I could use. Is there any way to achieve this?
This is the error you get, if you are interested: Encoding.GetEncoding can't work in UWP app
As you described, there is an inner error thrown when using this package with UWP app. System.ArgumentException: 'Windows-1252' is not a supported encoding name, by testing on my side, which is thrown by the code line public static readonly Encoding AnsiEncoding = Encoding.GetEncoding("Windows-1252"); of RtfSpec.cs when UpdateEncoding.
It seems like Windows-1252 may not be supported in UWP from the error details,also see this similar thread. You could use UTF instead as you want, for example, have a change on the library with following then it will work (testing demo here).
public static readonly Encoding AnsiEncoding = Encoding.UTF8;
I haven't even managed to make the suggested fix compile, so it might not be valid anymore
Encoding.RegisterProvider method should be work, but it only support UWP or .NET Framework 4.6, it does't support the Portable Class Library. The RtfPipe library you mentioned is Portable Class Library, so that you cannot use Encoding.RegisterProvider. Encoding.GetEncoding method supports Portable Class Library, details please check the version information of the two classed.
I guess, if I manage to make it not use ASCII code pages
RTF itself uses the ANSI, PC-8, Macintosh, or IBM PC character set to control the representation and formatting of a document, you may not able to change that. Consider to update the library to resolve the issue for UWP.

Custom JSON renderer in AEM/Sling

I've been playing around with this for a while now, and I think, I've - almost - cracked it, but I am still not fully satisfied with my solution.
So, what I want to do, is having a piece of content, a list of items, which would have two views: The standard HTML one, so people can view and edit it; and then a JSON endpoint for other services to consume.
First I thought it's a simple matter of creating two JSP scripts to render the content:
/apps/my-stuff/components/list-page/html.jsp
/apps/my-stuff/components/list-page/json.jsp
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
As a second attempt, I created another script, in /apps/foundation/components/primary/cq/Page/json.jsp which will be actually called, and renders the page, as I expected. However there are a couple of worries/questions regarding this:
First of all, why is this being honoured by the system, and not the one in the more specific place?
The documentation states, that to find the appropriate renderer, first sling:resourceType will be inspected, then sling:resourceSuperType and then, only as a fallback will jcr:PrimaryType checked. However I think this is rather: jcr:PrimaryType, then the DefaultServlet, and then all the other things.
Most worryingly however, I have to admit, this is rather generic, so it'll break all the contnet with jcr:PrmaryType = Page, so that could have some side-effects.
A solution could be creating a new type: ListPage extends Page; and then create a renderer for that in /apps/foundation.... However I have this bad feeling, that might introduce other problems.
So my question is two fold: What is the proper way of doing this, and/or what am I missing from the way the URL -> script resolution is working in AEM/Sling. (Because it seems to be slightly different that described here and here.)
(Obviously I am trying to keep the default JSON renderer for other pages, as that might be needed for other things in the page. I am not even sure, changing this one page won't break the UI for this particular page...)
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
Have you tried renaming your JSP like so: "list-page.json.jsp"?
If you're using AEM 6.3, you should look at Sling model Exporters. They allow you to automatically register a servlet against your Sling Model (that you can create to model your list content). That servlet can generate a JSON representation of the model for you using Jackson.
If you're not using AEM 6.3, I would suggest you create a servlet registered against your resource type and use an additional selector.
#SlingServlet(
selectors = "json",
resourceType = "my-stuff/components/list-page",
methods = "GET")
More information on Sling Servlets can be found here.

Is it possible to reflect changes in portal-ext.properties without restarting whole Liferay portal?

My problem is every time after changing the Liferay portal-properties (and this is frequent especially at beginning of a new portal project) I need to restart the whole portal.
Some properties I can set over hook and these values will be changed after redeployment. Also that must be possible to change most portal properties at run time.
However, do you know some approach to reflect changes in portal-ext.properties without restarting Liferay portal?
As stoldark mentioned, this is not possible in a production environment at all. Since portal.properties's properties are loaded at portal start-up.
But for development you can use a tool like JRebel, some steps to configure it here. The only issue you would get with this tool is that it is paid ;-).
I know it is a very old thread but it may be helpful for someone who is looking for some type of work around
As we know there is no straight forward way for this but I did this by using java reflection and class loader.
Liferay Version : 6.x
//Loading the PropsUtil class by using PortalClassLoader
Class<?> prospsUtilClass = PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.util.PropsUtil");
//getting the reload method of PropsUtil class
Method reloadMethod = prospsUtilClass.getMethod("reload", null);
//Invoking the static reload method
reloadMethod.invoke(null, null);
Reload method (re)loads the portal-ext properties to the portal so we can use new properties without restarting Liferay server.
This has also been asked in Liferay forums:
https://www.liferay.com/community/forums/-/message_boards/message/800954
But I am afraid that most properties are only read once during portal startup.
Usually, the use of a properties file as in this case has this drawback.
There's even an issue open at Liferay about this, but is still unresolved:
http://issues.liferay.com/browse/LEP-5579
If you create a hook to override portal properties, you will be able to change properties with just deploying the hook without restarting the Portal.
Be aware that you cannot modify all properties with a hook. For a list of the ones that you can modify, check out: https://docs.liferay.com/portal/6.2/definitions/.
I've just searched for reloading portal-ext.properties and landed here.
Ok - not a feature in Liferay.
So I'll use an old trick I like:
place custom properties in (liferay-tomcat-home)/conf/filename.properties
reload them whenever you want by
Properties customProperties = new Properties();
customProperties.load(new FileInputStream(new File(System.getProperty("catalina.base"), "conf/filename.properties")));
I must confess I haven't tried this in a Liferay-Portlet-Environment, but this system property ("catalina.base") should be available in this context, at least by using some Liferay-Helper-Class.
Some of the Liferay classes read their properties when initialising static field constants. E.g.:
public static final boolean ENABLED = GetterUtil.getBoolean(
PropsUtil.get(DynamicCSSFilter.class.getName()));
Basically, it is possible to reload the properties (eg via script in control-panel), but all those static constants will remain.