How to get AutoCompleteTextField to accept a substring - java

I can generate a list of strings used to select an item using AutoCompleteTextField but it puts the entire string in the edit control. I would like it to just insert the 'name' string.
Should I create a Model that contains the name string and the rendered string?
Which functions should I override to get the required string, to get a value or to handle the click?
private Model<String> groupToJoinModel = new Model<String>();
final AutoCompleteTextField<String> field = new AutoCompleteTextField<String>("ac", new Model<String>(""))
{
private static final long serialVersionUID = 1L;
#Override
protected Iterator<String> getChoices(String input)
{
List<String> choices = new ArrayList<String>(5);
// from a database: generate lookup items
// by concatenating strings: name, type, description
// code omitted
return choices.iterator();
}
};
form.add(field);
groupToJoinModel = (Model<String>) field.getDefaultModel();
// Create a button to perform an action
Button joinGroupsButton = new Button("joinGroupButton")
{
private static final long serialVersionUID = -4974389888115885756L;
#Override
public void onSubmit()
{
if (groupToJoinModel.getObject() != null)
{
// An action is performed on the contents of the edit control
}
}
};
form.add(joinGroupsButton);

You can use AbstarctAutoCompleteRenderer.
AbstractAutoCompleteRenderer<String> autoCompleteRenderer = new AbstractAutoCompleteRenderer<String>() {
private static final long serialVersionUID = 1L;
protected final String getTextValue(final String bean) {
String name;
// Do you logic to extract the name from the bean
...
...
...
return name;
}
#Override
protected final void renderChoice(final String object, final Response response, final String criteria) {
response.write(getTextValue(object));
}
};
final AutoCompleteTextField<String> autoComp = new AutoCompleteTextField<String>("item", new PropertyModel(str, "item"),
autoCompleteRenderer) {
private static final long serialVersionUID = 1L;
#Override
protected Iterator<String> getChoices(String arg0) {
// Your logic
...
...
...
return filteredList.iterator();
}
};
The renderer is passed in the Auto complete constructor.

Related

Deep copy Object ArrayList in Java

Java object to copy:
public class InfoDtcEx implements Serializable {
private static final long serialVersionUID = 1L;
private String infoCall="";
private String infoNotCall="";
private String infoTarget="";
private String infoTotal="";
private String infoValue="";
private ArrayList<String> valueList;
public InfoDtcEx(String infoCall, String infoNotCall,
String infoTarget, String infoTotal, String infoValue) {
this.infoCall = infoCall;
this.infoNotCall = infoNotCall;
this.infoTarget = infoTarget;
this.infoTotal = infoTotal;
this.infoValue = infoValue;
this.infoValueBefore = this.infoValue;
}
public InfoDtcEx(InfoDtc infoDtc) {
this.infoCall = infoDtc.getinfoDtcCall();
this.infoNotCall = infoDtc.getinfoDtcNotCall();
this.infoTotal = infoDtc.getinfoDtcTotal();
this.infoValue = infoDtc.getinfoDtcValue();
this.infoValueBefore = this.infoValue;
}
//getters and setters
}
I tried Using below method to deep copy as suggested at How to copy elements from an ArrayList to another one NOT by reference?:
private ArrayList<InfoDtcEx> copyInfoList(ArrayList<InfoDtcEx> infoListExChanged) {
infoListExChanged.clear();
for (int i = 0; i < infoListEx.size(); i++) {
String infoCall = infoListEx.get(i).getinfoCall();
if(infoCall != "Yes") {
infoListExChanged.add(infoListEx.get(i));
}
}
return infoListExChanged;
}
But, this is changing the actual list infoListEx as well.
You are not performing the deep copy as suggested in the post you linked to.
That post had the following line in the accepted answer :
copia.add(new Articulo_Venta(av.get(i)));
Notice the construction of the new Articulo_Venta. Your code is not calling new.
So try changing your line where you are adding to the list to create a new object, so :
infoListExChanged.add(new InfoDtcEx(infoListEx.get(i)));

Why I am getting this errors?

