Ich bins mal wieder vor ca 2-3h hat mein Programm noch wunderbar funktionier wie es sollte, vor ca 15min hab ich allerdings ein Problem festgestellt und zwar das die momentane Position vom Lied kontinuierlich bei 00:00 bleibt, obwohl das Lied läuft und die progressbar sich füllt.
Der Teil der für das setzen der aktuellen Position verantwortlich ist:
private Player player;
private int currentPosition;
/**
*
* @param milliseconds Time in Milliseconds which have to get formatted
* @return Returns the Milliseconds in Format HH:MM:SS
*/
public String getFileTimeFormatted(int milliseconds) {
int time = milliseconds;
int minutenZehner = 0;
int minutenEiner;
int sekundenZehner = 0;
int sekundenEiner;
int stunden, minuten, sekunden;
String gesamtLänge;
sekunden = (int) TimeUnit.MILLISECONDS.toSeconds(time);
minuten = (int) TimeUnit.MILLISECONDS.toMinutes(time);
stunden = (int) TimeUnit.MILLISECONDS.toHours(time);
sekundenEiner = sekunden;
if (sekundenEiner >= 10) {
sekundenZehner = (sekundenEiner / 10);
sekundenEiner = (sekunden - (sekundenZehner * 10));
}
minutenEiner = minuten;
if (minutenEiner >= 10) {
minutenZehner = (minutenEiner / 10);
minutenEiner = (minuten - (minutenZehner * 10));
}
if (sekundenZehner >= 6) {
sekundenZehner -= minutenEiner * 6;
}
if (stunden > 0) {
gesamtLänge = stunden + ":" + minutenZehner + minutenEiner + ":" + sekundenZehner + sekundenEiner;
} else if (minutenZehner == 0) {
gesamtLänge = "0" + minutenEiner + ":" + sekundenZehner + sekundenEiner;
} else {
gesamtLänge = minutenZehner + minutenEiner + ":" + sekundenZehner + sekundenEiner;
}
return gesamtLänge;
}
private void setCurrentPosition() {
player = Musik.player;
while (!player.isComplete()) {
currentPosition = player.getPosition();
String time = getFileTimeFormatted(currentPosition);
MusikPlayer.momentanePosition.setText(time);
System.out.println("Player position: " + player.getPosition());
}
}
// public int getCurrentPosition() {
// return currentPosition;
// }
@Override
public void run() {
setCurrentPosition();
}
}
SO, nun hab ich ein simples sout eingefügt und mal geschaut was da los ist. Also beim ersten Lied funktioniert alles wie es soll. Wenn ich allerdings in der Liste ein anderes Lied auswähle, gibt er kontinuierlich
Player position: 0
aus. aber warum? Beim ersten Lied klappt wie gesagt perfekt, aber sobald ich ein anderes auswähle, gibt er nur noch das aus. Google half auch nicht wirklich :o Hab sogr die Initialisierung vom Player in die Methode gepackt, geht trz nicht.
Aber wie gesagt, vor gut 2-3 Stunden hats noch funktioniert. Das einzige was ich verändert habe war die getMethode da unten, mit der Ich eine Play/Pause funktion realisieren wollte, aber ist alles schon auskommentiert, klappt trz nich
von ausgehend das du die conventions einhälts : “public static”
ganz böses yuyu
mach daraus normale private member und nutze getter, das sollte dein problem lösen
andernfalls wirst du nicht drum rum kommen den rest vom code zu posten
Also static muss es bleiben, muss ja mehrfach von außen den gleichen player zugegriffen werden. ansonsten müsste ich ja jedes mal nen neues Objekt erstellen… Ich meine es läuft ja, nur er gibt „0“ zurück, auch mit nem statischen getter
Naja, ich änder mal alles um, das jedes mal ein neues Objekt erzeugt wird um, vllt hilfts.
Edit: Wenn ich das mache, hagelts NullPointers und nix funzt mehr. Der Player muss static bleiben… Aber das kann doch nich das Problem sein, ich mein ja beim ersten Lied klappts ja, aber sobald ich ein anderes auswähle, funzt es nicht mehr und es kommt nur ne 0 zurück.
Das Problem ist, wenn ich es nicht static mache, wie soll ich bitteschön von außen auf den Player zugreifen? Ich ahb in jeder Klasse ein private Player player = new Musik().getPlayer()
reingemacht, was zur Folge hatte das jedesmal ein anderer Player genommen wurde in jeder Klasse, es soll aber immer der selbe genommen werden, deswegen das static, dafür ist static doch da oder etwa nicht?
Edit: Okay, ich kann ihn nicht static machen, aber nur wenn ich in Musik ein neues final Objekt instanziiere:
Und dann so auf die Methoden zugreife: Musik.getINSTANCE().getPlayer();
Also wenn ich das richtig verstehe, willst du überall ein gleiches Player Objekt? … Dann kannst du dir doch irgendwo ein Player- Objekt erzeugen und die Referenz an die Klassen geben, die es brauchen.
Ansonsten kannst du dir auch mal Singleton- Pattern anschauen:
Aber das wird auch von vielen als AntiPattern gesehen, ich wollte es nur mal erwähnt haben
[QUOTE=Schesam]Das ist doch das, was ich als letztes gemacht hab oder etwa nicht?^^ Hab das auch vom Singleton abgekuckt :)[/QUOTE]Darf man fragen, wieviele Methoden das Singleton “Musik” hat? Wenn es sich dabei nur um eine (“getPlayer()”) handelt und dieser Player immer der selbe sein soll, brauchst du “Musik” gar nicht. Dann wäre es besser, den Player selbst als Singleton zu implementieren.
Allerdings kommst du damit mit an Sicherheit grenzender Wahrscheinlichkeit schnell in die Bredullie, dass du keine verschiedenen Sounds parallel abspielen kannst. SoundClips sollten jeder für sich in einem eigenen Thread laufen oder an eine ständig laufende SoundRenderPipeline (Mixer) übergeben werden.
so wie es aussieht hast du mehr als nur fehlendes wissen was STATIC wirklich bedeutet, ich gehe eher davon aus das dein gesamtes projekt einen (oder gleich mehrere) schweren designfehler hat
wie ich es bereits erwähnte macht STATIC wirklich nur bedingt sinn, und es ist ganz sicher nicht die aufgabe von static dafür zu sorgen das man von überall auf EIN objekt zugreifen kann
und selbst ein singleton ist dieser aufgabe nicht immer gewachsen wenn es nicht korrekt implementiert wird (stichwort thread-safety)
wie würde ich dein projekt angehen
ich würde in MAIN erstmal die notwendigen instanz der klassen erzeugen die ich brauche, und zwar in der logischen reihenfolge
wenn jetzt klasse D auf irgendwas aus klasse A zugreifen muss, dann mache ich das field in A ganz sicher nicht public static sondern übergebe D einfach die instanz von A und über diese kann sich D dann das member holen, alles ohne static
ich würde mir wirklich mal gerne das gesamte projekt angucken
vermutlich hast du noch probleme OOP korrekt anzuwenden
Um genau zu sein wollte ich den Player erstmal soweit fertigstellen, bis auf 1,2 Bugs die im Moment noch herrschen ist er auch soweit fertig. Ich hab schon vor dem Thread hier viel static weggemacht. Allerdings gibts beim Rest nur Probleme.
Ich bin noch am Versuchen das ganze irgendwie umzusetzten und btw. Musik hat ein bissl mehr als nur die Methode und ist auch kein ganzes Singleton, da es noch einen public Konstruktor hat, der auch gebraucht wird.
Aber ich bin noch am lernen und ausprobieren, für mich ist schon das ganze Programm ein Erfolg
Wer das Projekt ansehen will, im Anhang ist der src Ordner von Netbeans
Edit: Hab jetzt mal alles aufs Singleton-Prinzip umgesetzt und dabei einen Bug gefixt, der mich davor tierisch aufgeregt hatte, welch Ironie^^ Gibt auch kein static mehr, außer das für die Instanz-Variablen und deren Getter, auch wenn eine nicht final ist, da der Compiler es nicht zulässt, mach ichs trotzdem außerhalb der main, ist das Default Look And Feel nicht gesetzt
Aber danke schon mal für die Hilfe
Ach und @Spacerat : das ganze ist ein Musikplayer, der soll nur ein Lied gleichzeitig abspielen mehrere gleichzeitig würden nur bei Spielen oä Sinn machen
[QUOTE=Schesam]Ach und @Spacerat : das ganze ist ein Musikplayer, der soll nur ein Lied gleichzeitig abspielen mehrere gleichzeitig würden nur bei Spielen oä Sinn machen[/QUOTE]Das mag stimmen… Aber eigentlich wäre es dann doch sinnig, wenn ein Sound die Methoden „start()“, „stop()“, „getDuration()“, „getTimeDurated()“ und evtl. „pause(boolean on)“ hätte und nicht der Player. So müsste man sich keine Gedanken mehr darum machen, ob die Anwendung nur einen oder gleich mehrere Sounds zugleich spielen kann.
@Spacerat : Und wie soll ich das anstellen? den Player in eine neue Klasse tun und per Konstruktor bei jeder Erzeugung ein neues Player-Objekt erstellen und die FUnktionen des Players (getDuration, start/stop, usw.) als eigene Methode implementieren, wo ich bei start beispielsweise einfach nur player.play() aufrufe?
@Den Unregistrierten: Hab ihn hier nochmal, aber bitte keine Kommentare zu meinem Englisch in der Doc
Also ich mach das in meiner DT_Lib zumindest so. Ich habe eine Klasse (bzw. Interface) Listenable:
void addMediaEventListener(MediaEventListener mel);
void removeMediaEventListener(MediaEventListener mel);
AudioFormat getFormat();
ScopeBuffer getScopeBuffer();
long getDurationTime();
long getTimeDurated();
long getTimeDurated(boolean remaining);
void start();
void stop();
void reset();
void pause();
void pause(boolean sw);
boolean isPaused();
boolean isStarted();
}```Ein Player muss nun nur noch die Audiodatei laden, in ein solches Listenable umwandeln, darin einen Listener registrieren (Events: START, STOP, PAUSE und UPDATE), das Listenable starten (evtl. per ActionListener) und dann schlicht warten (Attention! Never do "wait()" in EDT!), bis das Listenable einen STOP-Event dropped. Jedes "<Listenable>.start()" erstellt einen neuen Thread, sofern noch nicht gestartet wurde und jedes "<Listenable>.stop()" unterbricht und löscht diesen wieder, sofern gestartet wurde. Dieser Thread sorgt für das spoolen des Streams in die Audiopipeline und wirft dabei UPDATE-Events um z.B. die ScopeBuffer neu zu zeichnen. Ist der Stream zu Ende folgt ein STOP-Event, welcher vom Player abgefangen werden kann und somit wieder geweckt werden kann.
Hier bei pastebin. @Spacerat : Okay, hab zwar nur die Hälfte verstanden (Das interface hab ich verstanden, den Text darunter aber nur halbwegs) aber ich weiß ungefähr was du damit sagen wolltest. Zum Umsetzen fehlt mir dazu das Verständnis, was du mir damit sagen willst^^
sorry, aber bei mir hats mit main() und dem constructor schon aufgehört mit dem willen
du hast im constructor schon stehen “nextSong()”, und erst DANACH folgt das “setVisible()”
alleine rein logisch schon totaler unfug
klar kann man es schon so sehen das es zur erzeugung des objektes gehört seine GUI selbst aufzubauen, aber ganz sicher nicht die logik die dann schon den nächsten track startet
das gehört raus in main
ansonsten : GUI-builder ftw, aber ganz schönen müll den er gemacht hat, vor allem mit dem halbherzigen i18n versuch
da musst du wirklich noch so einiges überarbeiten, will gar nicht wissen wie der rest aussieht
ehm wieso unlogisch? Die Methode setzt ganz einfach nur das Icon, wenn der player noch nicht läuft…
nextSongButton.setIcon(getNextSongIcon());
if (Musik.getINSTANCE().getPlayer() != null) {
if (!Musik.getINSTANCE().getPlayer().isComplete()) {
Musik.getINSTANCE().getPlayer().close();
}
}
}```
Hab ich halt in die Methode reingeschrieben und die dann im Konstruktor aufgerufen, also alles schon ok. Hätt auch einfach die erste Zeile im Konstruktor reinschreiben können....
Und das mit dem GUI-Builder hab ich schon im Titel reingeschrieben, finde den Code ja selber nicht toll, aber ich hatte schon 2 GUIs händisch (Ich sags einfach mal so :P) geschrieben und wollte den mal ausprobieren, da ich zudem keine Lust hatte, mich nochmal ne Woche allein um die GUI zu kümmern :P In meinen nächsten Projekten werde ich den auch nicht mehr benutzen.
Soviel dazu :P