Adjust SeekBar styles Implement live updatingtags/Release_1
@@ -1,21 +1,22 @@ | |||||
package de.hems.trafficsim; | package de.hems.trafficsim; | ||||
import androidx.appcompat.app.AppCompatActivity; | import androidx.appcompat.app.AppCompatActivity; | ||||
import androidx.constraintlayout.widget.ConstraintLayout; | |||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.Looper; | |||||
import android.view.View; | import android.view.View; | ||||
import android.widget.Button; | import android.widget.Button; | ||||
import android.widget.LinearLayout; | import android.widget.LinearLayout; | ||||
import android.widget.SeekBar; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import java.util.List; | |||||
import java.util.Observable; | import java.util.Observable; | ||||
import java.util.Observer; | import java.util.Observer; | ||||
public class MainActivity extends AppCompatActivity implements Observer { | |||||
public class MainActivity extends AppCompatActivity implements Observer, SeekBar.OnSeekBarChangeListener { | |||||
public static final int defaultNoOfVehicles = 25; | |||||
public static final int defaultTrackLength = 100; | |||||
public static final float defaultBrakeProb = 0.3f; | |||||
public static final float defaultMaxVelocity = 5.0f; | |||||
protected Track track; | protected Track track; | ||||
protected TimeRecordView trackView; | protected TimeRecordView trackView; | ||||
protected Worker worker; | protected Worker worker; | ||||
@@ -25,19 +26,30 @@ public class MainActivity extends AppCompatActivity implements Observer { | |||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
setContentView(R.layout.activity_main); | setContentView(R.layout.activity_main); | ||||
this.track = new Track(25, 100); | |||||
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, defaultMaxVelocity); | |||||
this.track.addObserver(this); | this.track.addObserver(this); | ||||
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | ||||
SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); | |||||
trackLengthSeekBar.setOnSeekBarChangeListener(this); | |||||
trackLengthSeekBar.setProgress(defaultTrackLength); | |||||
SeekBar maxVelocitySeekBar = (SeekBar) findViewById(R.id.maxVelocitySeekBar); | |||||
maxVelocitySeekBar.setOnSeekBarChangeListener(this); | |||||
maxVelocitySeekBar.setProgress((int)defaultMaxVelocity); | |||||
SeekBar noOfVehiclesSeekBar = (SeekBar) findViewById(R.id.noOfVehiclesSeekBar); | |||||
noOfVehiclesSeekBar.setOnSeekBarChangeListener(this); | |||||
noOfVehiclesSeekBar.setProgress(defaultNoOfVehicles); | |||||
SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); | |||||
brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); | |||||
brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); | |||||
} | } | ||||
@Override | @Override | ||||
public void update(Observable observable, Object o) { | public void update(Observable observable, Object o) { | ||||
final Track trackRef = this.track; | final Track trackRef = this.track; | ||||
//final TimeRecordView viewRef = this.trackView; | |||||
final LinearLayout viewStackRef = this.viewStack; | final LinearLayout viewStackRef = this.viewStack; | ||||
//final List<VehicleTimeRecord> newRecords = (List<VehicleTimeRecord>) o; | |||||
final MainActivity mainActivity = this; | final MainActivity mainActivity = this; | ||||
final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | |||||
final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | |||||
runOnUiThread(new Runnable() { | runOnUiThread(new Runnable() { | ||||
@Override | @Override | ||||
public void run() { | public void run() { | ||||
@@ -45,10 +57,10 @@ public class MainActivity extends AppCompatActivity implements Observer { | |||||
if (viewStackRef.getChildCount() > 0) | if (viewStackRef.getChildCount() > 0) | ||||
viewStackRef.removeViewAt(0); | viewStackRef.removeViewAt(0); | ||||
viewStackRef.addView(newTrView); | viewStackRef.addView(newTrView); | ||||
lastAvgView.setText(String.valueOf(trackRef.getLastAvg())); | |||||
overallAvgView.setText(String.valueOf(trackRef.getOverallAvg())); | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
public void onStepButtonClick(View view) { | public void onStepButtonClick(View view) { | ||||
@@ -81,5 +93,55 @@ public class MainActivity extends AppCompatActivity implements Observer { | |||||
} catch (InterruptedException ex) { | } catch (InterruptedException ex) { | ||||
} | } | ||||
this.worker = null; | |||||
} | |||||
protected void updateTrack() { | |||||
int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); | |||||
SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar)); | |||||
int newNoOfVehicles = noOfVehiclesSeekBar.getProgress(); | |||||
if (newTrackLength < newNoOfVehicles) { // Dont allow values greater than track length! | |||||
newNoOfVehicles = (int) newTrackLength; | |||||
noOfVehiclesSeekBar.setProgress(newNoOfVehicles); | |||||
} | |||||
float newMaxVelocity = ((SeekBar) findViewById(R.id.maxVelocitySeekBar)).getProgress(); | |||||
SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); | |||||
float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); | |||||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity); | |||||
this.track.addObserver(this); | |||||
if (this.worker != null) { // There was a simulation running already | |||||
this.worker.setStop(true); | |||||
try { | |||||
this.worker.join(); | |||||
} catch (InterruptedException ex) { | |||||
} | |||||
this.worker = new Worker(track); | |||||
this.worker.start(); | |||||
} | |||||
} | |||||
@Override | |||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||||
if (seekBar == (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar))) { | |||||
this.updateTrack(); | |||||
} else if (seekBar == (SeekBar)(findViewById(R.id.brakeProbabilitySeekBar))) { | |||||
float newBrakeProb = (float)seekBar.getProgress() / (float)seekBar.getMax(); | |||||
System.out.println(newBrakeProb); | |||||
this.track.setBrakeProb(newBrakeProb); | |||||
} else if (seekBar == (SeekBar)(findViewById(R.id.maxVelocitySeekBar))) { | |||||
this.track.setMaxVelocity(seekBar.getProgress()); | |||||
} else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { | |||||
this.updateTrack(); | |||||
} | |||||
} | |||||
@Override | |||||
public void onStartTrackingTouch(SeekBar seekBar) { | |||||
} | |||||
@Override | |||||
public void onStopTrackingTouch(SeekBar seekBar) { | |||||
} | } | ||||
} | } |
@@ -72,6 +72,7 @@ public class TimeRecordView extends View { | |||||
y += 10; | y += 10; | ||||
} catch (ConcurrentModificationException ex) { | } catch (ConcurrentModificationException ex) { | ||||
System.out.println("Concurrent Exception occured, skipping record"); | System.out.println("Concurrent Exception occured, skipping record"); | ||||
y += 10; | |||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
@@ -7,47 +7,67 @@ import java.util.Observable; | |||||
public class Track extends Observable { | public class Track extends Observable { | ||||
protected List<Vehicle> vehicles; | protected List<Vehicle> vehicles; | ||||
public List<List<VehicleTimeRecord>> getVtrList() { | |||||
return vtrList; | |||||
} | |||||
protected List<List<VehicleTimeRecord>> vtrList; | protected List<List<VehicleTimeRecord>> vtrList; | ||||
protected float trackLength; | protected float trackLength; | ||||
protected float sumAvgMemory; | protected float sumAvgMemory; | ||||
protected int historyLength; | |||||
protected float overallAvg; | |||||
protected float lastAvg; | |||||
protected int waitTime; | |||||
protected float maxVelocity; | |||||
protected float brakeProb; | |||||
public List<List<VehicleTimeRecord>> getVtrList() { | |||||
return vtrList; | |||||
} | |||||
public float getOverallAvg() { | |||||
return overallAvg; | |||||
} | |||||
public float getLastAvg() { | public float getLastAvg() { | ||||
return lastAvg; | return lastAvg; | ||||
} | } | ||||
protected float lastAvg; | |||||
public List<Vehicle> getVehicles() { | public List<Vehicle> getVehicles() { | ||||
return vehicles; | return vehicles; | ||||
} | } | ||||
public float getTrackLength() { | public float getTrackLength() { | ||||
return trackLength; | return trackLength; | ||||
} | } | ||||
public Track(int numberVehicles, float trackLength) { | |||||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity) { | |||||
this.trackLength = trackLength; | this.trackLength = trackLength; | ||||
this.brakeProb = brakeProb; | |||||
this.maxVelocity = maxVelocity; | |||||
this.vehicles = createVehiclesList(numberVehicles); | this.vehicles = createVehiclesList(numberVehicles); | ||||
this.vtrList = new LinkedList<>(); | this.vtrList = new LinkedList<>(); | ||||
this.sumAvgMemory = 0; | this.sumAvgMemory = 0; | ||||
this.overallAvg = 0; | |||||
this.lastAvg = 0; | this.lastAvg = 0; | ||||
this.historyLength = 25; | |||||
} | } | ||||
protected List<Vehicle> createVehiclesList(int numberVehicles){ | protected List<Vehicle> createVehiclesList(int numberVehicles){ | ||||
List<Vehicle> result = new ArrayList<>(); | List<Vehicle> result = new ArrayList<>(); | ||||
for(int i=0;i<numberVehicles;i++){ | for(int i=0;i<numberVehicles;i++){ | ||||
Vehicle vehicle = new Vehicle(i, i, 6, 0.3f, this.trackLength); | |||||
Vehicle vehicle = new Vehicle(i, i, this.maxVelocity, this.brakeProb, this.trackLength); | |||||
result.add(vehicle); | result.add(vehicle); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
public void setBrakeProb(float brakeProb) { | |||||
for (Vehicle v : this.vehicles) { | |||||
v.setBrakeProb(brakeProb); | |||||
} | |||||
} | |||||
public void setMaxVelocity(float maxVelocity) { | |||||
for (Vehicle v : this.vehicles) { | |||||
v.setMaxVelocity(maxVelocity); | |||||
} | |||||
} | |||||
public void timeElapse() { | public void timeElapse() { | ||||
for(int i=0; i<vehicles.size();i++) { | for(int i=0; i<vehicles.size();i++) { | ||||
Vehicle v = vehicles.get(i); | Vehicle v = vehicles.get(i); | ||||
@@ -73,11 +93,9 @@ public class Track extends Observable { | |||||
this.setChanged(); | this.setChanged(); | ||||
this.notifyObservers(); | this.notifyObservers(); | ||||
this.clearChanged(); | this.clearChanged(); | ||||
// try { | |||||
// Thread.sleep(125); | |||||
// } catch (InterruptedException ex) { | |||||
// | |||||
// } | |||||
try { | |||||
Thread.sleep(waitTime); | |||||
} catch (InterruptedException ex) { } | |||||
} | } | ||||
public float avg_step(int step){ | public float avg_step(int step){ | ||||
@@ -89,8 +107,9 @@ public class Track extends Observable { | |||||
} | } | ||||
protected void update_avg(){ | protected void update_avg(){ | ||||
sumAvgMemory += avg_step(vtrList.size()-1); | |||||
lastAvg = sumAvgMemory / vtrList.size(); | |||||
lastAvg = avg_step(vtrList.size()-1); | |||||
sumAvgMemory += lastAvg; | |||||
overallAvg = sumAvgMemory / vtrList.size(); | |||||
} | } | ||||
public float avg_span(int start, int end){ | public float avg_span(int start, int end){ | ||||
@@ -7,15 +7,15 @@ public class Vehicle { | |||||
protected float position; | protected float position; | ||||
protected float curVelocity; | protected float curVelocity; | ||||
protected float maxVelocity; | protected float maxVelocity; | ||||
protected float brakeProp; | |||||
protected float brakeProb; | |||||
protected float trackLength; | protected float trackLength; | ||||
public Vehicle(int id, int position, float maxVelocity, float brakeProp, float trackLength) { | |||||
public Vehicle(int id, int position, float maxVelocity, float brakeProb, float trackLength) { | |||||
this.id = id; | this.id = id; | ||||
this.position = position; | this.position = position; | ||||
this.maxVelocity = maxVelocity; | this.maxVelocity = maxVelocity; | ||||
this.brakeProp = brakeProp; | |||||
this.brakeProb = brakeProb; | |||||
this.curVelocity = 0; | this.curVelocity = 0; | ||||
this.trackLength = trackLength; | this.trackLength = trackLength; | ||||
@@ -33,6 +33,10 @@ public class Vehicle { | |||||
return maxVelocity; | return maxVelocity; | ||||
} | } | ||||
public void setBrakeProb(float brakeProb) { this.brakeProb = brakeProb; } | |||||
public void setMaxVelocity(float maxVelocity) { this.maxVelocity = maxVelocity; } | |||||
public void updateVelocity(float distanceForerunner) { | public void updateVelocity(float distanceForerunner) { | ||||
Random random = new Random(); | Random random = new Random(); | ||||
@@ -41,13 +45,13 @@ public class Vehicle { | |||||
if (curVelocity < maxVelocity) { | if (curVelocity < maxVelocity) { | ||||
curVelocity = curVelocity + 1; | curVelocity = curVelocity + 1; | ||||
} | } | ||||
if (r < brakeProp && curVelocity > 0) { | |||||
curVelocity = getCurVelocity() - 1; | |||||
if (r < brakeProb && curVelocity > 0) { | |||||
System.out.println("vehicle: "+brakeProb); | |||||
curVelocity = curVelocity - 1; | |||||
} | } | ||||
if (curVelocity > distanceForerunner) { | if (curVelocity > distanceForerunner) { | ||||
curVelocity = distanceForerunner; | curVelocity = distanceForerunner; | ||||
} | } | ||||
} | } | ||||
public void timeElapse() { | public void timeElapse() { | ||||
@@ -39,12 +39,13 @@ | |||||
android:text="Track length" /> | android:text="Track length" /> | ||||
<SeekBar | <SeekBar | ||||
android:id="@+id/seekBar3" | |||||
style="@style/Widget.AppCompat.SeekBar.Discrete" | |||||
android:id="@+id/trackLengthSeekBar" | |||||
style="@android:style/Widget.Material.SeekBar" | |||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:max="10" | |||||
android:progress="3" /> | |||||
android:max="250" | |||||
android:min="1" | |||||
android:progress="50" /> | |||||
<TextView | <TextView | ||||
android:id="@+id/textView3" | android:id="@+id/textView3" | ||||
@@ -53,11 +54,12 @@ | |||||
android:text="Number of vehicles" /> | android:text="Number of vehicles" /> | ||||
<SeekBar | <SeekBar | ||||
android:id="@+id/seekBar2" | |||||
style="@style/Widget.AppCompat.SeekBar.Discrete" | |||||
android:id="@+id/noOfVehiclesSeekBar" | |||||
style="@style/Widget.AppCompat.SeekBar" | |||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:max="10" | |||||
android:max="250" | |||||
android:min="1" | |||||
android:progress="3" /> | android:progress="3" /> | ||||
<TextView | <TextView | ||||
@@ -67,7 +69,7 @@ | |||||
android:text="Maximum velocity" /> | android:text="Maximum velocity" /> | ||||
<SeekBar | <SeekBar | ||||
android:id="@+id/seekBar4" | |||||
android:id="@+id/maxVelocitySeekBar" | |||||
style="@style/Widget.AppCompat.SeekBar.Discrete" | style="@style/Widget.AppCompat.SeekBar.Discrete" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
@@ -81,12 +83,13 @@ | |||||
android:text="Brake probability" /> | android:text="Brake probability" /> | ||||
<SeekBar | <SeekBar | ||||
android:id="@+id/seekBar5" | |||||
android:id="@+id/brakeProbabilitySeekBar" | |||||
style="@style/Widget.AppCompat.SeekBar.Discrete" | style="@style/Widget.AppCompat.SeekBar.Discrete" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:max="10" | |||||
android:progress="3" /> | |||||
android:max="20" | |||||
android:min="0" | |||||
android:progress="6" /> | |||||
</LinearLayout> | </LinearLayout> | ||||
@@ -113,10 +116,9 @@ | |||||
android:text="Average velocity (overall):" /> | android:text="Average velocity (overall):" /> | ||||
<TextView | <TextView | ||||
android:id="@+id/textView7" | |||||
android:id="@+id/avgVeloOverallView" | |||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | |||||
android:text="TextView" /> | |||||
android:layout_height="wrap_content" /> | |||||
</TableRow> | </TableRow> | ||||
<TableRow | <TableRow | ||||
@@ -130,10 +132,9 @@ | |||||
android:text="Average velocity (last step):" /> | android:text="Average velocity (last step):" /> | ||||
<TextView | <TextView | ||||
android:id="@+id/textView8" | |||||
android:id="@+id/avgVeloLastView" | |||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | |||||
android:text="TextView" /> | |||||
android:layout_height="wrap_content" /> | |||||
</TableRow> | </TableRow> | ||||