How do I allow a "SPACE" character in an AutoComplete JavaFX uneditable ComboBox? - combobox

When I type a SPACE character in an AutoComplete ComboBox, I can get the space character to be accepted except the addEventFilter code I'm using to manage it multiplies and inserts a space for each character previously typed prior to the space. You can see a screen shot example below where 3 spaces were added after the 3 characters (ive), then 4 spaces added after I include an additional charater (t), each after typing a single SPACE, and the spaces only appear after I type the next character (e.g. 'm').
I did try this with the ContolsFX AutoComplete, but it cannot handle the uneditable ComboBox - and couldn't find anything to the contrary. In the online cases I research, it was recommended to use the ComboBox's popup skin - addEventFilter to manage the SPACE character event. In nearly all the cases it was to consume() and prevent the space from selection and closing. I did not find anything that strictly allowed the space to be entered. I've tried adding the SPACE in code prior to and after this Event Code but the addEventFilter event.consume() will remove it. The SPACE character will only appear if I manage its addition within the addEventFilter method. I've tried different events such as KeyEvent.ANY, KeyEvent.KEY_TYPED, and KeyEvent.KEY_RELEASE and read the documentation on the KeyEvent, but only KeyEvent.KEY_PRESSED seems to allow the SPACE character, it just multiplies the number of spaces, and doesn't insert until the next text character.
ComboBoxListViewSkin cbSkin = cbSkin = new ComboBoxListViewSkin(cmb);
// cmb is the ComboBox
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if(event.getCode() == KeyCode.SPACE){
filter += " ";
event.consume();}
});

I was able to solve my problem. The event code needed to be a part of the ComboBoxAutoComplete constructor and not part of the onKeyPressed event.
private ComboBoxListViewSkin cbSkin;
public ComboBoxAutoComplete(ComboBox<T> cmb) {
this.cmb = cmb;
cbSkin = new ComboBoxListViewSkin(cmb);
originalItems = FXCollections.observableArrayList(cmb.getItems());
cmb.setOnKeyPressed(this::handleOnKeyPressed);
cmb.setOnHidden(this::handleOnHiding);
cmb.setSkin(cbSkin);
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if(event.getCode() == KeyCode.SPACE){
filter += " ";
event.consume();}
});
}

Related

Tizen native wearable - how to add text label auto line break?

I want to show a full line of long text in a label. But when it is small in character numbers It can show it in full. But when the character number grows it shows some part of the texts. Even if I add size to it. It can show line break with html formats but I will perform character operation with network calls, so instead of checking individual characters or keeping track of numbers it will be better if it can add auto line break at the end of screen and show all the texts on screen.
Here's code for label:
ad->label = elm_label_add(ad->conform);
elm_object_text_set(ad->label, "<align=center>Hello Tizen , line is cut offfffffffffffff.</align>");
//elm_object_text_set(ad->label, "<align=center>Hello Tizen <br>testing br</align>");
evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
//elm_object_content_set(ad->conform, ad->label);
evas_object_move(ad->label, 20, 100);
evas_object_resize(ad->label, 300, 300);
evas_object_show(ad->label);
How to add auto line break?
Try using elm_label_line_wrap_set API.
elm_label_line_wrap_set(ad->label, ELM_WRAP_MIXED);
See the API reference below.
void elm_label_line_wrap_set ( Elm_Label *obj,
Elm_Wrap_Type wrap
)
Control the wrapping behavior of the label.
By default no wrapping is done. Possible values for wrap are: ELM_WRAP_NONE - No wrapping ELM_WRAP_CHAR - wrap between characters ELM_WRAP_WORD - wrap between words ELM_WRAP_MIXED - Word wrap, and if that fails, char wrap
https://docs.tizen.org/iot/api/5.0/tizen-iot-headed/group__Elm__Label.html#ga60a1dad4d49a3aea31ced12e30d0b815

Check if a string contains all other strings

