How to implement paging for a TableView in JavaFX? [duplicate] - pagination

This question already has answers here:
JavaFX TableView Paginator
(3 answers)
Closed 8 years ago.
I have JavaFx TableView, and want to implement tableView paging display.
How to javaFx tableView Implement paging display?

You have to use the Pagination control and implement a page factory. The factory is called for every page that should be displayed and you can use its parameter, the pageIndex, to provide a sublist of items to the TableView:
TableView table = ...
private Node createPage(int pageIndex) {
int fromIndex = pageIndex * rowsPerPage;
int toIndex = Math.min(fromIndex + rowsPerPage, data.size());
table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));
return new BorderPane(table);
}
#Override
public void start(final Stage stage) throws Exception {
Pagination pagination = new Pagination((data.size() / rowsPerPage + 1), 0);
pagination.setPageFactory(this::createPage);
...
}
A complete runnable example can be found here:
https://gist.github.com/timbuethe/7becdc4556225e7c5b7b
PS: I followed jewelsea link to the Oracle JavaFX Forums, and the example is really bad. I wanted to provide an cleaned up example here.

Related

Xamarin iOS monotouch dialog - labels overlapping text input

When you create a dialog similar to the one below
And then navigate to a new view controller by tapping on a radiobutton group (in my example industry type), then return back your labels are endinf up overlapping the text. Tested on simulator and Apple iPad mini 2.
Has anyone found a way to fix this without creating a custom class ?
The only way was to create a new class and explicitly specify constraints by overriding GetCell method:
public class BaseEntryElement:EntryElement
{
.....
public override UITableViewCell GetCell (UITableView tv)
{
var c= base.GetCell (tv);
c.ContentView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints ();
c.ContentView.AddConstraints (
c.ContentView.Subviews[0].WithSameCenterY(c.ContentView),
c.ContentView.Subviews[0].AtLeftOf(c.ContentView,BaseEntryElement.offset),
c.ContentView.Subviews[0].AtTopOf(c.ContentView),
c.ContentView.Subviews[1].ToRightOf(c.ContentView.Subviews[0],40),
c.ContentView.Subviews[1].WithSameCenterY(c.ContentView.Subviews[0])
);
return c;
}
}

Why isn't my custom UICollectionViewController's GetCell method called

I have a storyboard set up like so:
As you can see, I have a home screen. It has access to a navigation controller. It has two ContainerViews, one used as a sidepane, the other as the main content. I plan to swap things into this main content container as I need them.
One of the things I would like to show in this container, when it is selected from the sidepane, is a CollectionView of cells that show people. Each cell has a photo and the person's details.
The best code example I could find for CollectionView was the Xamarin StateRestoration sample project. It includes a storyboard. I have followed the recipe as best I can while working around my own specific storyboard.
The problem now is that the GetCell(UICollectionView collectionView, NSIndexPath indexPath) method used to populate each cell in the CollectionView is not being called. As far as I know I'm supposed to instantiate the CollectionViewController's Datasource property. I've tried this in AppDelegate and in the ViewDidLoad of my CollectionViewController itself, and GetCell is still not getting called. Why is this?
Any help is appreciated! Ask me to edit if you need more information.
You need to set both datasource and the delegate. As you've mentioned you've set the datasource. To set the delegate open up the storyboard in xcode, select UICollectionView and control drag to the its parent view controller. Have a look at this gif.
Also make sure you implement IUICollectionViewSource interface in your target view controller
public partial class DetailViewController : UIViewController, IUICollectionViewSource
{
protected DetailViewController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public nint GetItemsCount(UICollectionView collectionView, nint section)
{
return 10;
}
public UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
var cell = collectionView.DequeueReusableCell("PersonCell", indexPath) as UICollectionViewCell;
return cell;
}
}
EDIT 1:
You can also do this programmatically. Enter the storyboard, in Widget properties set the name for the UICollectionView - PersonCollection. Then in code behind view controller override ViewDidLoad and set WeakDelegate and WeakDataSource (weak because we definitely not want to create cyclic reference and memory leaks for iOS)
public override void ViewDidLoad()
{
base.ViewDidLoad();
PersonCollection.WeakDataSource = this;
PersonCollection.WeakDelegate = this;
}
Hope this helps!

