I'm trying to do a random method with BlueJ to play a random song of a playlist and then continue. My problem is that it just play one song and then stop. Here is my code. Hope someone can help me
https://gist.github.com/anonymous/9493432
My error is that all songs start simultaneously. Here is my code:
public void randomAllTracks(int index){
if(indexValid(index)) {
for(Track track : tracks) {
player.startPlaying(track.getFilename());
System.out.println("Now playing: " + track.getArtist() + " - " + track.getTitle());
System.out.println();
int randomTrack = (int)(Math.random() * tracks.size());
}
}
}
To get a random track that is always a valid index:
int randomTrack = (int)(Math.random() * tracks.size());
You can delete method randomTrack() because you don't need it.
You need some type of indication in class MusicPlayer to check whether the track is done. Here, this is represented by trackFinished. You can look at that variable as you play the song.
boolean trackFinished = true;
public void randomAllTracks(int index) {
while (true) {
if (trackFinished) {
playTrack((int)(Math.random() * tracks.size()));
trackFinished = false;
}
}
}
MusicPlayer code:
public class MusicPlayer
{
// The current player. It might be null.
private AdvancedPlayer player;
boolean finished = true;
//some code
public void startPlaying(final String filename)
{
try {
setupPlayer(filename);
Thread playerThread = new Thread() {
public void run()
{
try {
trackFinished = false;
player.play(5000);
}
catch(JavaLayerException e) {
reportProblem(filename);
}
finally {
killPlayer();
trackFinished = true;
}
}
};
playerThread.start();
}
catch (Exception ex) {
reportProblem(filename);
}
}
}
Related
I have a question about using events to run loops since doing so seems to lock down the thread. For example I have an nativeMousePressed and nativeMouseReleased event and I am trying to execute some code continuously while the mouse is pressed and then stop when its released. I tried to do this by creating a static boolean variable in another manager class and then setting it to true when the mouse is being pressed and false when the mouse is released. Then I decided to make a while loop that gets called from inside that nativeMousePressed event that uses the boolean value I talked about earlier. The issue is that no events can be called while that while loop is running which means the boolean value when never become false creating an infinite loop. How can I run the while loop while keeping the events running as well?
I assume this has to do with the thread being locked down but I have not worked with stuff like this much and would like some help figuring out how to run both these things in parallel.
public class NativeMouseEvent implements NativeMouseListener {
Program program = new Program();
#Override
public void nativeMouseClicked(org.jnativehook.mouse.NativeMouseEvent e) {
}
#Override
public void nativeMousePressed(org.jnativehook.mouse.NativeMouseEvent e) {
if(e.getButton() == 1 && Controller.threeClicked) {
Controller.fixAim = true;
program.start();
}
}
#Override
public void nativeMouseReleased(org.jnativehook.mouse.NativeMouseEvent e) {
program.interrupt();
Controller.fixAim = false;
}
}
Here is what my second thread is running...
public class Program extends Thread {
public void run() {
while(Controller.fixAim) {
System.out.println("test");
}
}
Here my second attempt which also gives me an error saying that this.program is null.
public class NativeMouseEvent implements NativeMouseListener {
Program program;
#Override
public void nativeMouseClicked(org.jnativehook.mouse.NativeMouseEvent e) {
}
#Override
public void nativeMousePressed(org.jnativehook.mouse.NativeMouseEvent e) {
if(e.getButton() == 1 && Controller.threeClicked) {
Controller.fixAim = true;
if(program != null) {
program = new Program();
program.start();
}
}
}
#Override
public void nativeMouseReleased(org.jnativehook.mouse.NativeMouseEvent e) {
program.interrupt();
program = null;
Controller.fixAim = false;
}
}
Start a tread on mouse down and stop the tread on mouse up. In the thread do circle drawing.
Something like below java code. Note: it is just an example. You need to make changes to make it work in your android environment.
public class Test {
Thread drawTask;
public void mouseDown() {
drawTask = new Thread(()-> {
int i = 0;
try {
for(;;) {
System.out.print("\rDrawing circle " + i++);
Thread.sleep(500);
}
} catch(InterruptedException e) {
System.out.println("finished drawing circle.");
}
});
drawTask.start();
}
public void mouseUp() {
if(drawTask != null) {
drawTask.interrupt();
drawTask = null; //<--- make sure you do this
}
}
public static void main(String[] args) {
Test test = new Test();
Scanner in = new Scanner(System.in);
System.out.println("type anything and press Enter to simulate mouse down/up");
in.next();
test.mouseDown();
in.next();
test.mouseUp();
in.next();
in.close();
}
}
So I have implemented Observer Pattern. In the update function of my Observer class, I want to update the progressbar. The problem is that it instantly updates to the maximum value. I don't get an loading animation. The application calculates some edges. After the calculation of the edges, they will be drawn on the screen.
My observers are the following :
GenerateEdgeBottom
GenerateEdgeLeft
GenerateEdgeRight
I also have a KochManager and an javaFX class.
I make my progressbars in the javaFX class. In the javaFX class is a function that binds all the progressbars.
Part of my javaFX class
public void binding(GenerateEdgeLeft leftEdges, GenerateEdgeRight rightEdges, GenerateEdgeBottom bottomEdges) {
progressBarLeft.progressProperty().unbind();
progressBarLeft.setProgress(0);
progressBarRight.progressProperty().unbind();
progressBarRight.setProgress(0);
progressBarBottom.progressProperty().unbind();
progressBarBottom.setProgress(0);
progressBarLeft.progressProperty().bind(leftEdges.progressProperty());
progressBarRight.progressProperty().bind(rightEdges.progressProperty());
progressBarBottom.progressProperty().bind(bottomEdges.progressProperty());
lblLeft.textProperty().bind(leftEdges.messageProperty());
lblRight.textProperty().bind(rightEdges.messageProperty());
lblBottom.textProperty().bind(bottomEdges.messageProperty());
}
My kochmanager
public void changeLevel(int nxt) {
edges.clear();
koch.setLevel(nxt);
this.leftEdgeTask = new GenerateEdgeLeft(koch);
this.bottomEdgeTask = new GenerateEdgeBottom(koch);
this.rightEdgeTask = new GenerateEdgeRight(koch);
tsCalc.init();
tsCalc.setBegin("Begin calculating");
//System.out.println("test 3");
Platform.runLater(() -> {
//System.out.println("test 4");
application.binding(leftEdgeTask,rightEdgeTask,bottomEdgeTask);
futures.clear();
Future<?> f = pool2.submit(bottomEdgeTask);
Future<?> f2 =pool2.submit(leftEdgeTask);
Future<?> f3 = pool2.submit(rightEdgeTask);
futures.add(f);
futures.add(f2);
futures.add(f3);
try {
edges.addAll(leftEdgeTask.get());
edges.addAll(rightEdgeTask.get());
edges.addAll(bottomEdgeTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//System.out.println("test 5");
koch.getEdges().clear();
tsCalc.setEnd("End calculating");
application.setTextNrEdges("" + koch.getNrOfEdges());
application.setTextCalc(tsCalc.toString());
application.requestDrawEdges();
drawEdges();
});
}
My GenerateEdgeLeft
public class GenerateEdgeLeft extends Task<ArrayList<Edge>> implements Observer {
private KochFractal koch;
//private KochManager manager;
private int numberOfEdges;
private int counter;
private ArrayList<Edge> edges = new ArrayList<>();
public GenerateEdgeLeft(KochFractal koch){
this.koch = koch;
numberOfEdges = koch.getNrOfEdges() / 3;
this.koch.addObserver(this);
}
public GenerateEdgeLeft() {
//edges.size
}
public ArrayList<Edge> getResult() {
return edges;
}
#Override
public ArrayList<Edge> call() throws Exception {
counter = 0;
System.out.println("Thread Started Left");
koch.generateLeftEdge();
edges = koch.getEdges();
return edges;
}
#Override
public void update(Observable o, Object arg) {
edges.add((Edge) arg);
counter++;
updateProgress(counter, numberOfEdges);
updateMessage( "Left : " + counter);
}
}
I am trying to plot data received from Bluetooth with real-time with MPAndroidChart library. I believe there is problem with thread deadlocks but I cannot figure it out exactly.
Here is how the code goes:
After connection is established, when "Read" button is pressed.
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent;
if (dtToggle.onOptionsItemSelected(item)) { return true; }
switch (item.getItemId())
{ ......
case R.id.menu_read:
String message;
if (oper_state) {
oper_state = false;
put_thread = new PutTask();
put_thread.start();
timer = new Timer();
timer.schedule(new MyTask(),10, 100);
//feedMultiple();
//put_thread.start();
message = CMD_READ + "";
sendMessage(message);
} else {
if(timer != null)
{
message = CMD_STOP + "";
sendMessage(message);
put_thread.interrupt();
timer.cancel();
timer.purge();
timer = null;
oper_state = true;
//put_thread.interrupt();
try{
if(fos != null)
fos.close();
}
catch(Exception e)
{
}
}
}
return true;
PutThread is where I add received data from bluetooth to data queue:
class PutTask extends Thread {
public void run(){
int channel_idx;
customParsePackets mBluetoothService;
while(true)
{
mBluetoothService = mChestPatchService;
for(int i=0;i<num_siganl_list;i++)
{
if(!mBluetoothService.isEmpty(i))
{
int read_data = mBluetoothService.poll_data(i);
put_data(i, read_data);
sample_incr(i);
}
}
}
}
}
Put_data function:
public synchronized void put_data(int i, int int_data)
{
int tmp_sample = 0;
int tmp_data, filtered_data;
double tmp_diff_val=0;
tmp_sample = sample_get_value(i);
tmp_data = int_data;
if(mECGSignCheck.isChecked())
tmp_data = -tmp_data;
if(mFilterCheck.isChecked() == true)
ecg_data[i] = ECG_bpf[i].getOutputSample(tmp_data);
else
ecg_data[i] = tmp_data;
if(i==1) {
tmp_diff_val = mRpeak.put_ecg(tmp_sample, tmp_data);
peak_point = mRpeak.Apply_ecg();
Log.d("PEAK", "Data pushed" );
}
synchronized (chartQueue_Lock){
if(tmp_sample % 4 == 0)
**chartQueue[i].offer(new Point(tmp_sample, (int)ecg_data[i]));**
}
}
And this is where I update my UI:
class MyTask extends TimerTask {
public void run(){
runOnUiThread(new Runnable(){
#Override
public void run(){
//updateui();
dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500);
}
});
}
}
The above code works perfectly fine for GraphView Library. But I want to implement it for MPAndroidChart.
For MPAndroidChart when I start do dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500); in the above class it works well. But my goal is to add the data from the data queue to the graphs. So in order to do so, in the above code sample instead of dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500); I call updateui() from where I poll the data from the queue and call dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500);:
public void updateui()
{
long starttime, endtime;
int tmp_sample = sample_get_value(APW_SIGNAL);
Point qPoint = new Point();
for(int i=0; i<num_siganl_list; i++)
{
int poll_num = 0;
while(!chartQueue[i].isEmpty())
{
if(poll_num != 0)
{
if(qPoint.x % 4 == 0) {
dataseries_add_new(i, qPoint.x, qPoint.y);
}
}
synchronized (chartQueue_Lock)
{
qPoint = chartQueue[i].poll();
}
poll_num = 1;
}
Where the graph update code is taken from MPAndroidChart sample app for Realtime Chart.
When "Read" button is presed app screen goes black for some time and then gives an error. Could you please provide some insight about how to solve the problem?
This question already has answers here:
Swing Progress Bar updates via Worker to EventDispatch thread
(2 answers)
Closed 7 years ago.
All the coding runs, my only problem is that the progress bar doesn't display the value changes. I set the values, but if I run it the value set, doesn't display on the progress bar. (The bar doesn't fill up)
public void logIn() {
try {
while (true) {
calculate();
System.out.println(loadingProgress);
if (loadingProgress < 100) {
mGUI.pbLoading.setValue(loadingProgress);
Thread.sleep(random.nextInt(5000) + 100);
} else {
mGUI.pbLoading.setValue(100);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void calculate() {
random = new Random();
loadingProgress = loadingProgress + random.nextInt(9) + 1;
}
The calculation has to be done in an extra thread. This is because the currently running thread is blocking the repaint of the UI until the calculation is done.
The problem is outside your posted code. I used your code to create a working example:
package snippet;
import java.util.Random;
public class Snippet {
public class ValueAccepter {
public void setValue(int loadingProgress) {
System.out.println(loadingProgress);
}
}
public class MGUI {
public final ValueAccepter pbLoading = new ValueAccepter();
}
private int loadingProgress;
private Random random;
private MGUI mGUI = new MGUI();
public static void main(String[] args) {
new Snippet().logIn();
}
public void logIn() {
try {
while (true) {
calculate();
System.out.println(loadingProgress);
if (loadingProgress < 100) {
mGUI.pbLoading.setValue(loadingProgress);
Thread.sleep(random.nextInt(5000) + 100);
} else {
mGUI.pbLoading.setValue(100);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void calculate() {
random = new Random();
loadingProgress = loadingProgress + random.nextInt(9) + 1;
}
}
I think you have a problem with your swing-threads. Make sure, that mGUI.pbLoading.setValue is returning as expected.
You have to use SwingWorker to execute graphical user interface operations and calculations otherwise the event dispatch thread won't be able to repaint. Here is a progress bar demo code by Oracle.
So my code works just the way I want it the only issue I'm having is this.. Basically I am having a main class which controls gates on a railroad track, when a train is approaching or crossing the track from either 1 of two tracks the gates should close. The only issue I'm having is the statements for when a gate opens or closes spam like 3-5 times everytime it does something so if the gate is closing it will go..
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closed
I'm wondering why this is occuring, here is my code for the Gate class and Main class
public class Gate {
private boolean isClosed = false;
private boolean closing = false;
private boolean opening = false;
public Gate(){
}
public void close(){
if(!(isClosing() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setClosing(true);
setOpening(false);
System.out.println("GATE: Closing");
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
public void open(){
if(!(isOpening() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setOpening(true);
System.out.println("GATE: Opening");
Thread.sleep(400);
setOpening(false);
if(closing == false){
setClosed(false);
System.out.println("GATE: Opened");
}
}catch(Exception ex){
}
}
};
new Thread(task, "openThread").start();
}
}
public boolean isClosed(){
return isClosed;
}
public boolean isClosing(){
return closing;
}
public boolean isOpening(){
return opening;
}
public synchronized void setClosing(boolean t){
closing = t;
}
public synchronized void setOpening(boolean t){
opening = t;
}
public synchronized void setClosed(boolean t){
isClosed = t;
}
}
public class Controller {
public static void main(String[] args){
Track t1 = new Track("Track 1");
Track t2 = new Track("Track 2");
Gate g = new Gate();
t1.simulateTrack();
t2.simulateTrack();
do{
System.out.print("");
if((t1.isApproaching() || t1.isCrossing()) || (t2.isApproaching() || t2.isCrossing())){
if(!g.isClosed() && !g.isClosing()){
g.close();
}
}else if(g.isClosed() && !g.isOpening()){
g.open();
}
}while((t1.isSimulating() || t2.isSimulating()));
}
}
Also the code for Track
import java.security.SecureRandom;
public class Track {
private static final SecureRandom gen = new SecureRandom() ;
private boolean approaching = false;
private boolean atCrossing = false;
private boolean simulating = false;
private String trackName = "";
public Track(String n){
trackName = n;
}
public void simulateTrack(){
Runnable task = new Runnable() {
public void run() {
try {
setSimulating(true);
for(int i = 0; i < 10; i++){
Thread.sleep((gen.nextInt(5000) + 2500));
setApproaching(true);
System.out.println(trackName + ": Train is now approaching.");
Thread.sleep((gen.nextInt(5000) + 3500));
setCrossing(true);
setApproaching(false);
System.out.println(trackName + ": Train is now crossing.");
Thread.sleep((gen.nextInt(1000) + 1000));
setCrossing(false);
System.out.println(trackName + ": Train has left.");
}
setSimulating(false);
} catch (Exception ex) {
}
}
};
new Thread(task, "simulationThread").start();
}
public boolean isApproaching(){
return approaching;
}
public boolean isCrossing(){
return atCrossing;
}
public boolean isSimulating(){
return simulating;
}
public synchronized void setSimulating(boolean t){
simulating = t;
}
public synchronized void setApproaching(boolean t){
approaching = t;
}
public synchronized void setCrossing(boolean t){
atCrossing = t;
}
}
This is just an idea:
By shooting the close() logic on a background thread you lose the atomicity. The main's do loop can go around 5 times before it gives up the control of the main thread and one of the "closeThread"s start executing. Don't you see multiple "GATE: Closed"s as well?
Try this (not tested, sorry):
public synchronized void close() { // added synchornized
if (!isClosing()) { // read: "if not closing"
setClosing(true); // set closing so next time close() is called it is a no op
setOpening(false); // close other loopholes so the state is correct
System.out.println("GATE: Closing");
// we're in closing state now, because the close method is almost finished
// start the actual closing sequence
Runnable task = new Runnable() {
public void run() {
try {
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
You'll need to modify open() the same way, so that the invariants are always kept. Checking and setting the closing and opening flags are mutually exclusive, that's what you get by placing synchronized on both of them.