JavaFX 2.x TableView localization - localization

When TableView control contains no content, it displays "No content in table". How to change/localize that string?

Here you go
tableView.setPlaceholder(new Text("Your localized text here"));

no things display in table view if no data
.table-row-cell:empty {
-fx-background-color: lightyellow;
}
.table-row-cell:empty .table-cell {
-fx-border-width: 0px;
}

Following JavaFX recommendation it'd be better to implement like this
Model.java
class Model {
private final ObjectProperty<Text> placeholderProperty;
Model(ResourceBundle resourceBundle) {
placeholderProperty = new SimpleObjectProperty<>(new Text(resourceBundle.getString("placeholderTextFromLocalizationProperties")));
}
...
ObjectProperty<Text> placeholderProperty() {
return placeholderProperty;
}
}
Controller.java
class Controller implements Initializable {
private Model model;
#FXML
private TableView tableView;
...
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
model = new Model(resourceBundle);
tableView.setPlaceholder(model.placeholderProperty().get());
}
...
}
When you are about to change localization everything you need is to edit your property file.

Related

Avoid refreshing of content in SplitLayout

I have a splitlayout in my vaadin application in which in the first column I should show different pages added through the addToPrimary method, while in the second column I should have a page which contains an IFrame with a videoconference. Now the problem is that when I change route in the first column, even the second is updated and this refreshes the IFrame. The implementation of the showRouterLayoyutContent is the following:
#Override
public void showRouterLayoutContent(HasElement content) {
if (this.accessControl.isAccessGranted(UI.getCurrent(), ((ContentView) content).getName()) && ((ContentView) content).getName().equals("contattaView") ) {
setLayoutCall((com.vaadin.flow.component.Component) content);
}
else if (this.accessControl.isAccessGranted(UI.getCurrent(), ((ContentView) content).getName())) {
setLayoutContent((com.vaadin.flow.component.Component) content);
}
}
And the two methods setLayoutCall and setLayoutContent are the following:
private void setLayoutContent(com.vaadin.flow.component.Component content) {
split.addToPrimary(content);
}
private void setLayoutCall(com.vaadin.flow.component.Component content) {
split.addToSecondary(content);
split.setThemeName("visible-split");
}
How can I avoid to refresh the entire content when I update the first column of the split layout through navigation?
UPDATE: I'm showing also a very simple code on which I'm testing. The following class is the main layout:
private SplitLayout split = new SplitLayout();
private HorizontalLayout hl = new HorizontalLayout();
private Div firstDiv = new Div();
private Div secondDiv = new Div();
public MainView() {
Button button = new Button("Click me",
event -> Notification.show("Clicked!"));
final VerticalLayout menuBar = new VerticalLayout();
menuBar.add(new RouterLink("first view", FirstView.class));
menuBar.add(new RouterLink("second view", SecondView.class));
menuBar.setAlignItems(Alignment.CENTER);
add(menuBar);
//split.addToPrimary(firstDiv);
//split.addToSecondary(secondDiv);
//firstDiv.setId("first");
//secondDiv.setId("second");
//hl.add(firstDiv,secondDiv);
add(split);
//add(hl);
}
#Override
public void showRouterLayoutContent(HasElement element) {
if(element!=null && element.getClass().getName().contains("FirstView")) {
split.addToPrimary((Component) element);
//firstDiv.removeAll();
//firstDiv.add((Component) element);
//firstDiv.removeAll();
//firstDiv.getElement().appendChild(new Element[]{element.getElement()});
}
else if(element!=null && element.getClass().getName().contains("SecondView") ) {
secondDiv.removeAll();
secondDiv.add((Component) element);
split.addToSecondary((Component) element);
//split.addToSecondary(element.getElement().getComponent().get());
}
}
While these are the two views added to the split:
#Route(value="v1",layout=MainView.class)
public class FirstView extends VerticalLayout implements RouterLayout {
public FirstView() {
add(new Label("First View"));
}
}
#Route(value = "v2",layout=MainView.class)
public class SecondView extends VerticalLayout implements RouterLayout {
public SecondView() {
IFrame frame = new IFrame();
frame.setSrc("https://www.youtube.com/watch?v=LoigVtPCYPk&list=RDLoigVtPCYPk&start_radio=1");
add(frame);
}
}
Your comment does indeed seem to be the issue.
I recommend creating a Div wrapper for the primary content, and instead changing the content of that.
private final Div wrapper;
public MyLayout() {
wrapper = new Div();
wrapper.setSizeFull();
split.addToPrimary(wrapper);
}
private void setLayoutContent(com.vaadin.flow.component.Component content) {
wrapper.removeAll();
wrapper.add(content);
}
You might also want to do the same for the secondary. In addition, to prevent any components from being automatically removed when navigating, you can override removeRouterLayoutContent as well (available in Vaadin 14)
#Override
public void removeRouterLayoutContent(HasElement oldContent) {
// Do nothing, we remove manually in showRouterLayoutContent
}
Edit
If you can't override removeRouterLayoutContent, you can try creating your own instance of the HasElement to add. This is a bit of a hack, but might be the simplest solution.
public void showRouterLayoutContent(HasElement content) {
if (content.getClass().getSimpleName().contains("TestView")) {
// Creating a new instance should stop it from being auto removed
content = new TestView();
firstDiv.add((Component) content);
}
...
}