I am trying to access to a method named sendHttpPost(final AsyncReponseHttpSending delegate, final String urlString, final Object data), which is in another class, and this class has a private constructor. However when I get the method like HttpSending postMethod = HttpSending.sendHttpPost() and I start to pass the same parameters than in the original class I get the error "delegate is always null" , "data is always null", delegate is an instance of the AsyncResponseHttpSending interface which have only one method void onHttpResult(int httpCode, String httpMessage, String body);what am I doing wrong?
Class from where I get the method
public class HttpSending {
private static final String TAG = "HttpSending: ";
private static final int TIMEOUT_CONNECTION = (int) (30 * UnitsConstants.SECOND_TO_MILISECOND);
private static final int TIMEOUT_READ = (int) (60 * UnitsConstants.SECOND_TO_MILISECOND);
private HttpSending() {
}
public static void sendHttpPost(final AsyncReponseHttpSending delegate, final String urlString, final Object data) {
new Thread(TAG) {
#Override
public void run() {
//BUNCH OF CODE
}
}.start();
}
Class where I do my request
public class HttpPost {
AsyncReponseHttpSending delegate = new AsyncReponseHttpSending() {
#Override
public void onHttpResult(int httpCode, String httpMessage, String body) {
}
};
final String url = "https://postman-echo.com/post";
final Object data = null;
HttpSending postMethod = HttpSending.sendHttpPost(delegate,url,data );
}
This line:
HttpSending postMethod = HttpSending.sendHttpPost(delegate,url,data );
should not compile because HttpSending.sendHttpPost is a void method.
Because you never instantiate delegate that's why you get the warnings for its null.

Constructor on typescript enum?

We have a situation at the moment with our code where we are using Enums in our Java layer which store an id and a 'display value' with a constructor like below:
public enum Status implements EnumIdentity {
Active(1, "Active"),
AwaitingReview(2, "Awaiting Review"),
Closed(3, "Closed"),
Complete(4, "Complete"),
Draft(5, "Draft"),
InProcess(6, "In Process"),
InReview(7, "In Review"),
NotStarted(8, "Not Started"),
PendingResolution(9, "Pending Resolution"),
Rejected(10, "Rejected");
private int id;
private String displayValue;
PlanStatus(final int id, String displayValue) {
this.id = id;
this.displayValue = displayValue;
}
/** {#inheritDoc} */
#Override
public int id() {
return id;
}
public String getDisplayValue() {
return displayValue;
}
}
and we would like something in typescript to match this to allow for displaying the status in a meaningful way for carrying out logic and for display the value to the user on the front end.
Is this possible? Is there a better way to handle this? We would like to avoid having to use logic such as does status.id() = 1 or status.name() = 'Active' hence for the push towards enums.
Thanks
Typescript does not support expanded enums such as in java. You can achieve a similar effect using a class:
interface EnumIdentity { }
class Status implements EnumIdentity {
private static AllValues: { [name: string] : Status } = {};
static readonly Active = new Status(1, "Active");
static readonly AwaitingReview = new Status(2, "Awaiting Review");
static readonly Closed = new Status(3, "Closed");
static readonly Complete = new Status(4, "Complete");
static readonly Draft = new Status(5, "Draft");
static readonly InProcess = new Status(6, "In Process");
static readonly InReview = new Status(7, "In Review");
static readonly NotStarted = new Status(8, "Not Started");
static readonly PendingResolution = new Status(9, "Pending Resolution");
static readonly Rejected = new Status(10, "Rejected");
private constructor(public readonly id: number, public readonly displayValue: string) {
Status.AllValues[displayValue] = this;
}
public static parseEnum(data: string) : Status{
return Status.AllValues[data];
}
}

Can't override node settings in ES integration test

I am writing an integration test for elasticsearch 5.3.
public class ProtectedWordsIndexTests extends ESIntegTestCase {
private final WordDelimiterActionListener wordsListener =
WordDelimiterActionListener.getInstance();
private final static String INDEX_NAME = "protected_words";
private final static String TYPE_NAME = "word";
private final static String FILTER_NAME = "my_word_delimiter";
#Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(WordDelimiterPlugin.class);
}
#Override
protected Settings nodeSettings(int nodeOrdinal) {
return builder()
.put("plugin.types", TYPE_NAME)
.put("plugin.dynamic_word_delimiter.refresh_interval", "500ms")
.put(super.nodeSettings(nodeOrdinal))
.build();
}
public void testAddWordToIndex() throws Exception {
Settings indexSettings = builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put("index.analysis.filter.my_word_delimiter.type", "dynamic_word_delimiter")
.build();
TokenFilterFactory filterFactory = filterFactory(indexSettings, FILTER_NAME);
createIndex(INDEX_NAME);
ensureGreen();
client().prepareIndex(INDEX_NAME, TYPE_NAME, "1")
.setSource("word", "1tb")
.execute();
Thread.sleep(TimeValue.timeValueSeconds(1).getMillis());
Set<String> protectedWords = wordsListener.getProtectedWords();
assertTrue(protectedWords.size() == 1);
}
}
When I am running testAddWordToIndex() I am getting the following error:
"java.lang.IllegalArgumentException: unknown setting
[plugin.dynamic_word_delimiter.refresh_interval] please check that any
required plugins are installed, or check the breaking changes
documentation for removed settings"
If I remove the following part and increase the refresh interval to be more than the default, the test passes. So I just can't override this.
.put("plugin.dynamic_word_delimiter.refresh_interval", "500ms")
The default refresh interval is declared here:
public class WordDelimiterRunnable extends AbstractRunnable {
public static final TimeValue REFRESH_INTERVAL = TimeValue.timeValueSeconds(20);
public static final String INDEX_NAME = "protected_words";
public static final String INDEX_TYPE = "word";
public static final int RESULTS_SIZE = 10000;
private volatile boolean running;
private final Client client;
private final String index;
private final long interval;
private final String type;
public WordDelimiterRunnable(Client client, Settings settings) {
this.client = client;
this.index = settings.get("plugin.dynamic_word_delimiter.protected_words_index", INDEX_NAME);
this.type = settings.get("plugin.dynamic_word_delimiter.protected_words_type", INDEX_TYPE);
this.interval = settings.getAsTime("plugin.dynamic_word_delimiter.refresh_interval", REFRESH_INTERVAL).getMillis();
}
// more code here
}
You need to register the setting using the SettingsModule#registerSettings(Setting) method as explain here:
https://www.elastic.co/guide/en/elasticsearch/reference/5.x/breaking_50_settings_changes.html#breaking_50_settings_changes

