Can I remove the 'carrot' (upside down triangle) created by the ComboBoxListViewSkin? - combobox

When implementing the java ComboBoxListViewSkin class to manage the popup listener of my ComboBox, this adds a 'carrot' to the upper left corner of the ComboBox (see below). If I remove this class implementation it goes away. I'm using the CombBoxListViewSkin's class popup listener to prevent the [SPACE] from selecting and closing the ComboBox when pressed which allows the [SPACE] character to be typed as part of an AutoComplete class.
This is all the code involved in managing and allowing the [SPACE] to work as part of AutoComplete class -and works great. I've tried searching the ComboBoxListViewSkin class for methods or properties that may prevent this, but nothing addresses this. I thought maybe the COMBO_BOX_STYLE_CLASS might offer something but everything really only manages the displaying, adding or removing items. Since the code below is the minimal necessary to recreate the issue, this will not perform the auto-complete function, but it demonstrates that removing and re-implementing the ComboBoxListViewSkin class causes the issue.... or appears to.
// Main method calling
public class Main extends Application{
public static void main(String[] args) {
launch();
}
public void start(Stage stage) throws Exception {
ComboBox cmb = new ComboBox();
cmb.getItems().setAll("One", "One Two", "One Two Three");
new ComboBoxAutoComplete(cmb);
Scene scene = new Scene(new StackPane(cmb));
stage.setScene(scene);
stage.setTitle("Test GUI");
stage.setWidth(300);
stage.setHeight(300);
stage.show();
}
}
// ComboBoxAutoComplete class with ComboBoxListViewSkin initialization
// Minimal of ComboBoxAutoComplete class constructor
import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.util.stream.Stream;
#SuppressWarnings("ALL")
public class ComboBoxAutoComplete<T> {
private ComboBox<T> cmb;
private String filter = "";
private ObservableList<T> originalItems;
private ComboBoxListViewSkin cbSkin;
public ComboBoxAutoComplete(final ComboBox<T> cmb) {
this.cmb = cmb;
originalItems = FXCollections.observableArrayList(cmb.getItems());
cbSkin = new ComboBoxListViewSkin(cmb);
// Aside from the variable declaration and initialization... this
// is the only ComboBoxListViewSkin code to handle the [SPACE]
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if (event.getCode() == KeyCode.SPACE) {
filter += " ";
event.consume();
}
});
}
}
My expectation is for the ComboBox to look like all the other ComboBoxes in the application GUI. Although it is a minor issue, to the user I believe it may look like an issue with the application is going on.

Resolved: As Fabian suggested above, I added a cmb.setSkin(cbSkin) after the initialization and before the event filtering and it worked. Thought I would post so others would see it was resolved.
cbSkin = new ComboBoxListViewSkin(cmb);
cmb.setSkin(cbSkin); // <------------- ADDED
cbSkin.getPopupContent().addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
if (event.getCode() == KeyCode.SPACE) {
filter += " ";
event.consume();
}
});

Related

Vaadin - How to convert a Grid column which has boolean value to Checkbox

