How to set GWT cell background color - java

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

Related

What parent to set when calling FieldEditor#setEnabled?

I am building a preference page in Eclipse by extending the FieldEditorPreferencePage class. this page contains 2 fields : 1 BooleanFieldEditor (checkbox) and 1 FileFieldEditor. I would like to disable/enable the file field following the checkbox value.
I went up to something like this (some obvious code is not displayed):
public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
public static final String PREF_KEY_1 = "checkBoxPref";
public static final String PREF_KEY_2 = "filePref";
private FileFieldEditor pathField;
private BooleanFieldEditor yesOrNoField;
private Composite pathFieldParent;
#Override
protected void createFieldEditors() {
this.yesOrNoField = new BooleanFieldEditor(PREF_KEY_1, "Check this box!", getFieldEditorParent());
this.pathFieldParent = getFieldEditorParent();
this.pathField = new FileFieldEditor(PREF_KEY_2, "Path:", this.pathFieldParent);
addField(this.yesOrNoField);
addField(this.pathField);
boolean isChecked = getPreferenceStore().getBoolean(PREF_KEY_1);
updatePathFieldEnablement(! isChecked);
}
/**
* Updates the fields according to entered values
*/
private void updatePathFieldEnablement(boolean enabled) {
this.pathField.setEnabled(enabled, this.pathFieldParent);
}
#SuppressWarnings("boxing")
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.VALUE) && event.getSource() == this.yesOrNoField) {
updatePathFieldEnablement(! (boolean) event.getNewValue());
}
super.propertyChange(event);
}
}
My question is about this second parameter in FieldEditor#setEnabled. This parameter is the parent composite of the FieldEditor's controls ("Used to create the controls if required" says the javadoc) . At first, I set the value with the return of getFieldEditorParent but then I got an exception "Different parent". So I ended storing it (cf. this.pathFieldParent) and give it back to setEnabled and it works (or it seems to work).
But I am not sure I am doing well, especially because I had to create a member in my class that means nothing to it (and I would have to create many of them if I had many fields to enable/disable).
Do you think I am doing well or is there a better way to provide this parent ? And could you explain to me why *setEnabled" needs it ?
Thanks.
You are using the default FLAT layout for the preference page. When this layout is used each call to getFieldEditorParent generates a new Composite so you have to make just one call and remember the correct parent. Using the GRID layout getFieldEditorParent always returns the same parent. This is the actual code:
protected Composite getFieldEditorParent() {
if (style == FLAT) {
// Create a new parent for each field editor
Composite parent = new Composite(fieldEditorParent, SWT.NULL);
parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
return parent;
}
// Just return the parent
return fieldEditorParent;
}
setEnabled does sometimes create a new Label control so it needs to know the correct parent Composite.

Netbeans Custom Component with Custom-Class Property

