Is there any solution for build a Feedback Panel that contains inside messages with Link? I try to use this:
StringBuilder stringBuilder= new StringBuilder(512);
stringBuilder.append("<a href=\"");
stringBuilder.append(Utils.getAbsoluteUrl(EditBookingSourcePage.class, new PageParameters())+"");
stringBuilder.append("\">Clicca Qui!</a>");
feedbackErrorPanel.info(stringBuilder);
public static <C extends Page> String getAbsoluteUrl(final Class<C> pageClass, final PageParameters parameters) {
CharSequence resetUrl = RequestCycle.get().urlFor(pageClass, parameters);
String abs = RequestUtils.toAbsolutePath("/", resetUrl.toString());
final Url url = Url.parse(abs);
return RequestCycle.get().getUrlRenderer().renderFullUrl(url);
}
but doesn't work.
You will need to call feedbackPanel.setEscapeModelStrings(false).
Without this Wicket will escape all HTML characters to prevent XSS attack.
As #martin-g mentioned first you should escape the html tag. feedbackPanel.setEscapeModelStrings(false)
As you mentioned you did. I believe url construct issue . So whatever you have done on Top of that Try below step. I have tried below solution it worked for me .
//since you are not passing any parameter we can send null
String absoluteUrl = RequestCycle.get().getUrlRenderer().renderFullUrl(
Url.parse(urlFor(EditBookingSourcePage.class, null).toString()));
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<a href=");
stringBuilder.append(absoluteUrl);
stringBuilder.append("\">Clicca Qui!</a>");
feedbackErrorPanel.info(stringBuilder);
In WicketApplication page
mountPage("setting/booking-source", EditBookingSourcePage.class);
Another apporach is to:
1, extend org.apache.wicket.markup.html.panel.FeedbackPanel
2, extend org.apache.wicket.feedback.FeedbackMessage and store data
3, Create MyMessagePanel with its own markup, model object
4, override newMessageDisplayComponent method in extended FeedbackPanel
#Override
protected Component newMessageDisplayComponent(String id, FeedbackMessage message) {
//message with its own markup
if (message.getClass().equals(MyMessage.class)) {
MyMessage msg = (MyMessage) message;
return new MyMessagePanel(id, Model.of(new MyMessagePanelModelObject(msg.getModelObject()))); //my message markup
}
return super.newMessageDisplayComponent(id, message); //other messages
}
Related
I am trying getting data from an API using volley. I am trying to store it as a global variable, but it always returns null. Why?
Here is my sample code:
JsonObjectRequest jsonRequest = new JsonObjectRequest
(Request.Method.GET, url, null, response -> {
try {
if (response.getString("action").equals("success")) {
checkInTime = response.getString("checkin");
checkOutTime = response.getString("chekout");
System.out.println(response);
}
} catch (JSONException e) {
e.printStackTrace();
}
}, Throwable::printStackTrace);
Volley.newRequestQueue(MainActivity.this).add(jsonRequest);
What is the problem here?
here is my api json response
{"action":"success","checkin":"08:30:25","chekout":"blank"}
It does not working out of the request parenthesis
because this variable is temporary and it can be null if no data found.
So you have to write looks like
public static String checkInTime = "";
public static String checkOutTime = "";
After declaring global variable of String you can store data and can access from anywhere
checkInTime = response.getString("checkin");
checkOutTime = response.getString("chekout");
Its actually working for me
From the context you provided I guess you have a problem with some of these lines:
if (response.getString("action").equals("success")) {
checkInTime = response.getString("checkin");
checkOutTime = response.getString("chekout");
Reason 1 - you are not entering the if body
Reason 2 - you are not getting the response values properly
Try to debug the function
If I need to debug it I will:
Print the response before the IF statement
Print these values:
response.getString("action") checkInTime = response.getString("checkin"); checkOutTime = response.getString("chekout");
If it's being done from an Activity:
create a variable, e.g.:
public class MainActivity extends AppCompatActivity {
private String checkInTime;
Then in the code you posted above, add:
if (response.getString("action").equals("success")) {
this.checkInTime = response.getString("checkin");
Now try to access it from other places.
If it's not what you are looking for, please update the question with the relevant code regarding your global variable.
I see in the API that it's possible but I can't figure out how to use that sanitize() method. There's even a forum post where someone says to use it but they don't explain how. In essence I have no idea what CTX means in that method signature. If someone can provide sample code of how to get a list of items that were sanitized that would be appreciated.
You need to setup the HtmlChangeListener to catch all elements that are sanitized. The code then looks something like:
List<String> results = new ArrayList<String>();
HtmlChangeListener<List<String>> htmlChangeListener = new HtmlChangeListener<>()
{
#Override
public void discardedTag(List<String> context, String elementName)
{
context.add(elementName);
}
#Override
public void discardedAttributes(List<String> context, String tagName, String... attributeNames)
{
context.add(tagName);
}
};
String sanitizedHtml = POLICY_DEFINITION.sanitize(rawHtml, htmlChangeListener, results);
System.out.println("Sanitized elements include: " + String.join(",", results));
I am creating a utility that will add a multi-line text field just below the last line of text in an existing PDF document. This will be used for people who want to add comments to a report that is generated from another system.
I followed the examples from the iText book, and also looked at this SO question: Get the exact Stringposition in PDF
So now I've got a method that parses the last page of the document and a custom listener that finds the coordinates of the text I'm looking for.
Here is my code parsing method:
private void parsePdfPage2(String src, int pageNum) throws IOException {
PdfReader reader = new PdfReader(src);
RenderListener listener = new MyTextRenderListener();
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
PdfDictionary pageDic = reader.getPageN(pageNum);
PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);
}
And here is the listener:
public class MyTextRenderListener implements RenderListener {
#Override
public void beginTextBlock() {}
#Override
public void endTextBlock() {}
#Override
public void renderImage(ImageRenderInfo renderInfo) {}
#Override
public void renderText(TextRenderInfo renderInfo) {
// Check if this is the text marker
String text = renderInfo.getText();
if (text.equalsIgnoreCase("Comments")) {
// Found it
LineSegment ls = renderInfo.getBaseline();
System.out.println("Found at X: " + ls.getBoundingRectange().getX() +
", Y: " + ls.getBoundingRectange().getY());
}
}
}
However, now I need to send the found LineSegment object (or the individual coordinates) back to the original parsing method. Of course I could write the values to disk and read it in the parsing method, but that seems horrible. I'm pretty sure there is a more elegant way to achieve this and would appreciate pointers.
This is an old question but still:
You could save the results of the listener into a private list (in the class).
After that what's left to add is a public method (getResults()) which returns the list.
Simply call getResults after the processContent call since the synchronous nature of the processContent method guarentees the list to be filled correctly.
The only problem with this solution is that listeners can't be reused.
I want to download a CSV file using Wicket, by implementing an AbstractResource. It looks something like this:
public class ExportCsvFileResource extends AbstractResource
{
#Override
protected AbstractResource.ResourceResponse newResourceResponse(IResource.Attributes attributes)
{
AbstractResource.ResourceResponse resourceResponse = new AbstractResource.ResourceResponse();
resourceResponse.setContentType("text/csv");
resourceResponse.setFileName("exported-contacts-file.csv");
resourceResponse.setTextEncoding("utf-8");
resourceResponse.setWriteCallback(new AbstractResource.WriteCallback()
{
#Override
public void writeData(IResource.Attributes attributes) throws IOException
{
OutputStream stream = attributes.getResponse().getOutputStream();
generateContentInBatches(stream);
}
});
return resourceResponse;
}
private void generateContentInBatches(OutputStream stream)
{
int numberOfChunks=//...
for (int i=0; i<numberOfChunks; i++)
{
byte[] contentChunk = retrieveContentFromBackend(i);
IOUtils.write(contentChunk, stream);
}
}
}
The problem is that, while the content is being generated with the retrieveContentFromBackend function (which is quite time consuming), the user interface is unresponsive. I click the buttons etc. but nothing happens, only after the file is done being generate can I use the interface again.
How do I avoid blocking the user interface while the file is being generated gradually?
Take a look at RequestMapperApplication and MapperDemoResourceReference from wicket-examples.
You can mount resource references:
mountResource("/print/${sheet}/${format}", new MapperDemoResourceReference());
To load such a resource without blocking the page, you'll have to render a link which triggers the resource directly:
add(new WebMarkupContainer("link")
{
#Override
protected void onComponentTag(ComponentTag tag)
{
super.onComponentTag(tag);
PageParameters parameters = new PageParameters();
parameters.add("sheet", "sheet1");
parameters.add("format", "A4");
tag.put("href", urlFor(new MapperDemoResourceReference(), parameters));
}
});
Here is an example of lazy loading:
http://www.wicket-library.com/wicket-examples/ajax/lazy-loading?1
I don't know how this works with your AbstractResource object but this should get you in the right direction.
I am having a problem with custom components in facelets. The first time that the page is rendered, the attributes are set properly on the component class. When a form is submitted however, the attributes are not set.
Here is the class that I am using to test this.
public class TestEcho extends UIData
{
/** Logger. */
private static Log log = LogFactory.getLog(TestEcho.class);
private String msg;
public TestEcho()
{
log.debug("Constructor.");
}
public void encodeEnd(FacesContext context) throws IOException
{
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeText("The value of msg is '" + msg + "'.", null);
writer.endElement("div");
}
public void setMsg(String msg)
{
log.debug("Setting msg to '" + msg + "'.");
this.msg = msg;
}
}
The component is used in the .xhtml page like this.
<h:form>
<v:testEcho msg="hello" />
<h:commandButton action="#{PictureManager.trigger}" value="Click" />
</h:form>
When the page renders for the first time, the component renders the following html code.
<div>The value of msg is 'hello'.</div>
When the button is clicked, it renders this.
<div>The value of msg is 'null'.</div>
From the log, you can see that the component is constructed again, but the attribute is not set.
13:23:42,955 DEBUG [TestEcho] Constructor.
13:23:42,955 DEBUG [TestEcho] Setting msg to 'hello'.
----- Button was pressed here -----
13:25:48,988 DEBUG [TestEcho] Constructor.
13:25:49,144 DEBUG [PictureManager] Button pressed.
From what I understand, facelets does all the wiring of attributes to components so I don't need a tag class, but I don't understand why the attribute would be set correctly the first time, but not the second time.
You must save your state by overriding the saveState and restoreState methods.
So, saveState must return a Serializable object (e.g. a JavaBean or Object[] array) containing the value in msg and whatever is returned by super.saveState. This object will be provided to restoreState where the method must restore msg from the object and pass the parent state to super.restoreState.
McDowell's answer did it. Just for completeness, here's the two methods I added.
public Object saveState(FacesContext context)
{
Object[] rtrn = new Object[2];
rtrn[0] = super.saveState(context);
rtrn[1] = msg;
return rtrn;
}
public void restoreState(FacesContext context, Object state)
{
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
msg = (String) values[1];
}