Continuously update TextArea - concurrency

I'm writing a program that creates a process using youtube-dl. That process has two InputStreams (inputStream and errorStream) of which I want to reroute each into a text area.
I've been trying to get the TextAreas to update without locking the JavaFX thread. It's working but I feel like it's terribly inefficient as it creates a large number of Task objects that only append a line. I've recreated the code I've been using below, using List<String> instead of BufferedReader to simplify the problem a bit.
When I press the button it will create two threads, one for each list, with an UpdateTask. The UpdateTask then creates a WriteTask gives it to Platform.runLater() which places it on the JavaFX thread again.
Surely there must be a better way to do this?
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
public class ConcurrentTest extends VBox{
TextArea output;
TextArea error;
Button start;
TextField writable;
public ConcurrentTest(){
// Init components
output = new TextArea();
output.setEditable(false);
error = new TextArea();
error.setEditable(false);
// Init button
start = new Button("Print stuff");
start.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
List<String> outputLines = Arrays.asList("A", "B", "C", "D");
List<String> errorLines = Arrays.asList("A", "B", "C", "D");;
Thread outputThread = new Thread(new UpdateTask<String>(output, outputLines));
outputThread.setDaemon(true);
outputThread.start();
Thread errorThread = new Thread(new UpdateTask<String>(error, errorLines));
errorThread.setDaemon(true);
errorThread.start();
}
});
writable = new TextField();
writable.setPromptText("Write while some text areas are getting updated.");
// Add components
this.getChildren().addAll(output, error, start, writable);
}
// UPDATE TASK CLASS
public class UpdateTask<V> extends Task<V>{
TextArea target;
Iterator<String> it;
public UpdateTask(TextArea target, List<String> lines){
this.target = target;
it = lines.iterator();
}
#Override
protected V call() throws Exception {
while(it.hasNext()){
Thread.sleep(1500); // Time to type something to test
Platform.runLater(new WriteTask<String>(target, it.next()));
}
return null;
}
}
// WRITE TASK CLASS
public class WriteTask<V> extends Task<V>{
TextArea target;
String line;
public WriteTask(TextArea target, String line) {
this.target = target;
this.line = line;
}
#Override
protected V call() throws Exception {
target.appendText(line + "\n");
return null;
}
}
}
For the entire program, the launcher with main:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class ConcurrentTestLauncher extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = new ConcurrentTest();
Scene scene = new Scene(root);
primaryStage.setTitle("Concurrent FX Test");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

Related

Java FX: Getting and editing an object from Observable List