I have a question about implementing a Swing control which uses a custom class as one of its properties. My goal is to use this control within the netbeans IDE and configure it in design-time like any other component. I already implemented a custom property editor for my ConnectionInfo object which works fine.
However - when I configure my IntLEDs ConnectionInfo property in Netbeans and save it, I can see, in the generated code by Netbeans, that it had troubles to init my ConnectionInfo class.
This is actually what the Netbeans IDE generated:
intLED1.setConnection(???);
So I guess that Netbeans doesn't know how to instantiate my ConnectionInfo class.
But how to tell Netbeans how to do it? :)
This code is basicly a stripped version of my component
public class IntLED extends JPanel {
private ConnectionInfo connection = new ConnectionInfo("", 11159, "", "", Variable.VARIABLE_TYPE.INT);
public IntLED() {
initComponents();
PropertyEditorManager.registerEditor(ConnectionInfo.class, PviCpuPropertyEditor.class);
}
public ConnectionInfo getConnection() {
return connection;
}
public void setConnection(ConnectionInfo connection) {
this.connection = connection;
}
}
Here the ConnectionInfo code. Just some members and Getters/Setters.
public class ConnectionInfo {
private String pviHost = "";
private int pviPort = 11159;
private String pviTask = "";
private String pviVarname = "";
private Variable.VARIABLE_TYPE pviType;
public ConnectionInfo() {
}
public ConnectionInfo(String pviHost, int pviPort, String pviTask, String pviVarname, Variable.VARIABLE_TYPE type) {
this.pviHost = pviHost;
this.pviPort = pviPort;
this.pviTask = pviTask;
this.pviVarname = pviVarname;
this.pviType = type;
}
public String getPviHost() {
return pviHost;
}
public void setPviHost(String pviHost) {
this.pviHost = pviHost;
}
public int getPviPort() {
return pviPort;
}
public void setPviPort(int pviPort) {
this.pviPort = pviPort;
}
public String getPviTask() {
return pviTask;
}
public void setPviTask(String pviTask) {
this.pviTask = pviTask;
}
public String getPviVarname() {
return pviVarname;
}
public void setPviVarname(String pviVarname) {
this.pviVarname = pviVarname;
}
public Variable.VARIABLE_TYPE getPviType() {
return pviType;
}
public void setPviVarname(Variable.VARIABLE_TYPE pviType) {
this.pviType = pviType;
}
}
I also tried to put the members of the ConnectionInfo-Class directly into my IntLED-Class which works fine! But I really need to let the user configure those Members directly in one editor since the editor also provides a tester to test those settings et cetera.
I hope someone can point me to the right direction :)
Thank you very much in advance!
I found the 'missing link' between my Custom Property and the Matisse Code generator!
In my Custom Property Editor (which extends PropertyEditorSupport) I did not override the method getJavaInitializationString().
Apperently when this method is not overwritten, it returns '???' which is exactly what I saw.
Here is how I fixed it:
#Override
public String getJavaInitializationString() {
return String.format("new ConnectionInfo(\"%s\", %d, \"%s\", \"%s\", Variable.VariableType.BOOLEAN)", getValue().getHost(), getValue().getPort(), getValue().getTask(), getValue().getVarname());
}
Surely there should be some Nullpointer checks and so on. But this is basicly how to tell Matisse how to init your Custom Class!
I hope I'm understanding your question, but as I see it you want to be able to add your custom JPanel (IntLED) as a component that you can use in the GUI Editor (Matisse) like every other component?
There is an answer here (https://stackoverflow.com/a/18409887/963076) that explains how to add custom components to the GUI Editor.
EDIT:
Ok, I see. To change the code that Netbeans is generating, you should look for that parameter in the Properties dialog for that component. Right click the component and click "Properties." Then find connection in the list of properties. connection should appear because Netbeans looks for all get() and set() methods and adds them as properties that you can edit. Once you find connection press the ... button to the right. It'll bring up a dialog allowing you to set that component's property. You'll probably need to select "custom code".
(In the pictures below, I used the columnModel property as an illustration).
From the screen below, select "custom code".

Where to store consistent application properties?

I'm building a Swing application in Java and I want the colours to be consistent. So I could do something like:
public class Colours {
public static final String BACKGROUND = "#D9DADE";
}
But then I thought maybe an enum would be better, so I did this:
public enum ColourStyles {
BACKGROUND("#D9DADE");
private String colourValue;
private ColourStyles(String value) {
colourValue = value;
}
public String getColourValue() {
return colourValue;
}
};
But then that made the String now a ColourStyle type and I can't decode it using Color.decode(BACKGROUND).
Is there any better way of doing this completely, like a properties file? I've done Wicket but never come across the same sort of structure for labels/colours in Swing.
Thanks!
The 2 options are good, but i'd prefer a 3rd way and it's using a property file. So you don't have to recompile your application if you want to change.
1st)
public final class Colours {
private Colours(){}
public static final BACKGROUND = "#D9DADE";
}
.
2nd) It's ok, but you can add a method to the enum to return the color.
public enum ColourStyles {
BACKGROUND("#D9DADE");
private String colourValue;
private ColourStyles(String value) {
colourValue = value;
}
public String getColourValue() {
return colourValue;
}
public Color getColour(){
return Color.decode(colourValue);
}
}
And 3rd) create a file for example lookAndFeel.properties
colour.background=#D9DADE
Make a class that could be a singleton to load the properties file and you can add a util method to return the colour like in the enum, the good thing of this is that you can change the values wihout compiling again your application.
4th) If you are using a customizable look&feel you can set that properties using UIManager.put(); to set properties for all components. Here is an example of properties for Nimbus L&F Nimbus defaults

GWT RootLayoutPanel - Problem rendering page from second to first (first works fine)

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);

Set focus on a component with Apache Wicket?

