I'm trying to print my webEngine with print method, and an issue I have is an extra empty page after all the content is printed. I wonder what it could be or how to troubleshoot that issue?
public class JSPrintHook {
public void print() {
PrinterJob job = PrinterJob.createPrinterJob();
if (job != null && job.showPrintDialog(webView.getScene().getWindow())) {
webView.getEngine().print(job);
job.endJob();
}
}
}
It can be a thread handling problem, if you use WebEngine without javafx.application.Application (eg. integrate JavaFX to Swing UI). In this case you should use Platform.runLater().
For example:
Platform.runLater(new Runnable() {
#Override
public void run() {
// print
}
});
Related
I am sure it's just a simple fault, but I'm not able to solve it.
My RecyclerView.Adapter loads its data with help of an AsyncTask (LoadAllPersonsFromDb) out of a SQLite DB. The response is handled by a callback interface (ILoadPersonFromDb.onFindAll).
Here is the code of the Adapter:
public class ListViewAdapter extends RecyclerView.Adapter<ListViewViewholder> implements LoadAllPersonsFromDb.ILoadPersonFromDb {
private int layout;
private List<Person> persons;
private Context context;
private AdapterDataSetListener adapterDataSetListener;
public ListViewAdapter(int layout, Context context,
AdapterDataSetListener adapterDataSetListener) {
this.layout = layout;
persons = new ArrayList<>();
this.context = context;
this.adapterDataSetListener = adapterDataSetListener;
new LoadAllPersonsFromDb(context, this).execute();
}
#Override
public ListViewViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
return new ListViewViewholder(view, context);
}
#Override
public void onBindViewHolder(ListViewViewholder holder, int position) {
holder.assignData(persons.get(position));
}
#Override
public int getItemCount() {
return persons.size();
}
#Override
public void onFindAll(List<Person> persons) {
Log.d("LISTVIEW", "Counted: " + persons.size() + " elements in db");
if (this.persons != null) {
this.persons.clear();
this.persons.addAll(persons);
} else {
this.persons = persons;
}
adapterDataSetListener.onChangeDataSet();
//notifyDataSetChanged();
}
public interface AdapterDataSetListener {
void onChangeDataSet();
}
}
As you can see, I tried more than one way to get it running. The simple notifyDataSetChanged did not do anything, so I made another interface which is used to delegate the ui information to the relating fragment. Following code documents this interface which is implemented in the relating fragment:
#Override
public void onChangeDataSet() {
Log.d("Callback", "called");
listViewAdapter.notifyDataSetChanged();
/*
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
listViewAdapter.notifyDataSetChanged();
}
});
*/
}
Here I also tried to put it on the MainUiThread but nothing works. I'm just not able to see where my problem is. Hopefully any of you guys can give me a hint.
The logging works, which is the prove for the working callbacks.
Thank you in advance.
PS: If you need any more code, just tell me and I will provide it.
instead of using the interface-llistener pattern, try this
#Override
public void onFindAll(List<Person> persons) {
Log.d("LISTVIEW", "Counted: " + persons.size() + " elements in db");
if (this.persons != null) {
this.persons.clear();
this.persons.addAll(persons);
} else {
this.persons = persons;
}
refereshAdapter(persons);
}
public void refereshAdapter(List<Person> persons){
listViewAdapter.clear();
listViewAdapter.addAll(persons);
listViewAdapter.notifyDataSetChanged();
}
To tell the background, I used RecyclerView in Version 23.1.1 because the latest 23.2.0 had some weird behaviour in holding a huge space for each card.
//Update: the problem with the space between cards, was because of a failure of myself in the layout file (match_parent instead of wrap_content). -_-
The upshot was using the latest version again and everything worked just fine. I have no idea why, but at the moment I am just happy, that I can go on. This little problem wasted enough time.
Maybe somebody has a similar situation and can use this insight.
Thx anyway #yUdoDis.
The default behaviour when creating a new Eclipse ViewPart is to show the new tab regardless of what happens in the createPartControl function. For example, if didn't create anything, no widgets, nothing, a blank tab will be shown. I don't like this behaviour. I want to close that tab if initialization in createPartControl fails.
Now, I have a mouse-button-context-menu handler that can do this, e.g.
public class MyPartMB3Handler extends AbstractHandler {
#Override
public Object execute(final ExecutionEvent event)
throws ExecutionException {
// Create a view and show it.
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage page = window.getActivePage();
try {
MyPart viewPart = (MyPart)page.showView(MyPart.ID);
if(!viewPart.isCreated()) {
page.hideView(viewPart);
}
}
catch(PartInitException e) {
e.printStackTrace();
}
return null;
}
}
The isCreated function is a little hack that lets me know if my ViewPart initialization fails, e.g.
public class MyPart extends ViewPart {
public static final String ID = "com.myplugin.MyPart";
private Composite _parent = null;
#Override
public void createPartControl(Composite parent) {
if(!MyPlugin.createPartControl(parent) { // Some common part creation code I use.
//PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(this);
return;
}
_parent = parent;
}
#Override
public void setFocus() {
}
public boolean isCreated() {
return _parent != null;
}
}
The problem arises when I launch this ViewPart from the Eclipse "Quick Access" field. I don't own the handler now. From an exception I forced, the handler might be org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.createPartControl or org.eclipse.ui.internal.e4.compatibility.CompatibilityView.createPartControl or org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create.
I tried hiding the view inside the createPartControl function (see the commented line above), but Eclipse did not like that and spewed a pile of exceptions.
I thought maybe I could throw a PartInitException in createPartControl, but Eclipse tells me I'm not allowed to do that.
So, how do I get my menu handler behaviour when launching from "Quick Access"?
An underlying question might be, is there a better/proper way to achieve this behaviour?
You can close the view by running the hideView asynchronously after the createPartControl has finished - like this:
#Override
public void createPartControl(Composite parent) {
parent.getDisplay().asyncExec(new Runnable() {
#Override
public void run()
{
getSite().getPage().hideView(MyPart.this);
}
});
i need to update a textView from my asynctask. I have an custom adapter for the listview and there i want to have a countdown for each entry. I will start the asynctask for each entry from my Adapter. How can i update the textview each second from the asynctask?
Thanks for help :)
If you post your code, I can give you a better answer. However, a common way to update views periodically is by using Handlers.
private final Handler mHandler = new Handler(); //intialize in main thread
public void test() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mTextView.setText("hello");
}
}, 1000);
}
You can do something like this (this will add an entry to a list view every one second). I have used the normal ArrayAdapter to add a string. You can use your custom adapter to do something similar. The publishProgress() method basically triggers the onProgressUpdate() method which hooks to the UI thread and displays the elements getting added.:
class AddStringTask extends AsyncTask {
#Override
protected Void doInBackground(Void... params) {
for(String item : items) {
publishProgress(item);
SystemClock.sleep(1000);
}
return null;
}
#Override
protected void onProgressUpdate(String... item) {
adapter.add(item[0]);
}
#Override
protected void onPostExecute(Void unused) {
Toast.makeText(getActivity(), "Done adding string item", Toast.LENGTH_SHORT).show();
}
}
I have written an Eclipse plugin that works. What happens, though, is that during the run, no console output is displayed. Only when the process is finished does the output show up in the console. Below is my handler, which appears as an extension point of type org.eclipse.ui.commands:
public class MyHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
...
MessageConsoleStream out = myConsole.newMessageStream();
...
IConsoleView view = (IConsoleView) page.showView(id);
view.display(myConsole);
...
out.println("output that only shows up at the end");
myConsole.activate();
...
// Slow process
...
out.println("everything is done");
return null;
}
}
So while the process runs, nothing in the console. Then at the end, both output lines pop into view.
I'm obviously doing the console thing incorrectly, but I haven't found any good examples, nor has my experimentation proven very fruitful. Please advise.
You could consider using a ProgressMonitor (possibly with cancelation in case the user wants to abort), so that the user can see that there is something going on.
This worked:
public class Merge extends AbstractHandler {
private static MessageConsole myConsole = null;
private static ExecutionEvent event = null;
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Merge.event = event;
//same idea as original post and other examples where it makes new or finds existing
myConsole = makeConsole(Merge.event);
Job job = new Job("My Job Name"){
#Override
protected IStatus run(IProgressMonitor monitor){
...
if (blah) {
MessageConsoleStream out = myConsole.newMessageStream();
out.println("output show up right away");
...
// Slow process
...
out.println("everything is done");
} else {
MessageDialog.openInformation(HandlerUtil.getActiveShell(Merge.event), "Information", "Please select valid file");
}
monitor.done();
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();
return null;
}
...
}
Maybe you can call out.flush() after every out.print...
As suggested in this question GWT - Where should i use code splitting while using places/activities/mappers?, I created an ActivityProxy to nest my activities.
I based my implementation on this http://code.google.com/p/google-web-toolkit/issues/detail?id=5129 (6th comment), with one modification: I added a check on the provider before calling GWT.RunAsync:
if (provider != null)
{
GWT.runAsync(new RunAsyncCallback()
{
#Override
public void onFailure(Throwable reason)
{
// ...
}
#Override
public void onSuccess()
{
ActivityProxy.this.nestedActivity = provider.create();
//...
}
});
}
But for some reason, this doesn't work in release mode: the onFailure methode is never called but my activity is never displayed the first time I use it. If I reload the place, everything display just fine.
Then I realised that doing the following solves the problem:
GWT.runAsync(new RunAsyncCallback()
{
#Override
public void onFailure(Throwable reason)
{
// ...
}
#Override
public void onSuccess()
{
if (provider != null)
{
ActivityProxy.this.nestedActivity = provider.create();
//...
}
}
});
So even if I don't understand why it works, I started using it for all my activities.
I ran into the problem again when I decided to use a generator for my ActivityProxy (to avoid writing a provider for each Activity). The synthax becomes GWT.create(ActivityProxy).wrap(MyActivity.class);
Basically, the generated code looks like this:
if (clazz.getName() == "FooClass")
{
nestedActivity = new FooClass(); //inside a RunAsync
}
if (clazz.getName() == "BarClass")
{
nestedActivity = new BarClass(); //inside a RunAsync
}
And the same problem occurs: my app fails to display my activities the first time they are used.
So simple question : "Why?"