I know about the method list.getSelectionModel().getSelectedItem(); and its index version, but heres my problem:
I have setup a List in my GUI which holds Objects of a class Person. In my GUI theres also Text Fields with the attributes of that class (Name,Street,Age etc).
What I did so far is implement a method clickList() which will fill the attribute fields with the data from the selected object in the listview. So the user can edit them from here and press another button which should then update those attributes.
I also setup so you can create a new object from the text form by doing this inside my "OK" Button inside my Controller:
ObservableList<Person> items = FXCollections.observableArrayList();
items.add(new Person(tf_vn.getText(), tf_nn.getText(),tf_strasse.getText(), tf_plz.getText(), tf_ort.getText(),genderChoice, sliderAge.getValue());
list.setItems(items);
However what im struggling with is the editing of the already existing Person. Can someone give me some pointers? I know I can get the selected object index but how do I work with it? Basicly I just need to find a way to do something like selectedObject.setAge(),selectedObject.setName() etc
I looked through all the getSelectionModel() methods but didnt find a solution, im sure there is a easy one....
Thanks in advance !
This way you can reach selectedObject's methods
ListView<Person> l = new ListView<>();
...
l.getSelectionModel().getSelectedItem().setFirstName("new name");
l.refresh();
a full example may look like;
package so;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith#example.com"),
new Person("Isabella", "Johnson", "isabella.johnson#example.com"),
new Person("Ethan", "Williams", "ethan.williams#example.com"),
new Person("Emma", "Jones", "emma.jones#example.com"),
new Person("Michael", "Brown", "michael.brown#example.com"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
// table.setEditable(true);
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final TextField addFirstName = new TextField();
addFirstName.setPromptText("First Name");
addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
final TextField addLastName = new TextField();
addLastName.setMaxWidth(lastNameCol.getPrefWidth());
addLastName.setPromptText("Last Name");
final TextField addEmail = new TextField();
addEmail.setMaxWidth(emailCol.getPrefWidth());
addEmail.setPromptText("Email");
final Button addButton = new Button("Add");
addButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
if (table.getSelectionModel().getSelectedItem() != null) {
table.getSelectionModel().getSelectedItem().setFirstName(addFirstName.getText());
table.getSelectionModel().getSelectedItem().setLastName(addLastName.getText());
table.getSelectionModel().getSelectedItem().setEmail(addEmail.getText());
table.refresh();
} else {
data.add(new Person(addFirstName.getText(), addLastName.getText(), addEmail.getText()));
addFirstName.clear();
addLastName.clear();
addEmail.clear();
}
}
});
table.getSelectionModel().selectedItemProperty().addListener((e, o, n) -> {
// addFirstName.clear();
// addLastName.clear();
// addEmail.clear();
if (n != null) {
addFirstName.setText(n.getFirstName());
addLastName.setText(n.getLastName());
addEmail.setText(n.getEmail());
addButton.setText("Edit");
}
else {
addButton.setText("Add");
}
});
hb.getChildren().addAll(addFirstName, addLastName, addEmail, addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}

JavaFX tableview, my list is erased when I add a new object