I am trying to code a part of a software where I try to show the results that match search criteria.
I have a textbox where I can type one or more words I want to search and a listview that contains 4 different columns and a dozen rows. The idea is that each listview row contains lots of words and I want to see only the rows that contain all the words I have typed in the textbox. I have finished the code that searches for one term only. The problem I am having is that I don't fully understand how to do the same, but using multiple terms instead of one term only.
In the textbox, I write the words I want to search separated by a space. I have a variable where I keep the whole content of the listview row separated by : (example => col1row1content:col1row2content:col1row3content,etc). Summarizing, I want to check if a string (the full content of a row) contains all other strings (each word I have typped in the textbox).
This is the code I have implemented:
Dim textboxFullContentArray As String() = textboxSearch.Split(New Char() {" "c})
Dim Content As String
Dim containsAll As Boolean = False
Dim wholeRowContent(listviewMain.Items.Count - 1) As String ' each index of the array keeps the entire row content (one array contains all 4 cells of the row)
' wholeRowContent contains in one index the entire content of a row. That means,
' the index contains the 4 cells that represent an entire row.
' The format is like "rowData1:rowData2:rowData3:rowData4" (omitted for simplicity)
For Q As Integer = 0 To listviewMain.Items.Count - 1
For Each Content In textboxFullContentArray
If wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = True
' rest of the code...
ElseIf Not wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = False
Exit For
End If
Next
Next
But of course, this code is showing false positives and I think it's not a good solution. I think it must be much easier and I am overcomplicating the concept.
I am using VB.Net 2013
You can determine whether a String contains all of a list of substrings with a single line of code:
If substrings.All(Function(s) str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) Then
Notice that I have actually implemented a case-insensitive comparison, rather than using ToLower or ToUpper.
It may not seem as neat to call IndexOf rather than Contains but guess what: Contains actually calls IndexOf internally anyway:
public bool Contains(string value)
{
return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}
You can write your own extension methods if you want a case-insensitive Contains method:
<Extension>
Public Function Contains(source As String,
value As String,
comparisonType As StringComparison) As Boolean
Return source.IndexOf(value, comparisonType) >= 0
End Function
Your If/Else looks like it could be simplified. I would set your containsAll value to true outside the nested loops, and only if you encounter a "Content" in "textboxFullContentArray" that is not contained in wholeRowContent(Q) you set containsAll to false, otherwise do nothing.
Also, one way to see what's going on is to print statements with the values that are being compared throughout your function, which you can read through and see what is happening at runtime when the false positives occur.
After some hours looking for a simple and effective solution (and trying different codes), I have finally found this solution that I adapted from: Bad word filter - stackoverflow
For Q As Integer = 0 To listviewMain.Items.Count - 1
If textboxFullContentArray.All(Function(b) wholeRowContent(q).ToLower().Contains(b.ToLower())) Then
' my code
End If
Next

clear text field using DELETE or BACK SPACE key in webdriver

