I'm trying to update my data widget from a CellTable to DataGrid and I basically thought I online a change from #UiField CellTable<T> to #UiField DataGrid<T> but thats not it.
private void init() {
sortHandler = new ListHandler<GWTUser>(getUsers());
dataGrid.setWidth("100%");
dataGrid.setHeight("100%");
dataGrid.setAutoHeaderRefreshDisabled(true);
dataGrid.setEmptyTableWidget(emptyDb);
dataGrid.addColumnSortHandler(sortHandler);
dataGrid.setVisibleRangeAndClearData(dataGrid.getVisibleRange(), true);
dataGrid.setRowCount(1, true);
dataGrid.clearTableWidth();
dataGrid.redraw();
// Setup Cell Table.
initCellTable();
// Connect the table to the data provider.
dataProvider.addDataDisplay(dataGrid);
}
private void initCellTable() {
// userId Column
TextColumn<GWTUser> userIdColumn = new TextColumn<GWTUser>() {
#Override
public String getValue(GWTUser object) {
return object.getUserId();
}
};
dataGrid.addColumn(userIdColumn, Lang.LABEL_USER_USERID);
dataGrid.addColumnSortHandler(sortHandler);
dataGrid.getColumnSortList().push(userIdColumn);
dataGrid.getColumnSortList().push(userIdColumn);
}
#Override
public void setUserList(List<GWTUser> users) {
setUsers(users);
dataGrid.setRowCount(getUsers().size(), true);
dataGrid.setRowData(0, getUsers());
dataGrid.setPageSize(getUsers().size());
dataGrid.setVisibleRange(new Range(0,dataGrid.getRowCount()));
dataGrid.redraw();
sortHandler.setList(getUsers());
}
uiBinder:
<g:VerticalPanel>
<g:ScrollPanel ui:field="listScrollPanel">
<c:DataGrid styleName= ui:field='dataGrid' width="100%" height="98%"/>
</g:ScrollPanel>
<g:HorizontalPanel>
<g:Button ui:field="createButton">New</g:Button>
<g:Button ui:field="refreshButton">Refresh</g:Button>
<g:Button ui:field="removeSelectedButton">Delete Selection</g:Button>
</g:HorizontalPanel>
</g:VerticalPanel>
When I change the region where my DataGrid should be with the chrome dev tool, the data with the tables is there but not shown.
as basic information: init is called by the constructor and setUserList is called in my activitiy when I get the data from a rest service. thanks for any help.
The DataGrid requires an explicitly set height. This means that you can't use percentages (e.g. 100%), but rather have to use something like 500px.
Here is a related question:
GWT DataGrid automatic height
Related
I am using JavaFx, and have Tabs with WebView objects on them. I am trying to have my tab title's text to read the web page's title like in most web browsers. When I use the "getTitle" method I get an empty title, Which I assume is because the page hasn't loaded yet. All the research I've done gives me an Android Solution and I'm looking for something that works with a desktop application. Here's what I have.
public class WebsiteTab extends Tab {
final static String DEFAULT_SITE = "https://google.com";
VBox browserBox;
WebView webView;
public WebsiteTab() {
super("Site One");
webView = new WebView();
webView.setPrefHeight(5000);
goToSite(DEFAULT_SITE);
browserBox = new VBox(10,webView);
VBox.setVgrow(browserBox, Priority.ALWAYS);
setContent(browserBox);
}
public void goToSite(final String site) {
webView.getEngine().load(site);
setText(webView.getEngine().getTitle());
}
}
Any help would be appreciated.
You can bind the tab's text property to the web engine's title property.
public class WebsiteTab extends Tab {
final static String DEFAULT_SITE = "https://google.com";
VBox browserBox;
WebView webView;
public WebsiteTab() {
super("Site One");
webView = new WebView();
webView.setPrefHeight(5000);
textProperty().bind(webView.getEngine().titleProperty()); // bind the properties
goToSite(DEFAULT_SITE);
browserBox = new VBox(10,webView);
VBox.setVgrow(browserBox, Priority.ALWAYS);
setContent(browserBox);
}
public void goToSite(final String site) {
webView.getEngine().load(site);
}
}
This will cause the text property to always have the same value as the title property. In other words, when the title property's value changes the text property will be automatically updated. Notice I bind the properties in the constructor as you only need to create the binding once. Also note that while bound you can no longer manually set the text property; attempting to do so will cause an exception to be thrown. For more information, see Using JavaFX Properties and Binding.
I am quite new to Wicket. I am adding a model to a sub-panel(ChartPanel) from a main panel (MainPanel) on a button click.
MainPanel.java
On button click, I am re-adding the chartPanel after I change its model. Following is the code I am using in the buttonClick of the MainPanel. Here the onRenderAnnotations event is generated on some click in the UI.
#OnEvent
public void onRenderAnnotations(RenderAnnotationsEvent aEvent)
{
LOG.trace("clicked on the annotation");
renderChart( aEvent.getRequestHandler());
}
private void renderChart(IPartialPageRequestHandler aRequestHandler)
{
MultiValuedMap<String, Double> recommenderScoreMap = getLatestScores(aRequestHandler);
Map<String,String> curveData = new HashMap<String,String>();
LearningCurve learningCurve = new LearningCurve();
for (String recommenderName : recommenderScoreMap.keySet()) {
String data = recommenderScoreMap.get(recommenderName).stream().map(Object::toString)
.collect(Collectors.joining(", "));
curveData.put(recommenderName,data);
learningCurve.setCurveData(curveData);
learningCurve.setMaximumPointsToPlot(MAX_POINTS_TO_PLOT);
}
chartPanel.setDefaultModel(Model.of(learningCurve));
// to avoid the error, A partial update of the page is being rendered
try {
aRequestHandler.add(chartPanel);
}
catch (IllegalStateException e) {
LOG.warn("Not updating the chart. " + e.toString());
setResponsePage(getPage());
}
}
ChartPanel.java
After this in the chartPanel, I want to use the updated model to add component inside the chartpanel. What would be the best way to do that?
I want to do something like this in the class ChartPanel:
#Override
protected void onRender()
{
super.onModelChanged();
LearningCurve newLearningCurve = getModel().getObject();
requestTarget = ???
String js = createJavascript(newLearningCurve);
requestTarget.prependJavascript(js);
}
My question is, in the above code how to get the request target since it is not an ajax request neither do I get it in the arguments. Should I use some other function where I also get a requestTarget. But I want it to be called every time the model of ChartPanel is updated from anywhere.
Pardon my ignorance. I have been trying for a few days but I am still stuck. I tried to explain it enough but if any information is missing, please comment and I will add it right away.
Thanks.
You should override renderHead() instead:
#Override
public void renderHead(IHeaderResponse response)
{
super.renderHead(response);
response.render(OnLoadHeaderItem.forScript(
createJavascript(newLearningCurve)));
}
This way your chart will be shown correctly regardless whether it was added due to an AjaxRequest or simply when the page is rerendered.
I am using Primefaces/JSF in combination with pure javascript tools in order to implement an image viewer & annotator. Image viewer is built upon the OpenLayers framework.
When the user annotates (draws shapes) on the canvas, a JSON object is created and upon Save action passed to the back bean. Back bean retrieves the object (deserialized) and stores it in to a file.
Here is the relevant code:
OpenLayers javascript (image-viewer.js):
function initialiseMap(){'
...
map = new OpenLayers.Map(imageEditorID, options);
imageLayer = new OpenLayers.Layer.TMS(imgURL, "", {
...
});
map.addLayer(imageLayer);
var vlayer = new OpenLayers.Layer.Vector("Editable");
map.addLayer(vlayer);
//draw controls and shape tools
...
//then define save action
var save = new OpenLayers.Control.Button({
...
var GEOJSON_PARSER = new OpenLayers.Format.GeoJSON();
var vectorLayerAsJson = GEOJSON_PARSER.write(vlayer.features);
//and finally post to server layer with drawn shapes
sendJSONToServer([{name:'param', value:vectorLayerAsJson}]);
...
The above Image Viewer/Map tool, is loaded via an p:outputPanel component of primefaces and uses sendJSONToServer remoteCommand to get JSON layer:
<h:head>
<script src="#{facesContext.externalContext.requestContextPath}/js/image-viewer.js" />
...
<h:body>
<h:form id="imageEditor">
<p:fieldset legend="Viewer">
...
// inoutHidden does not have on* events? how am i going to post to image-viewer.js?
<h:inputHidden value="#{imageAnnotations.fetchJsonString()}" />
...
<p:outputPanel layout="block" styleClass="imageEditorImagePanel" />
<p:remoteCommand immediate="true" name="sendJSONToServer" action="#{imageAnnotations.actionOnString}" />
</p:fieldset>
....
Finally in the backbean the JSON object is fetched and stored in a file (implementation is raw):
#ManagedBean(name="imageAnnotations")
public class ImageAnnotations {
//actionOnString fetches and saves the JSON string - this is a raw impementation
public String actionOnString() {
//Do the job and get and save JSON string
}
public String fetchJsonString(){
//Do the job and get JSON string
return jsonString;
}
}
The question is How am i going to use a JSF or primefaces element to make available the imageAnnotations.fetchJsonString() value for fetching from within js?
Even I can't give all answers, for me the filling of your hiddenInput should be managed as following:
#ManagedBean(name="imageAnnotations")
public class ImageAnnotations {
private String jsonString;
public void anyMethodFillingOrInitializingTheJSONString() {
this.jsonString = resultOfYourWork();
}
public String getJsonString(){
return this.jsonString();
}
public void setJsonString(String item) {
this.jsonString = item;
}
}
When you reload this hidden input field, just be sure to trigger a javascript parsing the String and updating your client-side Model. This can be done via the on* - events you can connect with Primefaces buttons.
Guys, can anybody help with the other parts?
With wicket-dnd, is it possible to use dropTop() / dropBottom() with HTML tables? If so, what should the selector be?
I have an HTML table created via a ListView and have had success with dropCentre("tr"), but this is the only drop option that appears to work. Ideally, I would like to use dropTopAndBottom() and see a horizontal divider between table rows which indicates the drop target.
Update:
Here's the relevant code, simplified for for brevity. The table in question has a label per row and is added to a form.
// Container class for Wicket DND
final WebMarkupContainer dataWrapper = new WebMarkupContainer("dataWrapper");
dataWrapper.add(new WebTheme());
final ListView<BinaryData> data = new ListView<BinaryData>("data", list) {
#Override
protected void populateItem(final ListItem<BinaryData> item) {
final BinaryData data = item.getModelObject();
item.add(new Label("label", data.getLabel()));
}
#Override
protected ListItem<BinaryData> newItem(final int index, final IModel<BinaryData> itemModel) {
final ListItem<BinaryData> item = super.newItem(index, itemModel);
item.setOutputMarkupId(true);
return item;
}
};
dataWrapper.add(data);
dataWrapper.add(new DragSource(Operation.MOVE) {
#Override
public void onAfterDrop(final AjaxRequestTarget target, final Transfer transfer) {
}
}.drag("tr"));
dataWrapper.add(new DropTarget(Operation.MOVE) {
#Override
public void onDrop(final AjaxRequestTarget ajaxTarget, final Transfer transfer, final Location location) {
}
}.dropTopAndBottom("tr"));
form.add(dataWrapper);
And the markup:
<div wicket:id="dataWrapper">
<table>
<tbody>
<tr wicket:id="data">
<td wicket:id="label"></td>
</tr>
</tbody>
</table>
</div>
I am using Wicket-DND 0.6.0 and Wicket 6.6.0. When I drag a row using this code, I get the red cross icon displaying in the drag indicator.
wicket-dnd uses standard css selectors to determine drop locations.
The following is the modified TableExample in wicket-dnd-examples:
table.add(new DropTarget(Operation.MOVE)
{
#Override
public void onDrop(AjaxRequestTarget target, Transfer transfer, Location location)
throws Reject
// something was dropped
{
}.dropTopAndBottom("tr");
My problem was caused not by Wicket DND but by a apparently conflicting reference to JQuery UI in my markup (JQuery UI isn't required for Wicket DND, but was present for other components of my application).
Replacing this with a WiQuery-provided reference no longer results in any issues:
#Override
public void renderHead(final IHeaderResponse response) {
super.renderHead(response);
// Ensure that Wicket's jQuery library is always loaded, so we can invoke our own jQuery calls
response.render(JavaScriptReferenceHeaderItem.forReference(getApplication().getJavaScriptLibrarySettings().getJQueryReference()));
response.render(JavaScriptReferenceHeaderItem.forReference(CoreUIJavaScriptResourceReference.get()));
}
So I'm having a heck of a time creating a Datagrid with GWT. I've created my table according the the docs for GWT, and I've added my data, but I can't get it or the datagrid itself to show up at all. What am I missing? I feel I've been tearing my hair out over this. I feel like making an aysnc call might be an issue, but I get no errors. When i compile and execute this portion of my code nothing shows up on the screen and the area where the datagrid is supposed to be on the dock is empty. Am I forgetting something trivial?
static int orderID = 1001;
private static List<OrderLine> orderLineList = new ArrayList<OrderLine>();
final DataGrid<OrderLine> dgOrder = new DataGrid<OrderLine>();
dgOrder.setWidth("100%");
//set columns
TextColumn<OrderLine> orderLineIdColumn = new TextColumn<OrderLine>(){
#Override
public String getValue(OrderLine object) {
return Integer.toString(object.getOrderLineID());
}
};
dgOrder.addColumn(orderLineIdColumn, "OrderLine ID");
TextColumn<OrderLine> productColumn = new TextColumn<OrderLine>(){
#Override
public String getValue(OrderLine object) {
return getProductName(object.getProductNumber());
}
};
dgOrder.addColumn(productColumn, "Product");
TextColumn<OrderLine> quantityColumn = new TextColumn<OrderLine>(){
#Override
public String getValue(OrderLine object) {
return Integer.toString(object.getQuantity());
}
};
dgOrder.addColumn(quantityColumn, "Quantity");
// add data to datagrid
Ioma.dataservice.getOrderLines(orderID, new AsyncCallback<ArrayList<OrderLine>>(){
#Override
public void onFailure(Throwable caught) {// TODO Auto-generated method stub
System.out.println("error in retrieving GP.getOrderLines" + caught.toString());
}
#Override
public void onSuccess(ArrayList<OrderLine> result) {
// TODO Auto-generated method stub
//yes i realize I could also set it to "result" but I use the result in other places as well, I have also tried setting it to result with no success
orderLineList = result;
dgOrder.setRowData(0, orderLineList);
}
});
//add datagrid to the dock
dock.add(dgOrder, DockPanel.EAST);
//add dock to mainPanel
return dock;
When you use the DataGrid you need to give it an explicit size. For CellTable you don't need to so that's why it worked.
When you were using the DataGrid is was there but had both height and width of 0. So you either need to explicitly set the size:
DataGrid<OrderLine> grid = new DataGrid<OrderLine>;
grid.setWidth("500px");
grid.setHeight("600px");
dock.add(dgOrder, DockPanel.EAST);
or you can put the gird in a ProvidesResize widget. So in your case I believe you can make it work with a DockLayoutPanel as opposed to a DockPanel which is what you seem to be using.
I had a smilliar problem . Try to put the datagrid in a Panel that implements the ProvidesResize interface, like SimpleLayoutPanel. Also in my case it helped to set the size of the SimpleLayoutPanel.
Turns out my problem was my declaration.
final DataGrid<OrderLine> dgOrder = new DataGrid<OrderLine>();
should be
final CellTable<OrderLine> dgOrder = new CellTable<OrderLine>();
I can't find out why this works, but it does. I can see my table now. are you not supposed to explicitly call an instance of datagrid I wonder?