I've got an issue with Tableview in JavaFX.
Whenever I add a new row in my Tableview my list is deleted.
I pre-make a list with 4 objects in it
When i use my button to add a row, the row is added.
The thing is when the row is added. If I had text in one of my cell, all is erased.
Here's my main program :
package application;
import vue.*;
import domaine.Reponse;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class Mainfx extends Application {
public static final String nomApplication = "QCM-Builder";
private TableViewReponse tableauReponse;
private Button addButton;
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage){
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(300);
stage.setHeight(500);
tableauReponse = new TableViewReponse();
tableauReponse.setTranslateX(130);
tableauReponse.setTranslateY(300);
tableauReponse.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tableauReponse.setPrefHeight(150);
addButton = new Button("Add");
addButton.setTranslateX(400);
addButton.setTranslateY(400);
((Group) scene.getRoot()).getChildren().addAll(addButton);
addButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
ObservableList<Reponse> list = tableauReponse.getItems();
list.add(new Reponse("",false));
tableauReponse.setItems(list);
}
});
((Group) scene.getRoot()).getChildren().addAll(tableauReponse);
stage.setScene(scene);
stage.show();
}
}
And here's my custom Tableview
package vue;
import java.io.IOException;
import java.sql.SQLException;
import domaine.Reponse;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
public class TableViewReponse extends TableView<Reponse> {
private TableColumn<Reponse, String> reponseCol;
private TableColumn<Reponse, Boolean> singleCol;
private final ObservableList<Reponse> list =
FXCollections.observableArrayList(
new Reponse("",false),
new Reponse("",false),
new Reponse("",false),
new Reponse("",false)
);
public TableViewReponse() {
super();
this.setEditable(true);
reponseCol = new TableColumn<Reponse, String>("RĂ©ponse");
singleCol = new TableColumn<Reponse, Boolean>("Correcte ?");
// ==== FULL NAME (TEXT FIELD) ===
reponseCol.setCellValueFactory(new PropertyValueFactory<Reponse, String>("reponse"));
reponseCol.setCellFactory(TextFieldTableCell.<Reponse>forTableColumn());
reponseCol.setMinWidth(200);
// On Cell edit commit (for FullName column)
reponseCol.setOnEditCommit((CellEditEvent<Reponse, String> event) -> {
TablePosition<Reponse, String> pos = event.getTablePosition();
int row = pos.getRow();
Reponse reponse = event.getTableView().getItems().get(row);
reponse.setLibelle(event.getNewValue());
try {
System.out.println("Bisous "+ reponse.toStringAMC());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
// ==== SINGLE? (CHECK BOX) ===
singleCol.setCellValueFactory(new Callback<CellDataFeatures<Reponse, Boolean>, ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(CellDataFeatures<Reponse, Boolean> param) {
Reponse reponse = param.getValue();
SimpleBooleanProperty booleanProp = new SimpleBooleanProperty(reponse.estJuste());
// Note: singleCol.setOnEditCommit(): Not work for
// CheckBoxTableCell.
// When "Single?" column change.
booleanProp.addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
reponse.setJuste(newValue);
}
});
return booleanProp;
}
});
singleCol.setCellFactory(new Callback<TableColumn<Reponse, Boolean>, TableCell<Reponse, Boolean>>() {
#Override
public TableCell<Reponse, Boolean> call(TableColumn<Reponse, Boolean> p) {
CheckBoxTableCell<Reponse, Boolean> cell = new CheckBoxTableCell<Reponse, Boolean>();
cell.setAlignment(Pos.CENTER);
//cell.commitEdit(true);
return cell;
}
});
this.setItems(list);
this.getColumns().addAll(reponseCol, singleCol);
StackPane root = new StackPane();
root.setPadding(new Insets(5));
}
public void ajouterReponse() {
ObservableList<Reponse> list = this.getItems();
list.add(new Reponse("", false));
this.setItems(list);
}
public String getColReponse(int i) {
return reponseCol.getTableView().getItems().get(i).getLibelle();
}
public void viderColReponse(int i) {
reponseCol.getTableView().getItems().get(i).setLibelle(null);
}
public Boolean getColSingle(int i) {
return this.singleCol.getCellData(i);
}
}
Any ideas why ?
Thanks by advance
As you didn't show your Reponse class i can only assume but i think the problem may come from the mismatch cause by
reponseCol.setCellValueFactory(new PropertyValueFactory<Reponse, String>("reponse"));
and the fact you are doing:
reponseCol.setOnEditCommit((CellEditEvent<Reponse, String> event) -> {
//Some code
reponse.setLibelle(event.getNewValue());
//the rest
});
Assuming you are using the common naming system for setter/getter your Reponse
class shoud have a libelle field that you are updating on commiting the cell.
On the other side you are telling the column to search the value to display in a property named reponse (maybe another field of your class?).
Your are updating a different value than the one your ask to display on automatic refresh, that's why the column is clear when your add a new one.
To fix it you can either do:
reponseCol.setCellValueFactory(new PropertyValueFactory<Reponse, String>("libelle"));
to display the libelle or update the reponse field on commit instead.

Implement my own Class Loader