I am using Vaadin 7.6.4 for my UI work. This has the following:-
I have a window which contains a grid with data in it. This window is actually a kind of a pop up[ which shows up when my main screen gets a click on the settings icon( not shown here). This is working fine( getting the UI screen to open the Vaadin window when the settings icon the main screen is clicked).
The problem is in showing the data as mentioned below.
This grid will have 4 columns for which the data comes from a bean container.
The first column is a boolean field with true/false getting displayed based on the data from the bean container.
I need to convert this boolean field column into a checkbox with true showing the field as a checkbox with a value selected. If the value is false, then show a checkbox which is not selected.
I am trying to do that as shown in the code below but I keep getting this checkbox name printed. I dont see the checkbox but the word "checkbox" printed in there?
This checkbox should be editable. The idea is that the user should be able to select some checkboxes and the ones selected should be shown in a panel ( not shown here). Thus, the checkbox has to be editable.
How do I fix this? The code for the window is shown below
package com.platform28.mybatis;
import java.util.List;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.GeneratedPropertyContainer;
import com.vaadin.data.util.PropertyValueGenerator;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
#SuppressWarnings("serial")
public class ConfigPopUp extends Window {
VaadinUtils vaadinUtils = null;
public ConfigPopUp(List<TableColumnData> tblDataLst) {
vaadinUtils = new VaadinUtils();
// Some basic content for the window
VerticalLayout configLayout = new VerticalLayout();
configLayout.addComponent(new Label("Settings"));
configLayout.setMargin(true);
//configLayout.setWidth(null);;
setContent(configLayout);
//adding grid.
List<SettingsColumnData> settingsList = vaadinUtils.processSettingsList(tblDataLst);
final BeanItemContainer<SettingsColumnData> gridDataSource = new BeanItemContainer<SettingsColumnData>(SettingsColumnData.class, settingsList);
//change boolean value to checkbox.
GeneratedPropertyContainer gp = new GeneratedPropertyContainer(gridDataSource);
gp.addGeneratedProperty("columnDisplayed", new PropertyValueGenerator<CheckBox>() {
#Override
public CheckBox getValue(Item item, Object itemId, Object propertyId) {
boolean currentCheckBoxValue = (boolean) item.getItemProperty("columnDisplayed").getValue();
CheckBox chkBox = new CheckBox();
chkBox.setValue(currentCheckBoxValue);
return chkBox;
}
#Override
public Class<CheckBox> getType() {
return CheckBox.class;
}
});
Grid settingsGrid = new Grid(gp);
settingsGrid.setWidth("100%");
settingsGrid.setSizeFull();
settingsGrid.setColumnOrder("columnDisplayed", "columnName","columnShortName","columnDescription");
configLayout.addComponent(settingsGrid);
//configLayout.setExpandRatio(settingsGrid, 1);
// Disable the close button
setClosable(false);
HorizontalLayout hLayout = new HorizontalLayout();
hLayout.setSpacing(true);
hLayout.setMargin(true);
// Trivial logic for closing the sub-window
Button ok = new Button("Ok");
ok.addClickListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
close(); // Close the sub-window
}
});
hLayout.addComponent(ok);
// Trivial logic for closing the sub-window
Button cancelBtn = new Button("Cancel");
cancelBtn.addClickListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
close(); // Close the sub-window
}
});
hLayout.addComponent(cancelBtn);
configLayout.addComponent(hLayout);
// set pop up to center.
center();
// should be resizable
setResizable(true);
// should not be draggable
setDraggable(false);
//set it as modal window
setModal(true);
setWidth("50%");
setHeight("75%");
}
}
Ok, we used the SelectionMode.MULTI to show the selection of rows in there.
https://cdn.vaadin.com/vaadin-core-elements/latest/vaadin-grid/demo/selection.html
Still, I would love to learn more as to how we get the change done as shown in the question above.
Still looking for an answer to that.
Use a Renderer and a Converter, you don't need to use SelectionMode.MULTI.
An example of this is posted here.

How to customize YUI calendar themes in Java Wicket

