I want to change the color of a g:label using java code on a onBlur event.
I am using eclipse, UIBinder.
This is what I have in mind although it doesn't work.
In my StandardDocumentDownload.ui.xml file
<ui:style>
.testStyle {
}
.styleRequiredData
{
color:red;
}
</ui:style>
this is the event in my standardDocumentDownload.java file
#UiHandler("comboTitle")
void onComboTitleBlur(BlurEvent event) {
int title = comboTitle.getSelectedIndex();
if(title == 0)
{
labTitleReq.setText("Please enter a value");
labTitle.addStyleName("styleRequiredData");
}
else
{
labTitleReq.setText("");
}
}
How could I add the color red to the existing style of the label upon the firing of the event.
Kind regards
See here under Programmatic access to inline Styles
for you, it shoulbe be something like :
<ui:style type="com.yourapp.YourClass.MyStyle">
.testStyle {
}
.styleRequiredData
{
color:red;
}
</ui:style>
public class YourClass extends Widget {
interface MyStyle extends CssResource {
String testStyle();
String styleRequiredData();
}
#UiField MyStyle style;
/* ... */
#UiHandler("comboTitle")
void onComboTitleBlur(BlurEvent event) {
int title = comboTitle.getSelectedIndex();
if(title == 0){
labTitleReq.setText("Please enter a value");
labTitle.getElement().addClassName(style.styleRequiredData);
} else {
labTitleReq.setText("");
}
}
}
Took me a while to find it but the Documentation; "Declarative Layout with UiBinder: Programmatic access to inline Styles" tells you how. Here the code snippets
UiBinder:
<ui:style type='com.my.app.MyFoo.MyStyle'>
.redBox { background-color:pink; border: 1px solid red; }
.enabled { color:black; }
.disabled { color:gray; }
</ui:style>
<div class='{style.redBox} {style.enabled}'>I'm a red box widget.</div>
</ui:UiBinder>
Code behind:
public class MyFoo extends Widget {
interface MyStyle extends CssResource {
String enabled();
String disabled();
}
#UiField MyStyle style;
/* ... */
void setEnabled(boolean enabled) {
getElement().addClassName(enabled ? style.enabled() : style.disabled());
getElement().removeClassName(enabled ? style.disabled() : style.enabled());
}
}
Description:
The element has a new attribute,
type='com.my.app.MyFoo.MyStyle'. That means that it needs to implement
that interface (defined in the Java source for the MyFoo widget above)
and provide the two CSS classes it calls for, enabled and disabled.
Now look at the #UiField MyStyle style; field in MyFoo.java. That
gives the code access to the CssResource generated for the
block. The setEnabled method uses that field to apply the enabled and
disabled styles as the widget is turned on and off.
You're free to define as many other classes as you like in a style
block with a specified type, but your code will have access only to
those required by the interface.
Related
I wish to find a method to get the Text node of a TextArea without using the CSS properties. The Text node of JavaFX exposes the method setUnderline(boolean)
through which I can set the underline property of a TextArea; the TextArea, instead, doesn't expose the same method. In addition, the TextArea.getText() method returns a String instead of a Text object.
So, I solved the problem as follow:
In the code,
// Fields..
private final PseudoClass pseudoClass = PseudoClass.getPseudoClass("underlined");
private final SimpleBooleanProperty underlinedProperty = new SimpleBooleanProperty(false);
private final TextArea textArea = new TextArea();
[...]
// In a method (ex. in the constructor)..
{
textArea.setId("textArea");
underlinedProperty.addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
Node node = textArea.getScene().lookup("#textArea .text");
node.pseudoClassStateChanged(pseudoClass, newValue);
}
});
}
[...]
// The class exposes the getter method for the underlinedProperty
public SimpleBooleanProperty getUnderlinedProperty() {
return underlinedProperty;
}
Now, I've create a CSS sheet with this code:
#textArea .text {
/* some styles */
-fx-underline: false;
}
#textArea .text:underlined {
-fx-underline: true;
}
Finally, the above class is called in some other classes:
{
'handleOfClassInPoint1'.getUnderlineProperty().set(true); // or false
}
The problem is the lookup() method: this method returns a not null value only if all the fx nodes were created, i.e. only after some graphical result.
I wish to find a procedure to set the underline property of a TextArea without using CSS (ex. a toggle button manages the underline property: the text of a TextArea is underlined if the toggle is selected).
Anyone can help me?
Thank you so much!
Based on your description in the question comments, I would recommend the following.
Create a custom TextArea that looks something like this:
public class CustomTextArea extends TextArea {
private static final PseudoClass UNDERLINED = PseudoClass.getPseudoClass("underlined");
private final BooleanProperty underlined = new SimpleBooleanProperty(this, "underlined") {
#Override
protected void invalidated() {
pseudoClassStateChanged(UNDERLINED, get()); // update PseudoClass state to match
// the current value of the property
}
};
// property access methods
public final void setUnderlined(boolean underlined) {
this.underlined.set(underlined);
}
public final boolean isUnderlined() {
return underlined.get();
}
public final BooleanProperty underlinedProperty() {
return underlined;
}
// constructor
public CustomTextArea(String text, boolean underlined) {
super(text);
setUnderlined(underlined);
getStyleClass().add("custom-text-area"); // to allow specific CSS styling
}
}
Then in your CSS you would do:
.custom-text-area .text {
-fx-underline: false;
}
.custom-text-area:underlined .text {
-fx-underline: true;
}
The CSS is set on any Text node that is a descendant of aCustomTextArea.
The first CSS rule (the one without ":underlined") may not even be necessary since the default of -fx-underline for a Text node is false.
Then to query whether or not the text is underlined is a simple matter of calling area.isUnderlined() where area is an instance of CustomTextArea.
To maintain the correct visual state you could bind the underlined property of the CustomTextArea bidirectionally to the selected property of a ToggleButton. When one changes the other will reflect that change.
If you want to style only a specific CustomTextArea then you can still give it an ID and reference it in the CSS with #ID.
I have little issue with CssResource in GWT. I want to change styles of AbsolutePanel and label, but it doestnt run. When I add style class with setStyleName method, nothing is happend.
In this snippet of code I use a resource :
public CustommerView() {
MyResource cssResource = GWT.create(MyResource.class);
MyCss myCss = cssResource.css();
AbsolutePanel basePanel = new AbsolutePanel();
initWidget(basePanel);
basePanel.setStyleName(myCss.rootPanel());
Label label = new Label();
label.setText("Im label");
label.setStyleName(myCss.label());
basePanel.add(label);
}
This is my interface which extends CssResource:
public interface MyCss extends CssResource {
/**
* Method for return command button class name
* #return command button class name
*/
public String rootPanel();
public String label();
}
This is my css file, which is next to MyCss interface on filesystem :
.rootPanel {
position:absolute !important;
top:0px;
left:0px;
background-color:yellow !important;
height: 20px !important;
width: 18px !important;
}
.label {
color:red;
}
Custommer view is GWT Composite. When I want to move on view, i call simply RootPanel.get("mainArea").add(view.asWidget) in presenter. mainArea is div element.
When I pasted css class in css file in web inf, everything run ok. Can someone give me the point how to solve this issue? Thanks.
The ensureInjected() call is missing.
i would like to change the background-color property of a gwt cell column. The problem is that this color can change at each render of the cell (background color depends on the value of the cell).
I have already tried to override the cell style names method of TextColumn as follow :
#Override
public String getCellStyleNames(final Context context, final Object data) {
if (my_condition) return "a custom style";
else return "default style"; // or null...
}
Well as you certainly know its only add a class name to the property so i can't use it to set a color "dynamically" due to the static css file definition.
Thx for ur help !
You can use CellFormatter, if you are using Grid. E.g.
grid.getCellFormatter().setStyleName(row, column, "dynamicStyleName");
For dynamic update of 'color' property I would recommend to extend TextCell (and pass it to 'TextColumn' constructor). Something like that:
public class CustomCell extends TextCell<String> {
interface Template extends SafeHtmlTemplates {
#Template("<div style=\"color:{0}\">{1}</div>")
SafeHtml div(String url, String text);
}
private static Template template;
public CustomCell () {
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
String color = "red";
if (value != null) {
// The template will sanitize the URI.
sb.append(template.div(color, value));
}
}
}
public class CustomColumn<T> extends TextColumn<T> {
public CustomColumn() {
super(new CustomCell());
}
}
Since you didn't give details of the component you are using, I'll give a generic suggestion for trying to find out which properties you might need to play with.
I use eclipse and suggest using the GWT Designer to help you with POC stuff. It helps me get an idea of which properties I might want to play with:
GWT Designer Refererence:
https://developers.google.com/web-toolkit/tools/download-gwtdesigner
Example of how to use GWT Designer:
https://developers.google.com/web-toolkit/tools/gwtdesigner/tutorials/loginmanager
I have a component inside an <a/> tag that opens a popup window on click. It's an "add to favourite" link which works on KML files. My KML file has a field named "favourite[boolean]". Now I'd like to hide or show my "add to favourite" link. The KML list is generated with a table:
public class CustomTracksAjaxDataTable<T> extends CustomAjaxDataTable<T> {
public CustomTracksAjaxDataTable(String id, List<IColumn<T>> iColumns,
ISortableDataProvider<T> tiSortableDataProvider, int rowsPerPage) {
super(id, iColumns, tiSortableDataProvider, rowsPerPage);
}
protected void onEventHandler(AjaxRequestTarget ajaxRequestTarget,
KMLFile file) {
setKMLData(file); // it just update map, dont care about it
add(new FavouriteStarIconState(file.isSaved()));
}
}
I tried to add a behavior thus:
public class FavouriteStarIconState extends AbstractDefaultAjaxBehavior {
private boolean isFavourite;
public FavouriteStarIconState(boolean isFavourite) {
super();
this.isFavourite = isFavourite;
}
#Override
protected void respond(AjaxRequestTarget target) {
if (isFavourite) {
target.appendJavascript("jQuery('.map_container_star').css(
{'display' : 'none' });");
} else {
target.appendJavascript("jQuery('.map_container_star').css(
{'display' : 'block' });");
}
}
#Override
public void renderHead(IHeaderResponse response) {
response.renderOnLoadJavascript(getCallbackScript().toString());
}
}
The part of the HTML containing the component:
<div id="map_container">
<a wicket:id="favourite_star" class="map_container_star"></a>
</div>
This isn't working. I got the same result with component.setVisible(false). How can I get hiding to work?
Well it finds out that I make a terrible mistake and put javascript appending in wrong place. AJAX request was not rendered. The proper class was CustomAjaxDataTable being extended by my class CustomTracksAjaxDataTable. I just add
new AjaxEventBehavior( "onclick" )
and override
protected void onEvent( AjaxRequestTarget ajaxRequestTarget )
and it works great now
You could use a CSS class like this
.hiddenClass
{
visibility:hidden;
}
then with AttributeModifier you add the class to the element
component.add(new AttributeModifier("class", "hiddenClass"));
or add the style directly to the style attribute
component.add(new AttributeModifier("style", "visibility:hidden;"));
Sorry if this was already answered before. I did a little searching and found nothing that could solve my problem. I created an application with Spring Roo, then converted to a GWT app.
All the code generated by Spring Roo is only for CRUD. Now i want to add a Calendar for make appointments, so i need to move to another page.
I´ve added this code to
ScaffoldDesktopShell.java()
public ScaffoldDesktopShell() {
initWidget(BINDER.createAndBindUi(this));
startButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
RootLayoutPanel.get().add(new NovoPainel());
}
});
}
...
Then created a new UIbinder, called it NovoPainel() and added this code:
public NovoPainel() {
initWidget(uiBinder.createAndBindUi(this));
botao.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
RootLayoutPanel.get().clear();
RootLayoutPanel.get().add (new ScaffoldDesktopShell());
}
});
}
Everything goes fine moving from my root panel to NovoPainel, but when i need to go back to rootPanel the page doesn´t render correctly.
EX: Doesn´t show ** ValuePicker ** to click on left panel and render on center.
This is my RootPanel
and this image is when navigate from rootPanel to NovoPainel
and finally this one is returning from NovoPainel to RootPanel
You have to integrate with Roo generated architecture so that you can still benefit from Roo scaffolding.
Roo generated code hides most of behavior in _Roo_Gwt classes and it is because GWT doesn’t currently support ITDs. So changes have to be made in derived classes by overriding methods from _Roo_Gwt class.
To navigate application use Places, ActivityMapper and ActivitiManager (you can find good read on #Thomas Broyer posterous and GWT help).
If you take a look in ScaffoldDesktopShell.ui.xml - page is devided in three main areas.
ApplicationMasterActivities class is responsible for master area.
masterActivityManager.setDisplay(shell.getMasterPanel());
proxyListPlacePicker in ScaffoldDesktopApp.init() generates place change event with apropriate ProxyListPlace.
public void onValueChange(ValueChangeEvent<ProxyListPlace> event) {
placeController.goTo(event.getValue());
}
ApplicationMasterActivities class creates appropriate Activity in Master area by checking EntityProxy type contained in ProxyListPlace object.
public Activity getActivity(Place place) {
if (!(place instanceof ProxyListPlace)) {
return null;
}
ProxyListPlace listPlace = (ProxyListPlace) place;
return new ApplicationEntityTypesProcessor<Activity>() {
#Override
public void handlePet(PetProxy isNull) {
setResult(new PetListActivity(requests, ScaffoldApp.isMobile() ? PetMobileListView.instance() : PetListView.instance(), placeController));
}
#Override
public void handleOwner(OwnerProxy isNull) {
setResult(new OwnerListActivity(requests, ScaffoldApp.isMobile() ? OwnerMobileListView.instance() : OwnerListView.instance(), placeController));
}
}.process(listPlace.getProxyClass());
}
Navigation is created by listing all EntityProxy's in ScaffoldApp class
protected HashSet<ProxyListPlace> getTopPlaces() {
Set<Class<? extends EntityProxy>> types = ApplicationEntityTypesProcessor.getAll();
HashSet<ProxyListPlace> rtn = new HashSet<ProxyListPlace>(types.size());
for (Class<? extends EntityProxy> type : types) {
rtn.add(new ProxyListPlace(type));
}
return rtn;
}
To output meaningfull name in navigation menu they are rendered using ApplicationListPlaceRenderer
public String render(ProxyListPlace object) {
return new ApplicationEntityTypesProcessor<String>() {
#Override
public void handlePet(PetProxy isNull) {
setResult("Pets");
}
#Override
public void handleOwner(OwnerProxy isNull) {
setResult("Owners");
}
}.process(object.getProxyClass());
}
So you have to create new Activity.
public class SomeActivity extends Composite implements Activity{
private static SomeActivityUiBinder uiBinder = GWT
.create(SomeActivityUiBinder.class);
interface SomeActivityUiBinder extends UiBinder<Widget, SomeActivity> {
}
private AcceptsOneWidget display;
public SomeActivity() {
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public String mayStop() {
return null;
}
#Override
public void onCancel() {
onStop();
}
#Override
public void onStop() {
this.display.setWidget(null);
}
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
this.display = panel;
this.display.setWidget(this);
}
}
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
Hello world!
</g:HTMLPanel>
</ui:UiBinder>
Create appropriate EntityProxy. It is only to obey ProxyListPlace mechanism.
public interface SomeEntityProxy extends EntityProxy {
}
Create SomeActivity in A
#Override
public Activity getActivity(Place place) {
if (!(place instanceof ProxyListPlace)) {
return null;
}
Activity activity = super.getActivity(place);
if (activity == null) {
ProxyListPlace listPlace = (ProxyListPlace) place;
if (SomeEntityProxy.class.equals(listPlace.getProxyClass())) {
activity = new SomeActivity();
}
}
return activity;
}
Add place to navigation in ScaffoldApp or override getTopPlaces in derived class.
rtn.add(new ProxyListPlace(SomeEntityProxy.class));
Set correct menu rendering text in ApplicationListPlaceRenderer
#Override
public String render(ProxyListPlace object) {
String label = super.render(object);
if(label == null) {
if (SomeEntityProxy.class.equals(object.getProxyClass())) {
label = "Some activity";
}
}
return label;
}
Code in GitHub.
GWT 2.1 introduced new classes that implements the Model-View-Places pattern (MVP). This pattern (and the GWT 2.1 concepts) are heavily based on best practices from developers who have build scalable GWT-based applications, so many people are migrating in this direction.
Roo generates a GWT 2.1 application; all of its navigational code is built on top of Activities and Places. The reason I bring this up is it sounds like you are attempting to side-step a lot of this navigational framework to implement your own. I'm not sure, but I believe your problem is coming from the fact that the MVP code is getting confused as a result.
My recommendation would be to work through the GWT MVP article linked above first. Do it completely separate of Roo, because the application that Roo generates is more complex. Once you have a good handle on it, go back through the Roo-generated application and it will likely make more sense.
You can create two div tags in your Porject.html file respectively with id firstdivtag_id1 and seconddivtag_id2.
Display first page by using
RootPanel.get("firstdivtag_id1").add(Panel1);
And then to switch over to another panel use
RootPanel.get("seconddivtag_id2").add(Panel2);