I'm trying to get the clicked cell in a headertable to do sorting, but I want to handle this in another class, the class that implements the table. If I write out the cell in the headertable class is prints the right cell id, but when adding the clickhandler to the implementing class the id is always 0.
Example:
public class CustomerDetailsHoldingsTable extends SimpleTable<Holding>
implements ClickHandler {
TableDataSource<Holding> ds;
Public CustomerDetailsHoldingsTable () {
this.headerTable = new HeaderTable();
this.headerTable.addClickHandler(this);
}
#Override
public void onClick(ClickEvent event) {
GWT.log("Clicked cell with id" +
getCellForEvent(event).getCellIndex());
}
public class HeaderTable extends Grid {
...
...
}
The GWT.log line always prints 0 regardless what cell is clicked in the headertable. Why is that?
You'll need to invoke getCellForEvent on your grid object, like so:
#Override
public void onClick(ClickEvent event) {
GWT.log("Clicked cell with id" +
this.headerTable.getCellForEvent(event).getCellIndex());
}
From the docs:
Given a click event, return the Cell
that was clicked, or null if the event
did not hit this table. The cell can
also be null if the click event does
not occur on a specific cell.
Related
I am trying to bind a string to a Button in pure C# (no XAML), but apparently I am doing it wrong, as the result of my code is that the button disappears.
I am defining my property as follows:
public string selectionString { get; set; }
And this is how I am binding the string to the button:
selectionString = "Hello";
selectionButton = new Button
{
TextColor = Color.Black
};
selectionButton.SetBinding(Button.TextProperty, "selectionString");
Children.Add(selectionButton);
I have tried to use BindingMode.TwoWay, but it doesn't work.
Of course, setting the text and removing the binding makes the button appear and work.
My need is just this: the button text should be the selectionString, and if this changes by an external event, so the button's text should change accordingly.
Am I missing something in how the binding works?
Bindings work against public properties on the view's binding context, and respond to INotifyPropertyChanged events firing. Hopefully this demonstrates for you.
public class MyViewModel : INotifyPropertyChanged
{
// Fire RaisePropertyChanged in the setter, I use Fody to weave this in
public string SelectionString {get;set;}
}
public class MyView : Page
{
protected override void OnBindingContextChanged()
{
if (BindingContext is MyViewModel)
{
this.SetBinding(Button.TextProperty, "SelectionString");
}
}
}
I am facing an issue with the Vaadin spring annotation #UIScope, defined as follows:
#SpringComponent
#SpringView(name = AdminView.VIEW_NAME)
#UIScope
public class AdminView extends NavigatingView {
...
}
The view is created every time the navigation is opening the view. I would expect that it is created only once, on first time access.
However, if I replace #UIScope with #Scope(UIScopeImpl.VAADIN_UI_SCOPE_NAME) then it works as expected. Did I miss something?
It's related to the order of the #SpringView and #UIScope annotations, as the tutorial and the older wiki page briefly suggest:
// Pay attention to the order of annotations
It's probably related to how and when the annotations are processed. I did not dig that deep into the Vaadin code, but as per the the #SpringView javadoc it puts the view into a view-scope by default. Furthermore, I don't think you require the #SpringComponent annotation because you're already using #SpringView to register it a spring component.
Annotation to be placed on View-classes that should be handled by the SpringViewProvider.
This annotation is also a stereotype annotation, so Spring will automatically detect the annotated classes. By default, this annotation also puts the view into the view scope. You can override this by using another scope annotation, such as the UI scope, on your view class. However, the singleton scope will not work!
In the sample below, you'll find 2 views, the first one with the annotations in the correct order, and the second one with them swapped:
#SpringUI
#SpringViewDisplay
public class MyVaadinUI extends UI implements ViewDisplay {
/* UI */
private Panel springViewDisplay;
#Override
protected void init(VaadinRequest request) {
VerticalLayout mainLayout = new VerticalLayout();
HorizontalLayout buttonLayout = new HorizontalLayout();
springViewDisplay = new Panel();
buttonLayout.addComponent(new Button("1", event -> getNavigator().navigateTo(FirstView.VIEW_NAME)));
buttonLayout.addComponent(new Button("2", event -> getNavigator().navigateTo(SecondView.VIEW_NAME)));
mainLayout.addComponents(buttonLayout, springViewDisplay);
setContent(mainLayout);
}
#Override
public void showView(View view) {
springViewDisplay.setContent((Component) view);
}
/* VIEWS */
#UIScope
#SpringView(name = FirstView.VIEW_NAME)
public static class FirstView extends HorizontalLayout implements View {
public static final String VIEW_NAME = "";
#PostConstruct
private void init() {
System.out.println("Created first view");
addComponent(new Label("First view - " + LocalDateTime.now()));
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
// no-op
}
}
#SpringView(name = SecondView.VIEW_NAME)
#UIScope
public static class SecondView extends HorizontalLayout implements View {
public static final String VIEW_NAME = "secondView";
#PostConstruct
private void init() {
System.out.println("Created second view");
addComponent(new Label("Second view - " + LocalDateTime.now()));
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
// no-op
}
}
}
As you'll notice in the animation below, when navigating to the second view a new instance is always created, while navigating to the first one will reuse the initial instance:
I have inherited my view model class from INavigateAware interface as below,
public class ViewModel : INavigationAware
{
public ViewModel()
{
}
public void OnNavigatedFrom(NavigationParameters parameters)
{
}
public void OnNavigatedTo(NavigationParameters parameters)
{
// some codes
}
}
And called that view model in the associated view(the page I have been navigated to)
public partial class Page1 : ContentPage
{
ViewModel viewModel;
public Page1()
{
InitializeComponent();
viewModel = new ViewModel();
this.Content = myview; //myview is my control like grid
}
}
Now my problem is when I navigate to this page(Page1), OnNavigateTo() method in ViewModel is not triggered. Please someone helps me how to make trigger OnNavigateTo() method.
Thanks in advance.
First thing first, check if you have AutowireViewModel parameter in your page class set to True.
Second, you should not assign view model yourself, prism will do that for you, when you call PushViewModel
Third there is well known limitation in prism:
https://github.com/PrismLibrary/Prism/issues/563
There is also workaround suggested:
Create interface:
public interface IPageNavigationAware
{
void OnAppearing();
void OnDisappearing();
}
Derive your ViewModel class from this interface.
In the Views code behind:
protected override void OnAppearing()
{
(BindingContext as IPageNavigationAware)?.OnAppearing();
}
protected override void OnDisappearing()
{
(BindingContext as IPageNavigationAware)?.OnDisappearing();
}
The problem with that is that OnAppearing/OnDissapparing are not reliable navigation methods and do not accept parameters, but rather page lifecycle methods. They do not indicate when a page has been navigated to or from. You can have instances where a parent page can be appearing at the same time as multiple child pages are appearing. This will be addressed when Xamarin provides a proper navigation API.
Textbox should accept only numbers, I would like to use anyother Handlers other than ChangedHandler/ Changehandler/ KeyPressHandler
My Validation class,
public class UnderLyingIDChangeHandler implements ChangedHandler {
private final CreditRiskView creditRiskView;
public UnderLyingIDChangeHandler(CreditRiskView creditRiskView) {
this.creditRiskView = creditRiskView;
}
#Override
public void onChanged(ChangedEvent event) {
String value= (String) event.getItem().getValue();
if(!value.matches("[0-9]*")){
creditRiskView.invalidUnderlyingID();
}
}
This is the main class where I need to show the validation
public class CreditRiskView{
private TextItem underlyingIDField;
public void addunderlyingIDInputChangeHadler(ChangedHandler changedHandler) {
//logic is that this method will invoked in the UnderLyingIDChangeHandler class
underlyingIDField.addChangedHandler(changedHandler);
}
public void invalidUnderlyingID(){
// I don't know how to set an error message as underlyingIDField.clearValue()
method is not doing well.
}
}
If the textbox is a TextItem in a DynamicForm it works like this:
IsIntegerValidator isIntegerValidator = new IsIntegerValidator();
isIntegerValidator.setErrorMessage("error message");
textItem.setValidators(isIntegerValidator);
And to show the errors like that when you call the form.validate() you need to set the setShowInlineErrors(true) in the form.
What about limiting characters that can be entered by the user?
Please see this sample:
http://www.smartclient.com/smartgwt/showcase/#form_keypress_filter
In JavaFX I want to check if a checkbox is selected and I want to do this using the lookup(#id) method. However this method returns a Node, which doesn't have the isSelected() method.
The code below shows the GUIController and a class Visualize it calls, where the status of the checkbox is read. I added a solution (reading the checkbox properties in GUIController and passing them to Visualize), but this is not how I want to proceed. I whish that the checkbox status is read in Visualize, because there will be many other GUI elements that I need to read so it is more compact to pass on a single object to Visualize instead of a list precomputed in GUIController.
Thank you for suggestions!
GUI Controller:
public class GUIController implements Initializable {
#FXML private AnchorPane RootPane;
#FXML private CheckBox TextCheckBox;
#Override
public void initialize(URL url, ResourceBundle rb) {
Boolean TextCheckBoxSelected = TextCheckBox.isSelected();
Visualize visualizeInstance = new Visualize();
root3D = visualizeInstance.draw(RootPane, TextCheckBoxSelected);
/* ... */
Class called by GUIController:
public class Visualize {
public Visualize() {
//
}
public Group draw(AnchorPane RootPane, Boolean TextCheckBoxSelected) {
System.out.println(RootPane.lookup("#TextCheckBox"));
System.out.println(TextCheckBoxSelected);
/* ... */
Output:
CheckBox[id=TextCheckBox, styleClass=check-box]'Text'
true
If you really want to do it this way, just downcast the result of the lookup:
public class Visualize {
// ...
public Group draw(AnchorPane rootPane) {
CheckBox textCheckBox = (CheckBox) rootPane.lookup("#TextCheckBox");
boolean selected = textCheckBox.isSelected();
// ...
}
}
If you are doing this because you need your Visualize object to respond to changes in the CheckBox's selected state, then consider passing a BooleanProperty instead, which you can observe if you need:
public class Visualize {
private BooleanProperty selectedProperty ;
public Visualize(BooleanProperty selectedProperty) {
this.selectedProperty = selectedProperty ;
// ...
}
// ...
public Group draw() {
boolean selected = selectedProperty.get();
// ...
}
}
and
Visualize visualizeInstance = new Visualize(textCheckBox.selectedProperty());
root3D = visualizeInstance.draw();