How to change the html of a HTMLPanel

I want do declare a Subclass of an HTMLPanel.
In its constructor I want to give it a few paramters to construct the containing html.
Because I have to call the super-constructor as first statement, I have to change the html later in the constructor.
How can I do this?
public class MyHTMLPanel extends HTMLPanel
{
public MyHTMLPanel(String id, int anotherParameter)
{ super("");
String html=""
// ... some code th construct the html
//??? this.setHtml(html);
}
}
You can find below an example I used and worked well for me.
I don't remember why I don't sub-class HTMLPanel, whether a good reason or not.
You will notice a mechanism to randomize the html ids in case you include several objects of the same type in a single page.
public abstract class HtmlPanelBase extends Composite
{
private String _dynPostfix = "";
protected final String id(final String staticId) { return staticId + _dynPostfix; }
private final String wrapId(final String id) { return "id=\"" + id + "\""; }
private final String wrapDynId(final String refId) { return wrapId(id(refId)); }
private String _htmlAsText = null;
public String getHtmlAsText() { return _htmlAsText; }
abstract protected String htmlPanelBundleHtmlText();
abstract protected List<String> idList();
protected HTMLPanel _holder = null;
private HTMLPanel createHtmlPanel(final boolean defineGloballyUniqueIds)
{
// Referent HTML panel text containing the reference id's.
_htmlAsText = htmlPanelBundleHtmlText();
if (defineGloballyUniqueIds)
{
// List of id's in the HTML Panel reference page to replace with dynamic/unique id's.
final List<String> refIdList = idList();
// Replace the reference id's with dynamic/unique id's.
for (String refId : refIdList)
_htmlAsText = _htmlAsText.replace(wrapId(refId), wrapDynId(refId));
}
// Return the HTMLPanel containing the globally unique id's.
return new HTMLPanel(_htmlAsText);
}
public HtmlPanelBase(final boolean defineGloballyUniqueIds)
{
setup(defineGloballyUniqueIds);
initWidget(_holder);
}
private void setup(final boolean defineGloballyUniqueIds)
{
if (defineGloballyUniqueIds)
_dynPostfix = "_" + UUID.uuid().replace("-", "_");
_holder = createHtmlPanel(defineGloballyUniqueIds);
}
}
And now how you could sub-class from the above base:
public class HtmlPanelTemplate extends HtmlPanelBase
{
private final static boolean _defineGloballyUniqueIds = false;
private final static int _numIdCapacity = 40;
public HtmlPanelTemplate()
{
super(_defineGloballyUniqueIds);
setup();
}
#Override
protected String htmlPanelBundleHtmlText()
{
return YourClientBundle.INSTANCE.getYourFileHtml().getText();
}
#Override
protected List<String> idList()
{
final List<String> idList = new ArrayList<String>(_numIdCapacity);
return idList;
}
private void setup()
{
}
}
You don't need to subclass HTMLPanel. You can create a simple Composite widget:
public class myPanel extends Composite {
private HTMLPanel panel = new HTMLPanel();
public myPanel(String id, int anotherParameter) {
// set HTML to panel based on your parameters
initWidget(panel);
}
}
htmlPanel.getElement().setInnerHTML(...)
Don't know whether this works in derived class' constructor. But setting up a class for specific content text isn't really a good solution.

Categories

Resources