I started using ANTLR, but the javascript support is not very strong, so I turned to PEGJS, which seems to do what I need. PEGJS is full Javascript, even the generator.
Lots of choices around. Not yet tested. I list the points which are important to me for writing hieroglyphic software, so your milleage may vary a lot.
Made by the original author of Raphaël, taking advantage of modern browsers SVG support.
Kevin Lindsey has a great site on SVG, with much javascript code, and in particular a huge list of intersection routines.
A nice opentype/truetype font library. It can do many things, such as interpreting ligatures correctly (which java/Swing doesn't do in the general case, for instance).
Huge framework for displaying and processing pictures on the Web. Manages very high resolution pictures.
Clients are usually using javascript, but servers are available in a number of languages.
A number of examples are available to browse.
Rich Library (one among many others) for Map manipulation and annotations.
Generic annotation framework... looks cool. I need to test it someday.
Another annotation tool, from the University of Caen.
Side-margin annotation tool library.
Javascript library for implementing inline code editors.
]]>When learning javafx, I have liked a number of things, and in particular the consistence of the naming and MVC mechanism (vs. the multiplicity of mechanisms used by Swing).
However, two points bothered me:
Suppose you have a component which must display lots of data. It might be a text component loading a whole book, a detailled map for a large zone, or a tabular-like display.
Typically (but not always) this zone will be embedded in a scroll panel.
The normal Node-oriented solution of Java FX supposes you create nodes for each item you want to display. But it's too much considering the amount of data you have. What you want is to create nodes only for the data which is currently displayed.
A number of solutions are available (https://github.com/TomasMikula/Flowless for instance) but I wanted to see how to code them from the ground up.
The JavaFX ScrollPane is not very useful there: it doesn't send events to its children (or at least, not automatically) when it is scrolled.
In Swing, any object, even if it is very large, can benefit from a JScrollPane. A good use of revalidate and a redefinition of getPreferredSize are sufficient. For JavaFx, Scrollbars work correctly on small objects, but an object in a ScrollPane is completely unaware of the said scrollpane.
As a result, partial drawing is difficult. Having looked at FlowLayout and FLowless implementation, the solution chosen by those two classes is to integrate the scrollbar in the component itself. That way, the component can listen to scrollbars modifications, and react accordingly.
Usually, very large components are used for text or grids... those are complex classes. As a result, the code related to virtual component management is difficult to separate from the rest of the class, and the learning process is more complex than necessary.
As a matter of fact, I was unable to find any tutorial on the subject (admitedly, it's not something programmer...
]]>Voilà quelques remarques sur la chose:
La classe ‛MockMvcBuilders‛ permet de construire deux types de tests:
stand-alone : on ne crée pas d'environnement spécial, et on peut travailler en test unitaire sans faire d'injection de dépendance.
en contexte : on met en place un environnement, avec injection de dépendance et tout. C'est moins unitaire, et plus proche d'un test d'intégration.
En gros, pour tester un ‛@Controller‛ de Spring MVC, on le crée à la main (avec un new), et on simule des requêtes1:
import org.junit.*;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.hamcrest.Matchers.*;
public class UserManagementControllerTest1 {
@Test
public void testAskForAccountGet() throws Exception {
MockMvcBuilders.standaloneSetup(new UserManagementController())
.build()
.perform(MockMvcRequestBuilders.get("/user/ask").accept("text/html"))
.andExpect(status().isOk())
.andExpect(view().name("template"))
.andExpect(model().attribute("content", hasProperty("main", equalTo("user/ask"))));
}
}
Quelques remarques sur le test:
Dans le cas de pages rendues en JSP (j'y reviendrai) nous avons un problème: ce qu'on peut tester, c'est le nom de la vue, et les données renvoyées dans model.
Vous remarquerez que, dans mon cas, je peux même tester les propriétés d'un objet passé dans le modèle (notez :
.andExpect(model()
.attribute("content",
hasProperty("main", equalTo("user/ask"))));
Dans le cas où l'API fluide ne vous convient pas (par exemple, vous voulez tester des propriétés un peu complexes des objets du domaine, vous pouvez terminer votre appel par ‛.andReturn()‛, et récupérer l'objet, de type ‛MvcResult‛, qui vous est renvoyé. Il donne accès à la vue, au modèle, etc.
Ça ressemble au test "stand-alone", sauf qu'on doit mettre en place l'environnement Spring normal.
Chez moi, ça donne ça:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfig.class, AppConfig.class, MyWebConfig.class, })
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class
})
@WebAppConfiguration
public class UserManagementControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Test
public void testAskForAccountGet() throws Exception {
MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build()
.perform(MockMvcRequestBuilders.get("/user/ask").accept("text/html"))
.andExpect(status().isOk())
.andExpect(view().name("template"))
.andExpect(model().attribute("content", hasProperty("main", equalTo("user/ask"))))
;
}
}
C'est beaucoup plus long à démarrer (même si la configuration que j'utilise prend une base de données de test). La logique est un peu différente : on ne crée pas un objet lié au contrôleur, mais un objet qui simule l'interface web; on lui envoie ensuite des requêtes.
Du coup, on peut simuler une série de requêtes sur des pages diverses.
Notez que les problèmes liés aux JSP restent intacts.
Le problème des JSP, c'est qu'elles ne sont pas traitées par Spring. En gros, la ‛DispatcherServlet‛ de Spring, quand elle a déterminé le nom de la vue et injecté les données du modèle,...
]]>Equals and inheritance play dirty tricks. I have recently met a problem in my hieroglyphic processor with this.
For printing purposes, I need to use CMYK colors. On printers, a CMYK black is quite different from a RGB Black. In fact, there is no one on one mapping between the two spaces, and usually, sending a RGB black to a printer is a bad idea in professional publishing.
Back to equals:
In my PDF generation code, I have the following function:
@Override
public void fill(Shape s) {
if (! delegate.getColor().equals(getColor()))
delegate.setColor(getColor());
delegate.fill(getTransform().createTransformedShape(s));
}
delegate
is a graphical object. The idea of the code is to change the delegate color
if the current color for the delegate is different from the current color
in this object, and then, to fill a shape.
Now, usually, the delegate starts with a drawing color which is a RGB black. When I draw, my color is a CMYK RBG. CMYK Color extends Color.
The problem is that equals is defined in the java Color class as follows:
public boolean equals(Object obj) {
return obj instanceof Color && ((Color)obj).getRGB() == this.getRGB();
}
So, two colors are considered the same if they render the same in RGB. Note that this is properly documented in the Javadoc for Color.equals. But it's not the right thing to do for CMYK vs RGB... the behaviour of those are very different on printers.
Now, the question is: when you have a hierarchy, may it be reasonnable to consider two objects as equals, even if they don't ?
I think it's not a good idea in general, except when you have a very sound and implementation independant definition of equality. For colors, for instance, the given definition is indeed in line with the rest of the Color interface, but it misses the points that two corresponding colors in different colorspaces are merely images of one another, and not the same concept.
For Sets, for instance, the equals method is based on the mathematical definition of sets. A = B iff (A ⊂ B ⋀ B ⊂ A), so a HashSet and a TreeSet with the same contents are equals.
I might lead to surprise if someone is trying to compare two sorted sets with different ordering (which is quite an unusual case), but one can argue that, in this case, if one is interested in the ordering, he is comparing lists and not sets. So the ground is quite firm here.
To summarize, in this precise case, I added a comparison of the classes themselves to fix my equality.
]]>com.sun.awt.AWTUtilities.setWindowOpacity(window, 0.5f);
et hop, une fenêtre transparente !
Sympa. Gadget, mais sympa.
]]>Dans ce framework, l'exécution des actions est déléguée à un objet de type façade. Je me base sur une classe proposée dans un article de Hans Muller sur java.net. Cette classe, BundledAction, représente une action
Le tout ne fonctionne pas trop mal. Vous pouvez jeter un œil à une petite application de démo dans org.qenherkhopeshef.guiFramework.demo.simple. Le système permet de configurer assez simplement les actions, et gère leur activation.
Cependant, j'étais bloqué pour le passage à l'échelle... dans mon application réelle (JSesh, quoi), j'avais plusieurs actions déjà écrites (et de plus, le système de délégation multiplie le nombre de méthodes de la façade au delà du raisonnable). Ces action préexistantes me posaient bien évidemment un problème.
Le framework de JHotdraw, quant à lui, gère différemment l'initialisation des actions. Il met en place une classe ResourceBundleUtil, et un simple appel
DoSomethingAction myAction= new DoSomethingAction();
ResourceBundleUtil.getBundle("jsesh.jhotdraw.labels").configureAction(myAction, "edit.doSomething");
permet d'initialiser les propriétés de l'action à partir du fichier de propriétés (ici jsesh.jhotdraw.labels.properties).
Cette approche est bien meilleure du point de vue de la modélisation. En effet, la BundledAction de tout à l'heure a deux caractéristiques orthogonales : la manière dont elle s'exécute d'une part, et la manière dont elle est initialisée d'autre part.
Le ResourceBundleUtil permet d'initialiser n'importe quelle action, sans demander qu'elle implémente un type particulier.
]]>This is the home page for the Java Library JVectCutAndPaste. This library provides :
The java cut and paste library probably suffers from the "good enough for me" syndrom. That is, I did not try to support all graphic features (in particular as far as colour transparency and filling are concerned), but only those I needed. If you want more, feel free to contribute code. So limitations are:
Getting the source : the current distribution of the library is part of JSesh. Get the whole sources for JSesh:
hg clone http://jsesh.hg.sourceforge.net:8000/hgroot/jsesh/jsesh
The sources for this particular library are in the folder jvectClipboard.
Note that there are other libraries for vector graphics. If you need more complete capabilities, you might have a look at freeHep. When I started the JSesh project, it didn't provide all functionnalities I needed, hence the creation of this library. Now, I haven't tried it yet, but the current version of FreeHep also provides clipboard capabilities (but it probably only works on Windows).
(deprecated. I must provide a maven-compatible system).
Get the source distribution, and type "ant run".
You will see a small window with a "copy" button. Click. Then open your favourite text editor (Word, OpenOffice, Mellel...).
Type "paste", and lo, a nice red rectangle was pasted!
This library is distributed under the LGPL (the GNU lesser public license), because I want it to be usable, including in commercial softwares. PDF copy/paste is done using an old version of IText, because of licenses issues (version 2.1.5 was still under the LGPL).
The various Graphics2D object provided (for WMF, EMF, MACPICT, EPS, SVG...) are relatively easy to use. Please notice that I made them for a specific software, JSesh, which might mean they lack some features you need. In particular, I didn't bother to emulate transparency and the like.
Currently, text is rendered as drawing outlines which means that :
Vector graphics are often difficult to copy on the clipboard. In fact, on Windows, it used...
]]>Opérations à mener pour faire un site Drupal multilingue:
Pour la page d'accueil. Si elle est fixe, le système de Drupal renverra toujours sur la page d'origine, et pas sur la page traduite. Une solution est de passer par "frontpage", une vue très paramétrable. Dans "Site information", on règle la page d'accueil sur FrontPage (il est suggéré de décocher dans les types de données "published to front page" si on ne veut pas se retrouver avec plein d'information à cet endroit. Autre solution pour ce dernier point: ajouter un filtre qui limite le chargement aux éléments "sticky", dont fait partie votre "vraie" page de titre.
On peut aussi aller placer
<?php print t($site_slogan); >
dans page.tpl.php
, histoire que le slogan soit multilingue.
Note: si on active i18n d'abord, le site plante. Pour le remettre d'équerre: déplacer le répertoire i18n pour désactiver le module. Désactivez aussi le cache (on a probablement intérêt à le désactiver de toutes façons quand on procède à des modifications).
]]>