Is there a way to customize YUI calendar Design, in Wicket7?
As far as i can see it comes with one css set and it really is not a burner.
The only way i could think about is to override the used css but i wonder if there are some more elegant solutions to, like themes.
The skin is hardcoded in class DatePicker, if you want to change it, there is some workaround in changing classes to get it working.
First think first, you should create your own Behavior derived from DatePicker, see the source code https://github.com/apache/wicket/blob/build/wicket-7.1.0/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/DatePicker.java
Replacing afterRender(Component) is enough, but you should copy-paste the code from the Wicket class and just replace the skin.
IMPORTNANT: DO NOT CALL super.afterRender(component); because it renders
the HTML you want to replace!
public class SkinnedDatePicker extends DatePicker
{
/**
* {#inheritDoc}
*/
#Override
public void afterRender(final Component component)
{
// NEVER CALL THIS: super.afterRender(component);
// Append the span and img icon right after the rendering of the
// component. Not as pretty as working with a panel etc, but works
// for behaviors and is more efficient
Response response = component.getResponse();
response.write("\n<span class=\"yui-skin-MYSKIN\"> <span style=\"");
if (renderOnLoad())
{
response.write("display:block;");
}
else
{
response.write("display:none;");
response.write("position:absolute;");
}
response.write("z-index: 99999;\" id=\"");
response.write(getEscapedComponentMarkupId());
response.write("Dp\"></span><img style=\"");
response.write(getIconStyle());
response.write("\" id=\"");
response.write(getIconId());
response.write("\" src=\"");
CharSequence iconUrl = getIconUrl();
response.write(Strings.escapeMarkup(iconUrl != null ? iconUrl.toString() : ""));
response.write("\" alt=\"");
CharSequence alt = getIconAltText();
response.write(Strings.escapeMarkup((alt != null) ? alt.toString() : ""));
response.write("\" title=\"");
CharSequence title = getIconTitle();
response.write(Strings.escapeMarkup((title != null) ? title.toString() : ""));
response.write("\"/>");
if (renderOnLoad())
{
response.write("<br style=\"clear:left;\"/>");
}
response.write("</span>");
}
}
The second place is, when you want to use it with DateTimeField you have to override the factory method newDatePicker(), copy-paste Wicket code is in place again, see https://github.com/apache/wicket/blob/build/wicket-7.1.0/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/DateTimeField.java
public class SkinnedDateTimeField extends DateTimeField
{
/**
* The DatePicker that gets added to the DateTimeField component. Users may override this method
* with a DatePicker of their choice.
*
* #return a new {#link DatePicker} instance
*/
#Override
protected DatePicker newDatePicker()
{
return new SkinnedDatePicker()
{
private static final long serialVersionUID = 1L;
#Override
protected void configure(final Map<String, Object> widgetProperties,
final IHeaderResponse response, final Map<String, Object> initVariables)
{
super.configure(widgetProperties, response, initVariables);
DateTimeField.this.configure(widgetProperties);
}
};
}
}
Than use your SkinnedDateTimeField component instead of DateTimeField

JavaFX: Capture "Enter" key pressed

I need to keep an indeterminably sized list of strings. I figured the best way to do this would be through a combo box which would take user input, and in turn add that user input upon an "Enter" keystroke detected to the ComboBox list of items, and also allow the user to remove those items by a "Delete" keystroke.
I had hoped this would be a very simple task handled like so:
this.cbx.setOnKeyTyped((KeyEvent E) -> {
switch(E.getCode()){
case ENTER:
this.cbx.getItems().add(this.cbx.valueProperty().get());
this.cbx.valueProperty().set("");
E.consume();
break;
case DELETE:
if (this.cbx.getItems().contains(
this.cbx.valueProperty().get()
)) this.cbx.getItems().remove(this.cbx.valueProperty().get());
this.cbx.valueProperty().set("");
E.consume();
break;
}
});
Unfortunately, Enter does not trigger the event. So clearly I am mistaken.
I also tried with onKeyPressed, and that did not work either.
What need I do to capture when "Enter" and "Delete" are pressed (It picks up "Shift" just fine which is maddening).
EDIT 1:
Have also tried with
If(E.getCode().Equals(KeyCode.ENTER)){
...
} else if (E.getCode().equals(KeyCode.DELETE)){
...
}
No Love.
Edit 2:
Based on James_D's answer below which put me on the right course, in order to accomplish what I was seeking to do, I employed the following method:
ComboBox<String> cb = new ComboBox<>();
cb.setEditable(true);
cb.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent E) -> {
switch(E.getCode()){
case ENTER:{
if (cb.getItems().contains(cb.getEditor().getText()))
E.consume();
else{
cb.getItems().add(cb.getEditor().getText());
cb.getEditor().clear();
E.consume();
}
break;
}
case DELETE:{
if (E.isControlDown() && cb.getItems().contains(cb.getEditor().getText()))
cb.getItems().remove(cb.getEditor().getText());
else if (E.isAltDown()) cb.getItems().clear();
if (E.isControlDown() || E.isAltDown()){
cb.getEditor().clear();
E.consume();
}
break;
}
}
});
Are you looking to have an editable combo box, that adds items to its popup list when the user types in items that are not there?
If so, try:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class UpdatingComboBox extends Application {
#Override
public void start(Stage primaryStage) {
ComboBox<String> combo = new ComboBox<>();
combo.setEditable(true);
combo.valueProperty().addListener((obs, oldValue, newValue) -> {
if (newValue != null && ! combo.getItems().contains(newValue)) {
combo.getItems().add(newValue);
}
});
HBox root = new HBox(combo);
root.setAlignment(Pos.TOP_CENTER);
primaryStage.setScene(new Scene(root, 350, 150));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
For deleting, the first thing I would ask is if you really want the functionality as you've described it. Users would typically expect pressing delete in an editable combo box to delete the next character, not remove an item entirely from the list. If you do want to do this, you have to get your hands a little more dirty and use a key listener. For some reason, adding the key listener to the combo box directly seems to have somewhat unpredictable results; it works however if you add it to the text field underlying the editable combo box:
combo.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.DELETE) {
combo.getItems().remove(combo.getValue());
event.consume();
}
});