How do you set focus on a component with Apache Wicket? Searching leads to very little information, mostly on setting the default field. I do not want to set a default field, rather I am looking to set focus when, for example, a specific radio button is selected.
I suggest using the native org.apache.wicket.ajax.AjaxRequestTarget#focusComponent(). For example:
/**
* Sets the focus in the browser to the given component. The markup id must be set. If
* the component is null the focus will not be set to any component.
*
* #param component
* The component to get the focus or null.
*/
org.apache.wicket.ajax.AjaxRequestTarget#focusComponent(Component component)
Once you create your behavior to set the focus, you should be able to add it to the component on any event, just make sure that component is part of the AjaxRequestTarget. I don't see why this wouldn't work...
myRadioButton.add(new AjaxEventBehavior("onchange") {
#Override
protected void onEvent(AjaxRequestTarget target) {
myOtherComponent.add(new DefaultFocusBehavior());
target.addComponent(myForm);
}
});
Here's a link that shows how to create the default focus behavior if you do not have one already:
http://javathoughts.capesugarbird.com/2009/01/wicket-and-default-focus-behavior.html
If you only want to setFocus through javascript and don't want to reload a form or a component, you can use the following code:
import org.apache.wicket.Component;
public class JavascriptUtils {
private JavascriptUtils() {
}
public static String getFocusScript(Component component) {
return "document.getElementById('" + component.getMarkupId() + "').focus();";
}
}
And then in any Ajax Method you can use:
target.appendJavascript(JavascriptUtils.getFocusScript(componentToFocus));
For a pop-up like modalWindow my workaround solution was to use the attribute "autofocus" on the first input tag.
An easy solution is to add it to the html directly.
<input ..... autofocus>
Another solution is to add it to the modalWindow itself:
#Override
public void show(AjaxRequestTarget target) {
super.show(target);
setUpFocus();
}
protected void setUpFocus() {
DeepChildFirstVisitor visitor = new DeepChildFirstVisitor() {
#Override
public void component(Component component, IVisit<Void> iVisit) {
if (isAutofocusable(component)) {
component.add(new AttributeAppender("autofocus", ""));
iVisit.stop();
}
}
#Override
public boolean preCheck(Component component) {
return false;
}
};
this.visitChildren(FormComponent.class, visitor);
}
protected boolean isAutofocusable(Component component) {
if (component instanceof TextArea ||
component instanceof DropDownChoice ||
// component instanceof RadioChoice ||
component instanceof AjaxCheckBox ||
component instanceof AjaxButton ||
component instanceof TextField) {
return true;
}
return false;
}
RadioChoice is commented out because this solution is not working on that. For RadioChoice i would recommend to implement a FocusedRadioChoice:
public class FocusedRadioChoice<T> extends RadioChoice<T> {
//constructors...
#Override
protected IValueMap getAdditionalAttributes(int index, T choice) {
super.getAdditionalAttributes(0, choice);
AttributeMap am = new AttributeMap();
am.put("autofocus", "");
return am;
}
}
Is there a way to achieve the same without JavaScript?
(I am implementing a form with a feedback-Panel that only comes up when Javascript is turned off, so it would not make sense to depend on JavaScript there...,-)
I could only find answers which use JS .focs()... maybe Wicket 1.5 will provide a method Component.setFocus()...
If you happen to be using an Ajax button, you can simply call target.focusComponent(myComponent); in the button's onSubmit method.
#martin-g 's solution was the only solution that got it working for my scenario - a modal/pop up.
Note:
I think autofocus embedded explicitly in HTML only works on page load, not modal load so any efforts to skillfully set the autofocus attribute in the HTML of a modal just fail miserably - always.
Here I lay out the steps for setting the focus on an input field called 'myInput' using the full power of Wicket (no JS!):
In onInitialize:
// Make sure the field has an ID in markup
myInput.setOutoutMarkupId(true);
Provide an overridden show method where you call the focusComponent method:
public void show(AjaxRequestTarget target)
{
// Make sure you call the super method first!
super.show(target);
target.focusComponent(myInput);
}
This does require that your component is an attribute of your modal content class so that you can access it in the show method. To avoid creating a class attribute for your input component you could blend this solution with the solution from BlondCode by replacing that solution's
component.add(new AttributeAppender("autofocus", ""));
with
target.focusComponent(component);
This also works!

Categories