Basically I have changed the css for a text field in javafx by adding a style class like this:
textfield.getStyleClass().add("textfieldstyle");
But then I want to be able to revert it back to its original appearance. But since the original appearance in this case is the default skin for JavaFX, I can't find the original layout for the textfields. I found the textfieldskin properties here, but its a jungle, and I can't find anything about the color of the -fx-control-inner-background, -fx-text-box-border and -fx-focus-color, which is what I want to know.
I've triedtextfield.getStyleClass().remove("textfieldstyle"); and think that does remove the new css, but it doesn't apply the old one again.
Thanks to the comments by #UlukBiy and #varren I solved the issue. System.out.println(textfield.getStyleClass()); was of great use since it allowed me to check which style classes were applied on the text field as default. And as it is pointed out in the comments those where text-input and text-field.
So to restore the text field's css to its default value I just did:
textfield.getStyleClass().clear();
textfield.getStyleClass().addAll("text-field", "text-input");
To reset an element's default styling after setting it using .setStyle("css settings....."); you can simply use -
textfield.setStyle(null);
I'm not sure if this would work on it's own for an element that's had a class applied using .getStyleClass().add("textfieldstyle"); but if not you could do something like -
textfield.getStyleClass().clear();
textfield.setStyle(null);
A short way to effictively remove your style class even in case of duplicates, with a lambda :
textfield.getStyleClass().removeIf(style -> style.equals("textfieldstyle"));
The following test code works for me when adding and removing a class from a control such as Textfield:
import javafx.scene.control.TextInputControl;
public class test
{
protected void setEditable(final TextInputControl toControl, final boolean tlEditable)
{
toControl.setEditable(tlEditable);
if (tlEditable)
{
if (toControl.getStyleClass().contains("non-editable-class"))
{
toControl.getStyleClass().removeAll("non-editable-class");
}
}
else if (!toControl.getStyleClass().contains("non-editable-class"))
{
toControl.getStyleClass().add("non-editable-class");
}
}
}
Related
I migrating a Vaadin 8 project to Vaadin 14 and i try to show HTML in a grid column.
I figured out, that i have to use a TemplateRenderer, but how can i use it?
Here is the code from Vaadin 8:
grid.addColumn(e -> {
return ((Data) e).getValues()[index];
}).setCaption(myCaption).setRenderer(new HtmlRenderer());
In Vaadin 14 i did this:
gird.addColumn(e -> {
return TemplateRenderer.<Data>of((String) e.getValues()[index])
}).setHeader(myCaption);
e.getValues()[index] includes HTML, for example: <FONT SIZE = 4 COLOR = BLACK> ⚫</FONT>
In Vaadin 14 it always returns com.vaadin.flow.data.renderer.
Before we get to how to use a TemplateRenderer with Grid, I first need to point out that what you're trying to do is potentially dangerous because of the way it can lead to XSS vulnerabilities if the HTML strings that you want to show may be supplied by application users.
Using the Html component is indeed one potential solution to this problem, but it causes some overhead because there will be one component instance in memory for each row in the grid. There's also the same problem with potentially causing XSS vulnerabilities.
The first thing to notice with TemplateRenderer is that the renderer needs to be supplied directly as a parameter to addColumn. Wrapping it in a lambda will instead use that lambda as a value provider, which means that the toString() value of the renderer instance will be used with the default plain text renderer.
All rows should use the same renderer instance, configured with the same template string. The trick is that you can pass the data to show as a per-row property that the template will render for you. The last piece of the puzzle is that the template syntax tries to protect you against accidental XSS vulnerabilities, so you need to use a slightly contrived syntax to actually make it render the data as HTML.
Putting everything together, and also using JSoup to remove any dangerous stuff from your HTML strings, the working solution looks like this:
grid.addColumn(TemplateRenderer
.<Data> of("<div inner-h-t-m-l='[[item.html]]'></div>")
.withProperty("html", e -> {
String unsafeHtml = e.getValues()[index];
String safeHtml = Jsoup.clean(unsafeHtml, Whitelist.basic());
return safeHtml;
})).setHeader(myCaption);
I found a solution.
Instead of using the TemplateRenderer I used a ComponentRenderer.
The migration documentation recomented to use a TempleteRenderer or an ComponentRenderer instead of the htmlRenderer.
https://vaadin.com/docs/v14/flow/migration/8-migration-example.html#step-4-product-grid
Here is the code that worked for me:
grid.addColumn(new ComponentRenderer<>(e -> {
String value = (String) e.getValues()[index];
return new Html(value);
})).setHeader(String.valueOf(col + 1));
Comparing your attempts with TemplateRenderer and the documentation, I would assume it will have to look like this:
grid.addColumn(e ->
TemplateRenderer.<Data>of("[[item.customValue]]")
.withProperty("customValue", (String) e.getValues()[index])
).setHeader(myCaption);
I'm using the Atlassian Commonmark API found here to parse Markdown to HTML.
Works beautifully, but tends to add <pand </p>to the beginning and end of every parsed String.
Has anyone used the API extensively in the past and/or has any idea how I could get it to stop doing this?
Other than manually removing the paragraph afterwards, that is, which feels ... unclean somehow.
Edit for clarification: The converted code snippets are intended for use in an HTML table, so I don't need the paragraph bits before and after them.
The Markdown input might be:
####Text for the table here.
The output I'm getting is:
<p><h6>Text for the table here.</h6></p>
What I want is simply for the paragraph snips not to be added:
<h6>Text for the table here.</h6>
Was looking for this as well. I achieved it by creating a simple custom renderer that does not render the top level <p>aragraphs.
It checks if the parent of a paragraph is the Document node and if yes it does only render the children of the paragraph.
It extends the default renderer (CoreHtmlNodeRenderer) to get access to visitChildren() and visit(Paragraph)
in kotlin:
class SkipParentWrapperParagraphsRenderer(val context: HtmlNodeRendererContext)
: CoreHtmlNodeRenderer(context), NodeRenderer {
override fun getNodeTypes(): Set<Class<out Node>> {
return setOf(Paragraph::class.java)
}
override fun render(node: Node) {
if (node.parent is Document) {
visitChildren(node)
} else {
visit(node as Paragraph)
}
}
}
register the new renderer:
val renderer: HtmlRenderer = HtmlRenderer
.builder()
.nodeRendererFactory { context -> SkipParentWrapperParagraphsRenderer(context) }
.build()
There is an example in the documentation.
How do I retrieve the text from JLabel without the HTML taggings?
E.g.
CustomJLabel:
public CustomJLabel extends JLabel(){
private String text;
public CustomJLabel(String text) {
super("<html><div style='text-align: center;'>"+text+"</div></html>"),
this.text=text;
}
}
Main method:
testCustomLbl = new CustomJLabel("Testing");
System.out.println(testCustomLbl.getText());
Output I got:
<html><div style='text-align: center;'>Testing</div></html>
Desired output:
Testing
There are three options:
You pick your favorite HTML parser and parse HTML; see here for some inspiration. This is by far the most robust and straight forward solution; but of course: costly.
If you are well aware of the exact HTML content that goes into your labels, then you could turn to regular expressions; or other means of string parsing. The problem is: if you don't control those strings, then coming up with your own custom "parsing" is hard. Because each and any change somewhere to the HTML that goes in ... might break your little parser.
You rework your whole design: if having HTML text is such a core thing in your application, you might consider to really "represent" that in your class. For example by creating your own versions of JLabels that take some HtmlString input ... and simply remember which parts are HTML, and which one "pure text".
And whoops; the code you are showing is already suited for option 3. So if you want that getText() returns that original text, you could add a simple
#Override
public void String getText() {
return this.text;
}
to your CustomLabel class.
Edit: alternatively, you could simply add a new method like
public void String getTextWithoutHtmlTags()
or something alike; as overriding that inherited method somehow changes the "contract" of that method. Which (depending on the context) might be ok, or not so ok.
There's no need for complex code or 3rd party JARS / Libraries.
Here's a simple solution using RegEx:
String htmlStr = "<html><h1>Heading</h1> ...... </html>";
String noHtmlStr = htmlStr.replaceAll("\\<.*?\\>", "");
Works great for me.
Hope this helps.
I would like to extend the CDT language plugin for gnu c, to create some kind of new language based on this.
The new language should have a different visual appearence in editor. I would like to color a method body in gray if there is a special pre-processor directive in front of (like an annotation).
Does anybody know where to extend the GCC language for a modification like this?
EDIT1:
As example I want that the colour of the method body of specialFunction to be gray, as a reason of an example annotation -> #annotation
#annotation
int specialFunction(){
return 1;
}
EDIT2:
What i have tried so far is to build a "extended language". The plan was to highlight a preprocessor position and also save the position so that the method below would be colored. I managed to get the preprocessor keyword colored but not how to work on method bodies color.
public class OwnKeyWords extends GCCLanguage implements ICLanguageKeywords
#Override
public String[] getPreprocessorKeywords() {
//System.out.println("Called keywords" + timesPre++);
return new String[]{
"hide",
"show"
};
}
Example to be colored:
#hide
int specialFunction(){
return 1;
}
In the example above "hide" would be highlighted.
EDIT3:
I tried to implement ISemanticHighlighter and tried a few ways to highlight my code:
CVariable
CFunction
ObjectStyleMacro
...
But non of them where suitable to highlight a method body with a preprocessor directive or anything else on top.
Also the note in ISemanticHighlighter:
* NOTE: Implementors are not allowed to keep a reference on the token or on any object retrieved from the
* token.
Is not what I want to achieve, because I would like to keep reference to the highlighted object for later operations.
Maybe the org.eclipse.cdt.ui.text.folding.DefaultCFoldingStructureProvider would be an option too, there I couldn't colour the instrumentation, I could instead hide it.
This does not sound like a new language so much as semantic highlighting.
CDT has a great extension point called org.eclipse.cdt.ui.semanticHighlighting that allows you to define custom semantic highlighting rules.
Here is an example of the plugin.xml entry:
<extension
point="org.eclipse.cdt.ui.semanticHighlighting">
<semanticHighlighting
class="com.example.SemanticHighlighter"
defaultBold="true"
defaultEnabled="true"
defaultTextColor="35,0,35"
displayName="Example Semantic Highlighter"
id="com.example.SemanticHighlighter"
preferenceKey="com.example.SemanticHighlighter.pref"
priority="5">
</semanticHighlighting>
</extension>
Then in your com.example.SemanticHighlighter you implement the org.eclipse.cdt.ui.text.ISemanticHighlighter interface. There is only one method, consumes that takes a ISemanticToken. Analyse the token to see if it is relevant to your highlighter and return true to have it highlighted.
Here is a trivial implementation of the method:
#Override
public boolean consumes(ISemanticToken token) {
IBinding binding = token.getBinding();
if (binding instanceof IFunction) {
IASTNode node = token.getNode();
if (binding != null && node instanceof IASTName && ((IASTName) node).isReference()) {
String n = binding.getName();
if ("MySpecialFunction".equals(n)) {
return true;
}
}
}
return false;
}
Once implemented, users can modify the colour and applicability via the preference page C/C++ - Editor - Syntax Coloring:
You should be able to use ISemanticHighlighter to do the kind of highlighting you want.
For your example of coloring the body of a function with a particular annotation, it could work like this:
class MyHighlighter implements ISemanticHighlighter {
#Override
public boolean consumes(ISemanticToken token) {
IASTNode node = token.getNode();
// Walk up the AST to determine if 'node' is inside a function body.
// If it's not, return false.
// Navigate the AST some more to examine what comes before the
// function's declaration. If it's the annotation in question,
// return true. Otherwise, return false.
}
}
I left out the details of how to navigate the AST, but CDT has a pretty rich AST API so it's definitely doable. Feel free to ask specific questions if you have them.
I have to check some textField with the following rule:
if (the value A != the value B) {
this.A.forceInvalid("");
}
This work really fine, but I want to remove the "info bubble" of the error,on the textfield.
I have tried to simply put a css with red border around it, but it seems that my superior dont want that.
How can I erase that bubble?
First of all, this validation looks wrong. It seems you are using gxt Field which already has built-in validators. Here is an example:
yourField.addValidator(new Validator<String>() {
#Override
public List<EditorError> validate(Editor<String> editor, String value) {
final List<EditorError> errors = new ArrayList<EditorError>();
if (!value.equals("test")) {
errors.add(new DefaultEditorError(yourField, "Value is not \"test\"", value));
}
return errors;
}
});
By default it looks like this:
You can change it by using non-default ErrorHandler on the field. It is not clear what exactly do you want, as far as I can understand you want to get rid of (!) sign and its popup. I think that TitleErrorHandler will suit your needs.
yourField.setErrorSupport(new TitleErrorHandler(yourField));