Localizing buttons of a FacesContext.addMessage in adf

Hi i want to localize the buttons eg: OK, Cancel in ADF,
I am using the following code
FacesContext fctx = FacesContext.getCurrentInstance();
fctx.addMessage(VALIDATIONERROR,new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
fctx.renderResponse();
I get the pop and the error message is localized, My question is how to localize the buttons which are on the pop up, ex: OK,CANCEL
I suppose you are talking about a af:dialog component. In that case i can think about two ways of doing so:
The af:dialog component has two properties: cancelTextAndAccessKey and affermativeTextAndAccessKey. They can take an EL which can take the key of a specific record into a .properties file (which is loaded as a resource bundle into the project. An example: cancelTextAndAccessKey="#{lang['popUp.dialog.button.cancel']}" (where lang is the name of the declared bundle in my case)
You can override the default component label, by creating a ListResourceBundle (which should be also loaded as a resource bundle into faces-config.xml, Application tab).
The code should be something like:
public class CTSResourceBundle extends ListResourceBundle {
public CTSResourceBundle() {
super();
}
#Override
protected Object[][] getContents() {
return new Object[][] {
{ "af_dialog.LABEL_YES", "Po" },
{ "af_dialog.LABEL_NO", "Jo" },
{ "af_dialog.LABEL_OK", "Ok" },
{ "af_dialog.LABEL_CANCEL", "Anullo" }
};
}
}

Create UI components on page load

I am currently working on oracle adf task flows and regions and I want to create and update some UI components on page load and for this I am using method call activity as default.The problem is that I am getting null values following is my code in the bean that executes on the method call.
package view;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import oracle.adf.view.rich.component.rich.output.RichOutputText;
public class testBean {
public testBean() {
}
public String testMethod() {
// Add event code here...
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
RichOutputText text = ( RichOutputText )root.findComponent( "r1:ot1" );
text.setValue( "Adding text on run time" );
return "product";
}
}
The set value method returning me null may be it is because the fragment product.jsff which is the view activity is not initiated and the output text with ot1 returning null.
The better approach to achieve the setting of value is to have a property in your bean say: textValue and then bind the value attribute of your ot1 with the property of the bean.
class TestBean{
private String textValue;
public String testMethod() {
textValue = "Adding text on run time";
}
public String getTextValue(){
return textValue;
}
}
Your JSPX would be:
<af:outputText id="ot1" value=#{beanName.textValue}" />

Resources