Calling variable MvxCommand(s) from custom CollectionViewCell

I've been banging my head against this for two days now working with mvvmcross, and having never worked with iOS before I think there's just something I don't understand.
I created my main menu with a UICollectionView in a two-column 3-row grid, each item representing a different location the user can go to on tap. I can override "ItemSelected" from the UICollectionViewSource, but I can't access the actual ViewModel without passing a reference of it into the source on creation....which doesnt feel like the right way to do it to me.
[MvxRootPresentation(WrapInNavigationController = true)]
public partial class MainPageView : MvxViewController
{
private MenuCollectionSource _menuCollectionSource;
List<MainMenuItem> menuItems;
public MainPageViewModel VM
{
get { return DataContext as MainPageViewModel; }
}
private void SetupMenuCollectionView()
{
......
collectionView.RegisterNibForCell(MainMenuCollectionViewCell.Nib, MainMenuCollectionViewCell.Key);
MainMenuItem.Init(menuItems);
_menuCollectionSource = new MenuCollectionSource(collectionView, MainMenuCollectionViewCell.Key, menuItems);
_menuCollectionSource.VM = VM; <----doesnt seem right.
collectionView.Source = _menuCollectionSource;
public class MenuCollectionSource : MvxCollectionViewSource
{
private UICollectionView _collectionView;
public List<MainMenuItem> Items { get; set; }
private MainPageViewModel _vm;
public MainPageViewModel VM
{
get { return _vm; }
set { _vm = value; }
}
}
With this method I can override ItemSelected in the ViewSource, and the do something like
( Cell is touched ->
Depending on cell enum/cell# - >
vm.NavigateToCorrectPage())
While this method works, I don't think its the correct way to handle this situation.
So then my next thought was to bind the source like like...(may not be 100%, trying to remember in my head)
set.CreateBinding(_menuCollectionSource) .For(s => s.SelectedCommand) .To(vm => vm.NavigateTo) .CommandParameter(_menuCollectionSource.SelectedItem)
But no matter what I tried, the passed param was always null as if the selected item was never set or the command was being called before it was set.
My CollectionViewCell class is pretty basic
public enum NavigationLocation
{
Search Database,
Lists,
etc....
}
public partial class MainMenuCollectionViewCell : MvxCollectionViewCell
{
public static readonly NSString Key = new NSString("MainMenuCollectionViewCell");
public static readonly UINib Nib;
public string MainMenuLabel
{ get { return mainMenuLabel.Text; } }
public int MainMenuIndexNumber
{ get; set; }
protected MainMenuCollectionViewCell(IntPtr handle) : base(handle)
{
}
static MainMenuCollectionViewCell()
{
Nib = UINib.FromName("MainMenuCollectionViewCell", NSBundle.MainBundle);
}
public static MainMenuCollectionViewCell Create()
{
NSArray topLevelObjects = NSBundle.MainBundle.LoadNib("MainMenuCollectionViewCell", null, null);
MainMenuCollectionViewCell cell = Runtime.GetNSObject(topLevelObjects.ValueAt(0)) as MainMenuCollectionViewCell;
return cell;
}
internal void BindData(string label, string iconBundleName)
{
mainMenuLabel.Text = label;
mainMenuImage.Image = UIImage.FromBundle(iconBundleName);
}
}
No binding I've tried in the cell class has actually worked, even adding a UITapGestureRecognizer on creation caused a crash on actual tap. I've run out of ideas, does anyone know what I'm not understanding or missing to actually implement
( Cell is touched ->
GetCellMenuType - >
CallCorrectCommandFromViewModel)
Thank you
Use EventHandler SelectedItemChanged from MvxBaseCollectionViewSource
View
set.Bind(yourCollectionViewSource).For(s => s.SelectionChangedCommand).To(vm => vm.CollectionItemSelected);
ViewModel
public ICommand CollectionItemSelected => new MvxCommand<ItemViewModel>((selectedItem) => { });

How to bind to the title of a UISegmentedControl segment with MVVMCross?

Is it possible to bind a property of a view model to the title of a segment in UISegmentedControl?
I'm aware of the SetTitle() method, but not sure if it's possible to bind to this in MvvmCross.
Building off of Kiliman's answer to a similar question.
Follow the first 2 steps from that answer. Then create the following custom binding builder.
public class MyTouchBindingBuilder : MvxTouchBindingBuilder
{
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories (registry);
registry.RegisterCustomBindingFactory<UISegmentedControl> ("Title", segmentTitle => new MvxSegmentTitleTargetBinding (segmentTitle));
}
}
And the following custom target binding.
public class MvxSegmentTitleTargetBinding : MvxConvertingTargetBinding
{
public MvxSegmentTitleTargetBinding(object target) : base(target)
{
}
public override Type TargetType
{
get {return typeof(MyViewModel);}
}
protected override void SetValueImpl(object target, object value)
{
var segmentControl = (UISegmentedControl)target;
MyViewModel myViewModel = (MyViewModel)value;
segmentControl.SetTitle(myViewModel.MyFirstValue, 0);
segmentControl.SetTitle(myViewModel.MySecondValue, 1);
}
}
And use it in your view like so.
set.Bind (MySegmentControl).For ("Title").To ((MyViewModel vm) => vm);

How to populate UIPickerView. After creating the outlets in xcode I can NOT seem to find out how to do anything with it

So I create and outlet by dragging the UIPicker into the .h file. I'm really new in Xamarin studio, but I have done endless amounts of research and have tried everything. Basically what I want to do is have the picker view give the user an option of numbers and when one is clicked display the amount for that option. I have tried everything I have read online but its somewhat confusing to me. As in where to put the data and what i should type in compared to what is being told.
I have a app with 2 view controllers the picker view is in the FirstViewController, I assume i put the code in there basically this is what I have but I get errors right from the start saying public PickerModelDelegate(FirstViewController) <___Parser Error: Unexpected symbol 'public' This is my demo I took out of the book just to understand what is going on :/
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace PickerViewApp
{
public class PickerModelDelegate : UIPickerViewModel
public PickerModelDelegate (FristViewController Controller)
{
thi
s.parentController = controller;
this.transportList = new List<string>()
{
"On Foot", "Bivycle", "Motocycle", "Car", "Bus"
};
this.distanceList = new List<string>()
{
"0.5", "1", "5", "10", "100"
};
this.unitList = new List<string>()
{
"mi", "km"
};
this.transportSelected = this.transportList[0];
this.distanceSelected = this.distanceList[0];
this.unitSelected = this.unitList[0];
int GetComponentCount (UIPickerView picker)
int GetRowsInComponent (UIPickerView picker, int component)
string GetTitle (UIPickerView picker, int row, int component)
void Selected(UIPickerView picker, int row, int component)
}
private FirstViewController parentController;
private List<string> transportList;
private List<string> distanceList;
private List<string> unitList;
string transportSelected;
string distanceSelected;
string unitSelected;
}
public partial class FirstViewController : UIViewController
{
public FirstViewController () : base ("FirstViewController", null)
{
Title = NSBundle.MainBundle.LocalizedString ("First", "First");
TabBarItem.Image = UIImage.FromBundle ("first");
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
}
}
Sorry I'm really new at this. Please dont be rude I really want to learn how to do this.
Thanks ahead for any help. I truly do appreciate it!!
You haven't implemented any of the methods that provide the picker with information on the data source.
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace PickerViewApp
{
public class PickerModelDelegate : UIPickerViewModel
{
List<string> Data;
public PickerModelDelegate (List<string> data)
{
Data = data;
this.parentController = controller;
this.transportSelected = this.transportList[0];
this.distanceSelected = this.distanceList[0];
this.unitSelected = this.unitList[0];
}
public override int GetComponentCount (UIPickerView picker)
{
// RETURN THE NUMBER OF COMPONENTS THE PICKER WILL NEED (THE NUMBER OF "SECTIONS" = THE NUMBER OF LISTS OF DATA YOU HAVE)
return 1;
}
public override int GetRowsInComponent (UIPickerView picker, int component)
{
return Data.Count;
}
public override string GetTitle (UIPickerView picker, int row, int component)
{
return Data[row];
}
}
private FirstViewController parentController;
private List<string> transportList;
private List<string> distanceList;
private List<string> unitList;
string transportSelected;
string distanceSelected;
string unitSelected;
public partial class FirstViewController : UIViewController
{
public FirstViewController () : base ("FirstViewController", null)
{
Title = NSBundle.MainBundle.LocalizedString ("First", "First");
TabBarItem.Image = UIImage.FromBundle ("first");
this.transportList = new List<string>()
{
"On Foot", "Bivycle", "Motocycle", "Car", "Bus"
};
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
this.Picker.Model = new PickerModelDelegate (transportList);
}
}
}
You can use the "component" parameter in the methods to determine which list you want to get the data for, for that specific component.
Hope that helps!

BlackBerry OS 6 Native Menu

Hi I am trying to create a global class for my Native Menu, but can seem to get it to load in my Screen Class, I want this to show up where ever I would like to show up.
Not sure if I am doing it right
Here is my MenuItems Class
public final class MenuItems extends MainScreen {
public void getMenuItems(){
MenuItem myItem = new MenuItem(new StringProvider("My Cards"), 0x230000, 0);
myItem.setCommandContext(new Object(){
public String toString(){
return "My Cards";
}
});
myItem.setCommand(new Command(new CommandHandler(){
public void execute(ReadOnlyCommandMetadata metadata, Object context){
// Do Something
}
}));
addMenuItem(myItem);
}
}
The Screen Class I want to add it to is this, not sure if how I would call it here, I tried creating a new instance and just fetching the get method, but no luck, but if I dump the code from the above class in to this class, it will work fine, but I don't want that.
public final class MobiScreen extends MainScreen {
ToolBar toolbar = new ToolBar();
Banner banner = new Banner("Welcome");
MenuItems myMenu = new MenuItems();
public MobiScreen()
{
setTitle(toolbar.getToolBar());
setBanner(banner.getBanner());
myMenu.getMenuItems();
}
}
Why not have MobiScreen extend your MenuItems class?
public class MobiScreen extends MenuItems { ... }

Resources