Re-implement JavaFX showAndWait [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to achieve the functionality of Stage.showAndWait() without using the method itself.
I have an application and I need a way of displaying something within the same stage and block the thread displaying the content until a button is pressed.
The thread displaying the content naturally needs to be tha JavaFX application thread - which of course won't handle the buttons as long as it is blocked.
Stage.showAndWait describes its inner workings as "This method temporarily blocks processing of the current event, and starts a nested event loop to handle other events." I see that the method calls "Toolkit.getToolkit().enterNestedEventLoop(this)", which is pretty implementation specific. Are there any other options? Is functionality like this exposed anywhere in the API?
Edit:
Since my question was misleading, I try to rephrase it more to the point from my current perspective:
Is there a public API for Toolkit.getToolkit().enterNestedEventLoop() and Toolkit.getToolkit().exitNestedEventLoop() ?
For my rephrased question:
Is there a public API for Toolkit.getToolkit().enterNestedEventLoop() and Toolkit.getToolkit().exitNestedEventLoop() ?
Since then the API has been made public in:
javafx.application.Platform.enterNestedEventLoop()
It isn't really clear what you are trying to do, but it sounds like you have some long running process that is building up some kind of data, and then you want the user to control how that built up data is delivered to the screen. In that case, then you need to run a background task to build the data, transfer that data to some element that is available to the FXAT, and then use the action event of a button to move the data onto the screen. Something like this:
public class LongTask extends Application {
StringProperty results = new SimpleStringProperty("");
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
TextArea textArea = new TextArea();
BorderPane root = new BorderPane();
root.setCenter(textArea);
Button button = new Button("More Data");
root.setBottom(button);
button.setOnAction(evt -> textArea.setText(results.get()));
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
Task<Void> sleeper = new Task<Void>() {
#Override
protected Void call() throws Exception {
for (int iteration = 0; iteration < 1000; iteration++) {
try {
Thread.sleep(5000);
int i = iteration;
Platform.runLater(() -> results.set(results.get() + "\nIteration " + i));
} catch (InterruptedException e) {
}
}
return null;
}
};
new Thread(sleeper).start();
}
}
Technically, you don't need to make "results" a property, nor do you need to update it through Platform.runlater(). Using Platform.runlater() guarantees that you won't have concurrency issues with results. Also, if you bind "results" to anything, then you'll need to use Platform.runlater() to modify it.

Missing Reference to Navigation Controller in Monotouch