I 'm trying to Implement my own Class Loader which is must be transparency for application, And NoClassDefError error still occurs.
here is my Custom Class Loader:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class CustomClassLoader extends ClassLoader{
public CustomClassLoader(ClassLoader parent) {
super(parent);
}
public Class loadClass(String name) throws ClassNotFoundException {
System.out.print(name);
if(!"MyObject".equals(name)){
System.out.println("Super load class function");
return super.loadClass(name);
}
try {
System.out.println("Go to load class function");
String url = "file:C:/Users/ahmad/Desktop/CustomClassLoader/class/MyObject.class";
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
InputStream input = connection.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int data = input.read();
while(data != -1){
buffer.write(data);
data = input.read();
}
input.close();
byte[] classData = buffer.toByteArray();
return defineClass(name, classData, 0, classData.length);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
here is my main code:
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException{
MyObjectInterface myobj = new MyObject();
System.out.println(myobj.getHelloMessage());
}
}
with -Djava.system.class.loader="CustomClassLoader" parameter for VM.
is there is any thing missed.
Thanks Alot.
You shouldn't use that system property. Try using the loadClass method and reflection Object main = loader.loadClass("Main", true).newInstance(); as suggested here
What is exactly the ClassLoader instance that should be passed into the constructor?
Anyway your implementation is incorrect as you are not delegating to the parent first (which is the way how it works in Java SE).

Displaying Multiple Images on a Single Google Glass Live Card

I'm creating a live card app that recieves PNGs from a php script running on my server in response to a request from scanning QR codes. At the moment, I simply replace the image on my Live card with the PNG I recieve from the server, but I would like to recieve and display multiple images from the server with each request.
Is there an approved way to show multiple images on a live card? I was thinking there may be a possiblity of generating a menu full of images that simply closed itself when clicked, but it seems like there might be a better alternative.
This is my code at the moment:
Current Code
import com.google.android.glass.timeline.LiveCard;
import com.google.android.glass.timeline.LiveCard.PublishMode;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.IBinder;
import android.util.Base64;
import android.widget.RemoteViews;
public class iotSplashScreen extends Service {
private static final String LIVE_CARD_TAG = "iotSplashScreen";
private LiveCard mLiveCard;
private RemoteViews mLiveCardView;
public class iotBinder extends Binder {
public void changeImage(String change) {
try {
byte[] bob = Base64.decode(change, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(bob, 0, bob.length);
if(bitmap != null) {
mLiveCardView.setImageViewBitmap(R.id.image_view_id, bitmap);
mLiveCard.setViews(mLiveCardView);
}
else
{
System.out.println("Daaang, dat bitmap was null doe");
}
}
catch (IllegalArgumentException e)
{
System.out.println("Base64 had an issues: " + e);
System.out.println(change);
}
catch (NullPointerException e)
{
System.out.println("Null Pointer: " + e);
}
}
}
private final iotBinder mBinder = new iotBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mLiveCard == null) {
mLiveCard = new LiveCard(this, LIVE_CARD_TAG);
mLiveCardView = new RemoteViews(getPackageName(), R.layout.iot_splash_screen);
mLiveCard.setViews(mLiveCardView);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, LiveCardMenuActivity.class);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
mLiveCard.publish(PublishMode.REVEAL);
} else {
mLiveCard.navigate();
}
return START_STICKY;
}
#Override
public void onDestroy() {
if (mLiveCard != null && mLiveCard.isPublished()) {
mLiveCard.unpublish();
mLiveCard = null;
}
super.onDestroy();
}
}
Simply add more ImageViews, either in your layout file (iot_splash_screen) or programmatically.
With the resource IDs of your ImageViews, you can call setImageViewResource on each one.
Make sure that you are setting these images before calling setViews on your Live Card.

Jmf Mp3 files not streaming on rtp

