I would like to add a click handler to an image that changes the size of the image. The BlobStore allows one to easily change the size of an image by changing the suffix of the URL, as "=s128" will change the image to 128 pixels in the line below:
im.setUrl(thing.get(i)+"=s128");
I want to use this feature to change the size of an image after it is clicked; in this example to change back to its original size, like:
//-- when clicked, do this:
im.setUrl(thing.get(i));
and I thought the following code would do it for a group of images:
for (int i=0; i<thing.size(); i++){
final Image im = new Image();
im.setUrl(thing.get(i)+"=s128");
im.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
im.setUrl(response.get(i));
}
});
htmlpanel.add(im,"imageGrid");
}
But the second "setUrl" line gives me this error:
Multiple markers at this line
- Cannot refer to a non-final variable response inside an inner class defined in a different method
- Cannot refer to a non-final variable i inside an inner class defined in a different method
How can I do this? Thanks.
response and i variables should be final. That why compiler can't compile this code. But you can't make ifinal because you are incrementing it in in for cycle. So you'll have to copy it into some final variable:
for (int i = 0; i < thing.size(); i++){
final Image im = new Image();
final int index = i; //here
im.setUrl(thing.get(i) + "=s128");
im.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
im.setUrl(response.get(index ));
}
});
htmlpanel.add(im, "imageGrid");
}
But the best solution will be to create special click handler class, which will set a specific URL to specific Image.
UPDATE
This structure:
new ClickHandler() {
public void onClick(ClickEvent event) {
im.setUrl(response.get(index ));
}
}
is called an anonymous class. If it needs to access some variable/parameter in method which defines it, such variable/parameter have to be final.
Related
So this is my code. Im trying to make it so the coins collected add to the score in the UI.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreTextScript : MonoBehaviour
{
Text.Text
coinAmount;
//Use this for initialization
void Start ()
{
text = GetComponent<Text>();
}
//Update is called once per frame
void Update ()
{
text.Text = coinAmount;
}
}
The Text is the error but I don't know how to fix it.
I need help immediately
I think you don't understand how variables work in unity.
First you are declaring a Text.text called coinAmount
In Unity when you are declaring a variable you first have to set the access modifier.
The 2 main are: private and public.
private means your variable will only be accessible in the class you declared it.
public means you can access it from any other class if you make a reference to that script.
Then you need to put the type of your variable.
Here you used Text.text and that's not a type for a variable.
You can set to int, string, etc... If you want to use a Text component in unity do like this:
private Text coinAmount;
Since it's a private variable you can't drag it in the editor. If you want to be able to place a Text component by hand in the editor you can either do:
public Text coinAmount;
//or
[SerializeField] private Text coinAmount; //I'll let you search about SerializeField
In your Start method you are assigning text variable to the Text component this object hold. But text does not exist. If you declare a variable in a method it will only be accessible in this method.
So, what you want is:
private void Start(){
coinAmount = GetComponent<Text>();
}
And lastly i see you want to assign your text to the variable we created earlier. That's useless. You need to create a new variable of type int and assign it to the text value of coinAmount.
To do so:
We will create a new variable right under coinAmount.
public int coinNumber;
And in update we can use it:
private void Update(){
coinAmount.text = coinNumber.ToString(); //.ToString() is used when you want to convert something to a string (which is a type of variable).
}
And there we go everything should work correctly !
The whole code:
private Text coinAmount;
public int coinNumber;
private void Start(){
coinAmount = GetComponent<Text>();
}
private void Update(){
coinAmount.text = coinNumber.ToString(); //.ToString() is used when you want to convert something to a string (which is a type of variable).
}
Hope it helped ! Have a nice day !
I am new in iText 7, i am developing a spa project (asp.net, c#, and angularjs), where i need to implement a report for existing html page.I found iText 7 (.Net) has a easy way to implement it. Using below code of line, that's return me a byte array and i can easily show in browser as pdf also can download.
var memStream = new MemoryStream();
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.SetFontProvider(fontProvider); converterProperties.SetBaseUri(System.AppDomain.CurrentDomain.BaseDirectory);
HtmlConverter.ConvertToPdf(htmlText, memStream, converterProperties);
In my raw html there has some html tables (every table has some particular rows) and i want to keep them in a page (i mean if table rows not fit in a single page then start from next page). I got a solution like below
Paragraph p = new Paragraph("Test");
PdfPTable table = new PdfPTable(2);
for (int i = 1; i < 6; i++) {
table.addCell("key " + i);
table.addCell("value " + i);
}
for (int i = 0; i < 40; i++) {
document.add(p);
}
// Try to keep the table on 1 page
table.setKeepTogether(true);
document.add(table);
But in my case i cannot implement like that way because content already exist in html tables (in my existing html page).
Advance thanks, if anyone can help me.
This can easily be done using a custom TagWorkerFactory and TableTagWorker class.
Take a look at the code samples below.
The first thing we should do is create a custom TableTagWorker that tells iText to keep the table together. We do this using the code you've mentioned: table.setKeepTogether(true).
class CustomTableTagWorker extends TableTagWorker{
public CustomTableTagWorker(IElementNode element, ProcessorContext context) {
super(element, context);
}
#Override
public void processEnd(IElementNode element, ProcessorContext context) {
super.processEnd(element, context);
((com.itextpdf.layout.element.Table) getElementResult()).setKeepTogether(true);
}
}
As you can see the only thing we changed on our custom TableTagWorker is the fact that it has to keep the table together.
The next step would be to create a custom TagWorkerFactory that maps our CustomTableTagWorker to the table tag in HTML. We do this like so:
class CustomTagWorkerFactory extends DefaultTagWorkerFactory{
#Override
public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
if (tag.name().equalsIgnoreCase("table")) {
return new CustomTableTagWorker(tag, context); // implements ITagWorker
}
return super.getCustomTagWorker(tag, context);
}
}
All we do here is tell iText that if it finds a table tag it should pass the element to the CustomTableTagWorker, in order to be converted to a PDF object (where setKeepTogether == true).
The last step is registering this CustomTagWorkerFactory on our ConverterProperties.
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setTagWorkerFactory(new CustomTagWorkerFactory());
HtmlConverter.convertToPdf(HTML, new FileOutputStream(DEST), converterProperties);
Using these code samples I was able to generate an output PDF where tables, if small enough to render on an entire page, will never be split across multiple pages.
I had a similar issue of trying to keep together content within a div. I applied the following css property and this kept everything together. This worked with itext7 pdfhtml.
page-break-inside: avoid;
I want to display data. I used AfterFieldChange method to display the data but it turns out the radio button doesn't change. I already insert the data customer table, the BAQ (Business Activity Query) also work just that the screen form doesn't work.
private void UD24_AfterFieldChange(object sender, DataColumnChangeEventArgs args)
{
// ** Argument Properties and Uses **
// args.Row["FieldName"]
// args.Column, args.ProposedValue, args.Row
// Add Event Handler Code
//EpiDataView edvUD24 = ((EpiDataView)(this.oTrans.EpiDataViews["UD24"]));
//System.Data.DataRow edvUD24Row = edvUD24.CurrentDataRow;
EpiDataView view = oTrans.EpiDataViews["UD24"] as EpiDataView;
switch (args.Column.ColumnName)
{
case "Character03":
DataTable tblcust=customer(args.Row["Character03"].ToString());
if(tblcust!=null && tblcust.Rows.Count>0)
{
string client = tblcust.Rows[0]["Customer_client1_c"].ToString();
view.dataView[view.Row]["ShortChar04"] = client;
//MessageBox.Show(Client);
}
break;
}
}
After changing the data in the EpiDataView you need to call Notify to make it call the UI elements that need to be updated:
view.dataView[view.Row]["ShortChar04"] = client;
view.Notify(new Ice.Lib.Framework.EpiNotifyArgs(this, view.Row, NotifyType.Initialize));
Kieym, perhaps try adding EpiNotifyArgs into your declaration, like so:
private void UD24_AfterFieldChange(object sender, DataColumnChangeEventArgs args, EpiNotifyArgs args)
I'm currently working on an Adobe AIR application which is targeting the iPad2 as the hardware platform, and can not get decent scrolling performance on one of the screens. I'm using a spark list, with a custom item renderer like so:
<s:List id="productList" top="116" bottom="0" left="10" right="10"
width="100%"
visible="true" includeInLayout="true"
height="0"
maxHeight="500"
opaqueBackground="#ffffff"
itemRenderer="myRenderer">
</s:List>
Originally, I was using an .mxml renderer, but after seeing the nasty performance I decided to roll my own, extending UIComponent (I've left off the package and braces to save on horizontal space):
import mx.controls.listClasses.IListItemRenderer;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.utils.ColorUtil;
import spark.components.Label;
import spark.components.TextInput;
public final class OrderViewProductLineTestIR extends UIComponent implements IListItemRenderer
{
public function OrderViewProductLineTestIR()
{
super();
}
// Internal variable for the property value.
private var _data:Object;
private var productName:Label;
private var orderQty:TextInput;
private var stockQty:TextInput;
// Make the data property bindable.
[Bindable("dataChange")]
// Define the getter method.
public function get data():Object
{
return _data;
}
// Define the setter method, and dispatch an event when the property
// changes to support data binding.
public function set data(value:Object):void
{
_data = value;
invalidateProperties();
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
override protected function createChildren():void
{
super.createChildren();
productName = new Label();
// productName.visible = true;
addChild(productName);
orderQty = new TextInput();
addChild(orderQty);
stockQty = new TextInput();
addChild(stockQty);
}
override protected function commitProperties():void
{
super.commitProperties();
productName.text = _data.Name;
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
productName.move(0, 0);
productName.setActualSize(250, 48);
orderQty.move(270, 0);
orderQty.setActualSize(100, 48);
stockQty.move(390, 0);
stockQty.setActualSize(100, 48);
}
override protected function measure():void
{
super.measure();
measuredWidth = 490;
measuredHeight = 48;
}
}
As you can see this is pretty light-weight, yet my dataprovider contains upwards of 100 items, and 11 of them can be on screen at any one time. Everything I've read around increasing performance for scrolling revolves around using opaqueBackground and cacheAsBitmap, however no matter what I try neither help here. Using cacheAsBitmap at the list level doesn't help as the item renderer recycling kicks in once you've scrolled more than a couple of lines requiring the whole thing to be re-rendered, and using it at the item renderer level is still horribly slow when scrolling fast — presumably because many are being recycled at once during a very fast scroll.
I know the iPad should have no problem blitting a screenful of information in a frame at 60 fps, yet when I scroll quickly I'm seeing it struggle to make 10 fps (from sight). So the question: have I missed something obvious, or is this to be expected due to the number of layers (and vector rendering) involved when using AIR? For the record, I have tried changing the render mode for the application and tried changing the frame rate to eliminate the obvious.
This is a bit of guessing, but can the itemRenderer be optimized? Do all the children need to be positioned and sized every time component redraws? Do you need to update productName.text every time commitProperties run?
Here is how I might modify things:
import mx.controls.listClasses.IListItemRenderer;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.utils.ColorUtil;
import spark.components.Label;
import spark.components.TextInput;
public final class OrderViewProductLineTestIR extends UIComponent implements IListItemRenderer
{
public function OrderViewProductLineTestIR()
{
super();
}
// Internal variable for the property value.
private var _data:Object;
// Add a dataChanged property
private var dataChanged :Boolean = false
private var productName:Label;
private var orderQty:TextInput;
private var stockQty:TextInput;
// Make the data property bindable.
[Bindable("dataChange")]
// Define the getter method.
public function get data():Object
{
return _data;
}
// Define the setter method, and dispatch an event when the property
// changes to support data binding.
public function set data(value:Object):void
{
_data = value;
// switch the dataChanged flag
dataChanged = true;
invalidateProperties();
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
override protected function createChildren():void
{
super.createChildren();
productName = new Label();
// productName.visible = true;
addChild(productName);
orderQty = new TextInput();
addChild(orderQty);
stockQty = new TextInput();
addChild(stockQty);
}
override protected function commitProperties():void
{
super.commitProperties();
// Only update the display if the data actually changed
If(dataChanged){
productName.text = _data.Name;
dataChanged = false;
}
}
// add variable to tell whether the component's children have been sized and positioned or not
// since they have static locations, no need to set these each time
protected var compChildrenSized :Boolean = false;
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(!compChildrenSized){
productName.move(0, 0);
productName.setActualSize(250, 48);
orderQty.move(270, 0);
orderQty.setActualSize(100, 48);
stockQty.move(390, 0);
stockQty.setActualSize(100, 48);
compChildrenSized = true;
}
}
override protected function measure():void
{
super.measure();
measuredWidth = 490;
measuredHeight = 48;
}
}
I guess I'll add that I'm not sure measure will ever run. What happens if you replace the textInputs with labels? Are you using Flex 4.6, and if so are you using StyleableStageText (AKA StageText) or the 4.5 skin which uses StyleableTextField? I wonder if StageText scrolling could kill performance because it hangs out above the Flash Display list.
What happens if you remove the textInput completely and replace with labels?
These are little things, and I'm not sure if they'll help.
Try just this on your "Spark List component"
1/ add a layout (horizontal or vertical depending on what you want ;)
2/ add attribute "useVirtualLayout=true" on your list component !
And tell me what's the result ... but i think it will be smoother (very very smoother),
because when you add your elements to the list, all the components are rendered, even if
they are out of the layout ... so whith "useVirtualLayout" just items that are on the viewport are rendered others are destroyed ...
See ya ! and have fun whith Flash Builder ! it's a so cool technology to have a multi support app !
A bit late. but.
Its true that its better to use starling and feather if you want something close to native performance.
But you can still optimise your renderer.
Please dont use binding anywhere in a Flex mobile application.
Extending UIComponent is the right thing to do.
I think it would be better to not use invalidation and set your properties in the data setter.
Hope it helps.
I have a form with a combobox/drop down to select the user language. If the user changes the language, I'd like to update all the labels but leave the input elements alone.
In jQuery, I'd request a list of label IDs and the new texts via JSON and then use a loop like this:
var texts = {[ {id:'nameLabel', text:'First Name'}, {id:'familyLabel', text:'Family Name'} ]};
for( var i=0; i<texts.length; i++) {
var item = texts[i];
$('#'+item.id).text(item.text);
}
That would update all the labels without modifying anything else. How do I do this in Wicket?
[EDIT] What I tried:
DropDownChoice<Locale> ddc = new DropDownChoice<Locale>(...);
ddc.add( new AjaxFormComponentUpdatingBehavior("onchange") {
private static final long serialVersionUID = 1L;
#Override
protected void onUpdate( AjaxRequestTarget target ) {
getSession().setLocale( language );
for( MarkupContainer label : labels ) {
target.addComponent( label );
}
}
});
This does change the labels but it also renders all the input fields again. I found no way to access the current values of the input fields.
[EDIT2] The list of labels is created like so:
StringResourceModel usernameLabel = new StringResourceModel("usernameLabel", this, new Model<ValueMap>(map));
labels.add(add(new Label("usernameLabel", usernameLabel)));
This is wrong:
labels.add(add(new Label("usernameLabel", usernameLabel)));
You're not adding Label instances to 'labels', it's repeatedly adding the container you are adding it to (probably the Page instance). The method 'add()' doesn't return the component being added, it returns the container you are adding the components into.
Try changing it to:
Label label = new Label("usernameLabel", usernameLabel);
add(label);
labels.add(label);