I am new to Monotouch and attempting to understand how some of the basics hang together. Hopefully someone out there will be able to assist.
I've created a test project in MonoDevelop based on the Multi-Screened Apps tutorial on the Xamarin site and have extended it to include a tableView. I am having issues with referencing the Navigation Controller in a view that I need to push a detail view onto to display the detail of an item tapped in the table via an accessory button. I know some of the coding is scrappy, just been trying to get it working at this stage rather than the clarity in the code! (I'm using the latest versions of all Mono tools/libraries etc and XCode 4 on Lion). Starting at the beginning here's the code in FinishedLaunching in AppDelegate.
window = new UIWindow (UIScreen.MainScreen.Bounds);
this.rootNavigationController = new UINavigationController();
// Create a new homescreen
HomeScreen homeScreen = new HomeScreen();
// Add the homescreen to the root navigation controller
this.rootNavigationController.PushViewController(homeScreen, false);
// Set the root view controller on the window - the navigation controller
// will handle the rest.
this.window.RootViewController = this.rootNavigationController;
// make the window visible
this.window.MakeKeyAndVisible ();
homeScreen just contains a button which loads a new view containing a table view (OrderList). Here's the button event handler.
void HandleOrdersButtonhandleTouchUpInside (object sender, EventArgs e)
{
if (orderListScreen == null)
orderListScreen = new OrderList();
NavigationController.PushViewController(orderListScreen, true);
}
This all works fine. I've got some dummy data that loads into the table view, which also works fine. OrderData is a simple class for testing which just contains a couple of properties. I've added an AccessoryButton to the cells and am trying to load a detail view when this is tapped. Here's the code that does this - comment in code where issue is! (I'd previously tested the AccessoryButtonTapped functionilty was working by just displaying an alert).
public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
{
var dataSource = (OrdersTableViewDataSource)tableView.DataSource;
if (detailScreen == null)
detailScreen = new OrderDetailScreen();
OrderData theOrder = dataSource.OrdersData[indexPath.Row];
detailScreen.currentOrder = theOrder;
// Cant get a reference to NavigationController here to push the detail view!
// this.NavigationController is not available
this.NavigationController.PushViewController(detailScreen, true);
}
My understanding of NavigationControllers from what I've read so far is that this reference should be available through all views that originate from the root ViewController/NavigationController without the need to pass the reference from AppDelegate through the various view constructors?
Can anyone tell me what I might be missing here?
Thanks in advance.
** An update after reviewing Jason's comment: (Please let me know if this is the incorrect way to post updates)
So, I tried the following:
I saved a reference to the NavigationController in the constructor for the ViewController that contains the table view as follows:
public partial class OrderList : UIViewController
{
UINavigationController navController;
public OrderList () : base ("OrderList", null)
{
this.Title = "Orders";
navController = this.NavigationController;
}
Then passed that into the TableViewDelegate, where the AccessoryButtonTapped is handled, in the ViewDidLoad method.
public override void ViewDidLoad ()
{
orderTableView.DataSource = new OrdersTableViewDataSource();
orderTableView.Delegate = new OrdersTableViewDelegate(navController);
base.ViewDidLoad ();
}
Then referenced that in the TableViewDelegate:
public class OrdersTableViewDelegate : UITableViewDelegate
{
UINavigationController navController;
public OrdersTableViewDelegate(UINavigationController controller)
{
navController = controller;
}
// Rest of class definition
}
Then the reference to the NavigationController using navController compiles with the code as previously described using the following in the AccessoryButtonTapped method:
navController.PushViewController(detailScreen, true);
When I run this and tap on the AccessoryButton I get a null reference exception on navController. The reference to this.NavigationController in the ViewController constructor is null. Am I doing something in the wrong place or sequence?
Cheers
The NavigationController property is on your table's view controller. If you are trying to reference it from your table's datasource, you need to pass a reference to the controller when you create the datasource.

GWT - Refreshing an element on the page

Hi I play with GWT in the weekends, and I really like what i've seen
so far. I have 2 questions:
I don't really understand the execution model of my app. I think
that's because I don't know javascript. I'm assuming that there is
only one logical thread from the browser running the javascript and it
is the same thread that updates the display (disregarding asynchronous
requests). So when through js I add 50 elements to a frame, the 50
elements are displayed after all of them are added to the frame. In
other words, after the js has finished executing. Do I have it
right? Are there articles out there on this topic?
Sorry this is not a great example, but it may get my question
across. What do I do in the following situation (design):
a) update the text in a label to "starting..."
b) do a bunch of js and dom manipulation
c) update the text in the label to "finished!"
Currently, all I see is the after-effect: my dom manipulation and
"finished". The label never displays "starting..."
How can I force the label to refresh between step a & b. I've seen
some posts describing that one could use the Timer and somehow force
the element to refresh. But I can't figure out how this is achieved.
Looking forward to your suggestions. Thanks in advance.
To 1): Yes, javascript is single threaded. It is up to you to implement long running operations as non-blocking. Otherwise you're likely to run into Slow Script Warnings (see next point).
To 2): Have a look at the IncrementalCommand class (it's usage is described here). With it you can divide long running operations into chunks of smaller work and display progress updates to the user. A small example:
public class Starter implements EntryPoint {
private Label text = new Label();
private Label update = new Label();
#Override
public void onModuleLoad() {
Button btn = new Button("hit me");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
text.setText("starting...");
startIncrementalWork();
}
});
RootPanel.get().add(text);
RootPanel.get().add(update);
RootPanel.get().add(btn);
}
private void startIncrementalWork() {
IncrementalCommand cmd = new IncrementalCommand() {
private int count = 0;
#Override
public boolean execute() {
if (count >= 10000) {
text.setText("finished");
return false;
}
for (int i = 0; i < 100; i++) {
update.setText("count " + count);
count++;
}
return true;
}
};
DeferredCommand.addCommand(cmd);
}
}
Hope that helps.

Resources