Here is my code that set action for ctrl+c combination in JavaFX. It doesn't work when there is a focus on TextField command_line. Why?
public void setCtrlC() {
command_line.getScene().getAccelerators().put(new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY),
new Runnable() {
#Override
public void run() {
LOGGER.debug("CTRL+C pressed");
try {
if (tab_toradex.isSelected()) {
bw.write(3);
bw.flush();
}
if(tab_novatel.isSelected()){
bw2.write(3);
bw2.flush();
}
} catch (IOException e) {
LOGGER.debug("CTRL+C command failed");
}
}
});
}
Thanks!
Ok, solved with this:
final KeyCombination keyCombinationShiftC = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_DOWN);
public void setCtrlC() {
command_line.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (keyCombinationShiftC.match(event)) {
LOGGER.debug("CTRL+C pressed");
try {
if (tab_toradex.isSelected()) {
bw.write(3);
bw.flush();
}
if(tab_novatel.isSelected()){
bw2.write(3);
bw2.flush();
}
} catch (IOException e) {
LOGGER.debug("CTRL+C command failed");
}
}
}
});
}
On the other hand, now it works only while TextField is focused...
Related
I want to show progress bar while a functionality is running. What is the best way to show it? Basically I am building a program to send multiple mails on a single click. While sending the mail I want to show progress bar while sending the mails.
The best solution in this case is using a Task.
Example:
Task<Parent> yourTaskName = new Task<Parent>() {
#Override
public Parent call() {
// DO YOUR WORK
//method to set progress
updateProgress(workDone, max);
//method to set labeltext
updateMessage(message);
}
};
//ProgressBar
ProgressBar pBar = new ProgressBar();
//Load Value from Task
pBar.progressProperty().bind(yourTaskName.progressProperty());
//New Loading Label
Label statusLabel = new Label();
//Get Text
statusLabel.setText("Loading...");
//Layout
VBox root = new VBox(statusLabel, pBar);
//SetFill Width TRUE
root.setFillWidth(true);
//Center Items
root.setAlignment(Pos.CENTER);
//SetOnSucceeded methode
yourTaskName.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
System.out.println("Finish");
}
});
//Start Thread
Thread loadingThread = new Thread(yourTaskName);
loadingThread.start();
Hope this helps you.
P.S.: The code in the task run as a Thread...
I implemented what you want last time ,If you want to show progressIndicator or progressBar when sending is running ,try this part of code
senderThreadlive = new Thread(new Runnable() {
#Override
public void run() {
try {
Platform.runLater(new Runnable() {
#Override
public void run() {
ProgressIndicator WaitingSend=new ProgressIndicator();
WaitingSend.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
WaitingBox.getChildren().add(WaitingSend);//this is an HBOX
SendMailButton.setDisable(true);
SendMailButton.setText("sending in progress");
}
});
//call Your method of sending
SimpleMail.EmailSender.sendEmail(MailSenderTxt.getText(), MotMailTxt.getText(), DestMailTxt.getText(), ObjetMailTxt.getText(), org.jsoup.Jsoup.parse(ContentMail.getHtmlText()).text());
Platform.runLater(new Runnable() {
#Override
public void run() {
WaitingSend.setProgress(0);
WaitingSend.setVisible(false);
SendMailButton.setDisable(false);
SendMailButton.setText("Send");
}
});
} catch (AuthenticationFailedException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (SendFailedException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (MessagingException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (Exception ex) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
}
}
});
senderThreadlive.start();
Just use javafx.scene.control.ProgressBar
Documentation:
http://docs.oracle.com/javafx/2/ui_controls/progress.htm
In a JavaFX application I wish to update a status bar according to some work logic which I've implemented in an other class.
I can't figure out how to combine my desire to pass to work logic to the method (and not to write it inside the task) and to know about the work progress percentage.
This is an example of the controller with the Task:
public class FXMLDocumentController implements Initializable {
#FXML private Label label;
#FXML ProgressBar progressBar;
#FXML
private void handleButtonAction(ActionEvent event) {
Service<Void> myService = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
DatabaseFunctionality.performWorkOnDb();
//updateProgress(1, 1);
} catch (InterruptedException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
};
}
};
progressBar.progressProperty().bind(myService.progressProperty());
myService.restart();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
This is the helper class:
public class DatabaseFunctionality {
public static void performWorkOnDb () throws InterruptedException {
for (int i = 1; i <= 100; i++) {
System.out.println("i=" + i);
Thread.sleep(100);
//Update progress
}
}
}
Thank you
You have a couple of options here. One is to do as Uluk suggests and expose an observable property in your DatabaseFunctionality class:
public class DatabaseFunctionality {
private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper();
public double getProgress() {
return progressProperty().get();
}
public ReadOnlyDoubleProperty progressProperty() {
return progress ;
}
public void performWorkOnDb() throws Exception {
for (int i = 1; i <= 100; i++) {
System.out.println("i=" + i);
Thread.sleep(100);
progress.set(1.0*i / 100);
}
}
}
And now in your Task, you can observe that property and update the task's progress:
Service<Void> myService = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
DatabaseFunctionality dbFunc = new DatabaseFunctionality();
dbFunc.progressProperty().addListener((obs, oldProgress, newProgress) ->
updateProgress(newProgress.doubleValue(), 1));
dbaseFunc.performWorkOnDb();
} catch (InterruptedException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
};
}
};
Another option (in case you don't want your data access object to depend on the JavaFX properties API) is to pass the data access object a callback to update the progress. A BiConsumer<Integer, Integer> would work for this:
public class DatabaseFunctionality {
private BiConsumer<Integer, Integer> progressUpdate ;
public void setProgressUpdate(BiConsumer<Integer, Integer> progressUpdate) {
this.progressUpdate = progressUpdate ;
}
public void performWorkOnDb() throws Exception {
for (int i = 1; i <= 100; i++) {
System.out.println("i=" + i);
Thread.sleep(100);
if (progressUpdate != null) {
progressUpdate.accept(i, 100);
}
}
}
}
and then
Service<Void> myService = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
DatabaseFunctionality dbFunc = new DatabaseFunctionality();
dbFunc.setProgressUpdate((workDone, totalWork) ->
updateProgress(workDone, totalWork));
dbaseFunc.performWorkOnDb();
} catch (InterruptedException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
};
}
};
public void initialize() {
Task<Void> task = new Task<>() {
#Override
protected Void call() {
try {
Double d = 0.0;
for (int i = 1; i <= 100; i++) {
Thread.sleep(100);
d = 1.0 * i / 100;
updateProgress(d, 1);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
task.progressProperty().addListener((obs, oldProgress, newProgress) -> {
System.out.println((newProgress.doubleValue() * 100) + "% completed");
});
new Thread(task).start();
}
I have a multiple buttons; When I press new button, previous(with another button) running request should be interrupted and new runs. How to realize it?
for (button : Buttons) {
button.setOnClickListener(b -> networkApi.getLongContentFromUrl(url)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<JsonElement>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(JsonElement jsonElement) {
//do with result
}
}));
}
You can have a common SerialSubscription and assign your subscriber to it on button click. It will unsubscribe and thus cancel your previous stream:
SerialSubscription serial = new SerialSubscription();
for (Button btn : buttons) {
btn.setOnClickListener(e -> {
Subscriber<JsonElement> s = new Subscriber<JsonElement>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {}
#Override
public void onNext(JsonElement jsonElement) {
//do with result
}
};
serial.set(s);
networkApi.getLongContentFromUrl(url)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s);
});
}
I have a static BorderPane with ContextMenu insight Task
Task task = new Task()
{
#Override
protected Void call() throws Exception
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
try
{
contextMenu = new ContextMenu();
MenuItem item1 = new MenuItem("About");
item1.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("About");
}
});
MenuItem item2 = new MenuItem("Preferences");
item2.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("Preferences");
}
});
MenuItem item3 = new MenuItem("Close");
item3.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
}
});
contextMenu.getItems().addAll(item1, item2, item3);
bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
{
#Override
public void handle(ContextMenuEvent event)
{
contextMenu.show(bp, event.getScreenX(), event.getScreenY());
event.consume();
}
});
bp.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent event)
{
contextMenu.hide();
}
});
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
}
}
});
return null;
}
};
new Thread(task).start();
I noticed that when I close the component which holds the BorderPane the Java Threads are not disposed they are still initialized into the memory. I'm not sure is this caused by the static BorderPane. After the Task is completed the Java Thread should be disposed. Any idea why is this happening?
The problem is not a Task, but the anonymous classes in your Runnable.
In the next piece of code:
bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
{
#Override
public void handle(ContextMenuEvent event) {
//...
}
});
you introduce an anonymous class extending EventHandler which holds inner link to a Runnable. To solve that you can use nested static class instead.
P.S.: Unfortunately you can't make anonymous class static in Java, see Is it possible to make anonymous inner classes in Java static?
Now a days it's my first step in android. I am simply trying to implement progress bar with with a "Download" Button. When i press download button progress bar keep on progressing but when the whole progress gets over i am not able to hide progress bar. Here is my code. please help me.
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread timer = new Thread()
{
public void run()
{
try
{
for(int i=0; i<=50; i ++)
{
pb.incrementProgressBy(i);
sleep(1000);
}
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo.this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}catch(Exception e){}
}
};
timer.start();
}
});
}
}
You should only modifiy ui elements from the mainThread (the UI Thread) try
pb.post(new Runnable() {
#Override
public void run() {
pb.setVisibility(View.INVISIBLE);
}
})
instead.
Maybe u have to use the same thing for incrementing your progressbar. Alternativley you could use the AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html class. onProgressUpdate and onPostExecute are called in the UIThread automatically.
you can also use AsynTask that is a better solution...
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
new AsynTasks().execute();
}
});
}
class AsynTasks extends AsyncTask<Void, Integer, Void>
{
#Override
protected Void doInBackground(Void... params) {
for(int i=1;i<=100;i++)
{
SystemClock.sleep(1000);
publishProgress(i);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo .this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}
}
}
You should not do UI task from different thread.Use this...
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread timer = new Thread()
{
public void run()
{
try
{
for(int i=1; i<=100; i ++)
{
pb.setProgress(i);
sleep(100);
}
}catch(Exception e){}
finally{
runOnUiThread( new Runnable() {
public void run() {
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo .this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}
});
}
}
};
timer.start();
}
});
}
}