The player mp3 gives error:
RTP Handler internal error: javax.media.ControllerErrorEvent[source=com.sun.medi
a.content.unknown.Handler#baf4ae,message=Internal module com.sun.media.BasicRend
ererModule#197f158: failed to handle a data format change!]
i m running
server as:java MediaConverterExample rtp://rajneesh-pc:49150/audio Dead_End.mp3
client as:java PlayerExample rtp://rajneesh-pc:49150/audio
this is server side code
import javax.media.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import javax.media.protocol.*;
import javax.media.format.AudioFormat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MediaConvertion
{
private MediaLocator mediaLocator = null;
private DataSink dataSink = null;
private Processor mediaProcessor = null;
private static final Format[] FORMATS = new Format[] { new AudioFormat(AudioFormat.MPEG_RTP)};
private static final ContentDescriptor CONTENT_DESCRIPTOR =new ContentDescriptor (ContentDescriptor.RAW_RTP);
public MediaConvertion(String url)throws IOException,NoProcessorException, CannotRealizeException, NoDataSinkException, NoDataSinkException
{
mediaLocator=new MediaLocator(url);
}
public void setDataSource(DataSource ds) throws IOException,NoProcessorException, CannotRealizeException, NoDataSinkException {
mediaProcessor = Manager.createRealizedProcessor(new ProcessorModel(ds, FORMATS, CONTENT_DESCRIPTOR));
dataSink = Manager.createDataSink(mediaProcessor.getDataOutput(),mediaLocator);
}
public void startTransmitting() throws IOException {
mediaProcessor.start();
dataSink.open();
dataSink.start();
}
public void stopTransmitting() throws IOException {
dataSink.stop();
dataSink.close();
mediaProcessor.stop();
mediaProcessor.close();
}
}
public class MediaConverterExample extends Frame implements ActionListener
{
Button st_stream;
static MediaConvertion mdcon;
public static void main(String args[])throws IOException,NoProcessorException, CannotRealizeException, NoDataSinkException,MalformedURLException,NoDataSourceException
{
Format input1 = new AudioFormat(AudioFormat.MPEGLAYER3);
Format input2 = new AudioFormat(AudioFormat.MPEG);
Format output = new AudioFormat(AudioFormat.LINEAR);
PlugInManager.addPlugIn(
"com.sun.media.codec.audio.mp3.JavaDecoder",
new Format[]{input1, input2},
new Format[]{output},
PlugInManager.CODEC
);
File mediaFile = new File(args[1]);
DataSource source = Manager.createDataSource(new MediaLocator(mediaFile.toURL()));
mdcon=new MediaConvertion(args[0]);
mdcon.setDataSource(source);
new MediaConverterExample();
}
public MediaConverterExample()
{
st_stream=new Button("Start Streaming");
add(st_stream);
st_stream.addActionListener(this);
setVisible(true);
setSize(200,300);
}
public void actionPerformed(ActionEvent ae)
{
try
{
mdcon.startTransmitting();
}
catch(Exception e){
}
}
}
this is client side code
import javax.media.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.format.*;
public class PlayerExample extends JFrame implements ActionListener
{
Button play;
SimpleAudioPlayer sap;
PlayerExample(String playFile) throws IOException,NoPlayerException, CannotRealizeException
{
sap=new SimpleAudioPlayer(new MediaLocator(playFile));
setLayout(new BorderLayout());
//add(sap.VideoComponent(),BorderLayout.CENTER);
//add(sap.AudioComponent(),BorderLayout.WEST);
//add(sap.ControlComponent(),BorderLayout.NORTH);
add(play=new Button("play"),BorderLayout.SOUTH);
play.addActionListener(this);
setSize(200,300);
setVisible(true);
}
public void actionPerformed(ActionEvent ae)
{
sap.play();
}
public static void main(String args[])throws IOException,NoPlayerException, CannotRealizeException
{
Format input1 = new AudioFormat(AudioFormat.MPEGLAYER3);
Format input2 = new AudioFormat(AudioFormat.MPEG);
Format output = new AudioFormat(AudioFormat.LINEAR);
PlugInManager.addPlugIn(
"com.sun.media.codec.audio.mp3.JavaDecoder",
new Format[]{input1, input2},
new Format[]{output},
PlugInManager.CODEC
);
new PlayerExample(args[0]);
}
}
class SimpleAudioPlayer {
private Player videoPlayer = null;
public SimpleAudioPlayer(MediaLocator ml) throws IOException, NoPlayerException, CannotRealizeException {
videoPlayer = Manager.createRealizedPlayer(ml);
}
public void play() {
//videoPlayer.deallocate();
videoPlayer.start();
}
public void stop() {
videoPlayer.stop();
}
public Component VideoComponent(){
return videoPlayer.getVisualComponent();
}
public Component ControlComponent(){
return videoPlayer.getControlPanelComponent();
}
public Component AudioComponent(){
return videoPlayer.getGainControl().getControlComponent();
}
}
Please help I did every thing I could. Please advise me of any other details I might be missing, server runs fine, but client blocks at player creation. The audio format I am using is MPEG_RAW. Eagerly looking for an answer, thanks in advance.
SOLVED......
i figured when looked at oracle forum
change
AudioFormat.MPEG_RTP to AudioFormat.DVI_RTP
don't ask a reason why mp3 didn't work.i did everything i could.
please tell me why previous didn't work.