I am trying to clear a text field using this action:
emailField.sendKeys("gmail.com");
emailField.sendKeys(Keys.CONTROL,"a",Keys.DELETE);
In above code, the last line only selects the text, does not delete it, but if I separate the actions it works.
emailField.sendKeys(Keys.CONTROL,"a");
emailField.sendKeys(Keys.DELETE);
From the JavaDoc for WebElement.clear():
If this element is a text entry element, this will clear the value.
Has no effect on other elements. Text entry elements are INPUT and
TEXTAREA elements. Note that the events fired by this event may not be
as you'd expect. In particular, we don't fire any keyboard or mouse
events. If you want to ensure keyboard events are fired, consider
using something like sendKeys(CharSequence) with the backspace key. To
ensure you get a change event, consider following with a call to
sendKeys(CharSequence) with the tab key.
Most likely you simply need to call:
emailField.sendKeys("gmail.com");
emailField.clear();
But if you need the clearing to be done via the keyboard for some reason, use Keys.BACKSPACE.
keys.DELETE can not work to delete the input text,you should use keys.BACKSPACE.
emailField.sendKeys(Keys.BACKSPACE)
From the JavaDoc for Keys.chord
chord(java.lang.CharSequence... value)
Simulate pressing many keys at once in a "chord".
You should be able to use
emailField.sendKeys(Keys.chord(Keys.CONTROL,"a",Keys.DELETE));
Tested in chrome driver
WE.send_keys(' \b')
This will add space then delete it (backspace)
I use in javascript and it's working fine:
await textBox.sendKeys(value);
await textBox.sendKeys(Key.BACK_SPACE);
emailField.sendKeys(Keys.BACKSPACE)
doesn't worked for me .
I used 'Key' instead of 'Keys'
emailField.sendKeys(protractor.Key.BACKSPACE)
emailField.sendKeys(Keys.CONTROL + "a",Keys.DELETE);
In PHP:
if you use php-webdriver (https://github.com/php-webdriver/php-webdriver) you must:
use Facebook\WebDriver\WebDriverKeys AS Keys;
.
.
.
$this->driver->findElement(By::id('demo'))->sendKeys([Keys::BACKSPACE,'Any other text']);
Just adding another working C# example using the Google Chrome webdriver.
SendKeys only takes one parameter so created a string with the Crtl + A. This code sequence will select the current text in the field then delete the text.
Code example:
var crtlA = Keys.Control + "a";
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(crtlA); Wait(5000); // Select current text
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(Keys.Delete); Wait(5000); // Clear current text
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(newItemSku); Wait(5000); // Input SKU name
1. in WebdriverIO, i tried to edit the text by clear text (which contains special charactes like #, +, _) in text field by below following step. Eventhough it was not successful.
example: text=> abc+1234#gmail.com
step1:browser.clearElement(selector);
step2:browser.execute(function () {
document.querySelector(>>>Cssselector<<<).value="";
});
step3: browser.doubleClick(selector);
browser.keys("Delete");
step4: browser.click(selector);
browser.keys(['Meta',a]);
browser.keys('Meta');
browser.keys('Delete');
Note: below step is resolved this issue.
var count= browser.getAttribute(selector, value).length;
for (var i=0;i<count;i++)
{
if (browser.getAttribute(selector, value)=='')
break;
}
else
{
browser.doubleClick(selector);
browser.keys("Delete");
}
browser.pause(200);
// it will clear your text field easily.
Note:
You can add the new text now.

Overriding Ext.util.Format.thousandSeparator except when formatting money

I am trying to override Ext.util.Format.decimalSeparator and thousandSeparator. So, in my app, when I chnage the language to Spanish and I try using this function, Ext.util.Format.number(1234,'$0,000'), still it converts the number to 1.234 instead of 1,234.
I want that, irrespective of what language I choose, it should always format the money to $0,000 format and not using my selected locale, e.g., never $0.000. I observed if I change the thousandSeparator of Ext.util.Format object, it works fine. So, I added the following code in Ext.Loader.loadScript callback function in launch function in Application.js,
var utilFormatObj={};
utilFormatObj.thousandSeparator = ",";
utilFormatObj.decimalSeparator = ".";
Ext.override(Ext.util.Format, utilFormatObj);
BUt, it seems to work only in this place, once it loads the app on webpage, it again gets back to thousandSeparator=".". I can see that ext-lang-es.js file has the function which sets these properties. Can anyone suggest how can I catch whether the app is completely loaded on webapge and then use the above code there. Thank you.
When you call Ext.util.Format.number() you're not specifying what to use as decimal or thousand separator, you're only specifying precision, whether to show thousands separator, and whether to pad precision with zeroes.
The documentation for Ext.util.Format.number states:
The format string must specify separator characters according to US/UK conventions ("," as the thousand separator, and "." as the decimal separator)
Therefore if you want to display numbers in different locales, you have to run the code that changes the default separators before calling Ext.util.Format.number or Ext.util.Format.currency.
var value = 202020.20, format = "0,000.0000";
// Print in Spanish
Ext.util.Format.thousandSeparator = ".";
Ext.util.Format.decimalSeparator = ",";
alert(Ext.util.Format.number(value, format));
// Print in Swedish French
Ext.util.Format.thousandSeparator = "'";
Ext.util.Format.decimalSeparator = ",";
alert(Ext.util.Format.number(value, format));
// Print in English
Ext.util.Format.thousandSeparator = ",";
Ext.util.Format.decimalSeparator = ".";
alert(Ext.util.Format.number(value, format));
Here's a hack you can use if you really want to specify that currency should always use a period as the thousand separator but still have Ext.util.Format.number use the selected locale's separators.
function formatMoney(amount, sign, decimals, end) {
// Save the thousand separator
var thousandSep = Ext.util.Format.thousandSeparator;
Ext.util.Format.thousandSeparator = '.';
var formatted = Ext.util.Format.currency(amount, sign, decimals, end);
// restore the thousand separator
Ext.util.Format.thousandSeparator = thousandSep;
return formatted;
}
Example for the above code snippets: https://fiddle.sencha.com/#fiddle/9vm
I am guessing that you are not using the loader after you build your application for deployment. Typically the dynamic loader is only used for development (so you can see each script individually) and you use a faster method in prod.
You could load your Ext overrides on the callback for Ext.define:
Ext.define( className, data, [createdFn] )
where createdFn is a function that contains your Ext overrides. This approach may lend itself to race conditions if you invoke that Format object before the override is applied. To be confident, you could add another JS file with your overrides (after Ext is loaded, before your app code) and make sure that is included when you load your app.

Text length in a WinForms ToolTip

how to set the max length of a text in a WinForms ToolTip?
I have a String with about 300 chars, but my ToolTip displays only 264 of them...
Greets,
Jürgen
You could add NewLine a few times in your ToolTip string like this so that it does not go all the way across the screen.
The string in this code is 434 characters long.
:-)
Just run this code to try it please:>>
Imports System.Environment
Public Class Form1
Friend WithEvents myToolTip As New ToolTip
Private Sub Form1_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
Dim someText As String = _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D" & NewLine & _
"Hello World!! Hi everyone!! Good day, good evening or goodnight, wherever you are in the world!! :-) :-D"
Me.Text = someText.Length.ToString
myToolTip.Show(someText, Me, 5000)
End Sub
End Class
I had this same issue (it happened to be with a DataGridView cell) and the default ToolTip text (i.e. the text content of the cell) was indeed being truncated.
For me, it started working correctly when I set the ToolTip text explicitly (all of the answers I see do this). What I think is subtle is that the default ToolTip text uses the same cell content, only the default handler does truncate it as noted in the original question. By overriding the event and setting the ToolTip text (even though it's exactly the same cell text!) now the default length restriction seems to go away.
protected override void OnCellToolTipTextNeeded(DataGridViewCellToolTipTextNeededEventArgs e)
{
if((e.RowIndex >= 0) && (e.ColumnIndex >= 0))
{
// By setting this explicitly we can make the ToolTip length
// longer even though the content is exactly the same.
e.ToolTipText = this[e.ColumnIndex, e.RowIndex].Value.ToString();
}
base.OnCellToolTipTextNeeded(e);
}
Other controls will fire different events of course, but it should hold that if you put the text onto the tool tip yourself then you can circumvent the truncation that occurs with any default ToolTip.
I know this is an old question and I'm not sure if the following functionality existed at that time, but for those searching for this, I noticed that if the Tooltip text is very long, it may not get displayed at all, and after some trying, found that this helps:
// 999 = just an arbitrary number to test for possible very long text, may have to fiddle with that (maybe screen width) !
// 456 = also arbitrary, change to your liking !
// tooltip.GetToolTip((sender as ToolTip).Tag as Control) is because I have multiple controls using the same Tooltip, so I set the Tooltip.Tag to the control that will call Tooltip.Show(...). If you have 1 tooltip per control than just replace it with the control in question.
tooltip.Popup += (sender, e) =>
{
if (e.ToolTipSize.Width > 999)
{
Size s = TextRenderer.MeasureText(tooltip.GetToolTip((sender as ToolTip).Tag as Control), SystemFonts.SmallCaptionFont);
e.ToolTipSize = new Size(456, s.Height * 3); // * 3 turned out to work for SystemFonts.SmallCaptionFont
}
};

Resources