I have a very basic version of a media player built using JavaFX. The project is well segregated and has a different packages for controllers, utils and supporter classes.
My project follows the MVC pattern and it contains the following important parts:
- All the views are in FXML files.
- These views have dedicated controllers for them, all inside the
com.ita.controllerpackage. - Some custom controls / dialogs inside the
com.ita.uipackage. - Utility classes inside the
com.ita.util. - The
Mainclass extendsApplicationand is the entry point. It is also responsible for invocation and loading the views into the stage.
Main.java
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/ita/fxml/mediaplayer.fxml"));
BorderPane pane = loader.load();
Scene scene = new Scene(pane, 650, 400);
primaryStage.setScene(scene);
MediaPlayerController controller = ((MediaPlayerController) loader.getController());
// Load Playlist FXML and inject controller/root
FXMLLoader playListLoader = new FXMLLoader(getClass().getResource("/com/ita/fxml/playlist.fxml"));
playListLoader.load();
controller.injectPlayListController((PlaylistController) playListLoader.getController());
controller.injectPlayListRoot(playListLoader.getRoot());
bindSize(controller, scene);
controller.setStage(primaryStage);
primaryStage.show();
controller.applyDragAndDropFeatures(scene);
}
private void bindSize(MediaPlayerController controller, Scene scene){
controller.timerSliderWidthProperty().bind(scene.widthProperty().subtract(500));
controller.mediaViewWidthProperty().bind(scene.widthProperty());
controller.mediaViewHeightProperty().bind(scene.heightProperty().subtract(70));
}
public static void main(String[] args) {
launch(args);
}
}
PlaylistController.java
public class PlaylistController implements Initializable {
@FXML
private Button add;
@FXML
private Button delete;
@FXML
private ListView playList;
private ObservableList playListFiles =FXCollections.observableArrayList();
private ObjectProperty<Path> selectedMedia = new SimpleObjectProperty<>();
private ObjectProperty<Path> deletedMedia = new SimpleObjectProperty<>();
@Override
public void initialize(URL location, ResourceBundle resources) {
playList.setOnMouseClicked((click) -> {
if (click.getClickCount() == 2) {
if (playList.getSelectionModel().getSelectedItem() != null) {
selectedMedia.setValue((Path) playList.getSelectionModel().getSelectedItem());
}
}
});
}
@FXML
void add(ActionEvent event) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Files",
PropertiesUtils.readFormats()));
List<Path> listOfFiles = new ArrayList<Path>();
listOfFiles = FileUtils.convertListFiletoListPath(chooser.showOpenMultipleDialog(((Button) event.getSource()).getScene().getWindow()));
if (listOfFiles != null) {
listOfFiles.stream().forEach(System.out::println);
listOfFiles.stream().forEach(playListFiles::add);
playListFiles.stream().forEach(System.out::println);
playList.setItems(playListFiles);
}
}
@FXML
void delete(ActionEvent event) {
if (playList.getSelectionModel().getSelectedItem() != null) {
if(null!=playListFiles || !playListFiles.isEmpty()) {
deletedMedia.setValue((Path) playList.getSelectionModel().getSelectedItem());
playListFiles.remove(playList.getSelectionModel().getSelectedItem());
playList.setItems(playListFiles);
}
}
}
public ObservableList listViewItems(){
return playListFiles;
}
public ObjectProperty<Path> selectedFile(){
return selectedMedia;
}
public ObjectProperty<Path> deletedFile() {
return deletedMedia;
}
}
PropertiesUtils.java
public class PropertiesUtils {
public static Map<String, String> readDetails()
{
Map<String, String> map = new HashMap<String, String>();
try{
InputStream in = PropertiesUtils.class.getClassLoader().getResourceAsStream("details.properties");
Properties p = new Properties();
p.load(in);
map.put("name", p.getProperty("name"));
map.put("version", p.getProperty("version"));
map.put("link", p.getProperty("link"));
}
catch (Exception e) {
e.printStackTrace();
}
return map;
}
public static List<String> readFormats()
{
List<String> formats = null;
try
{
InputStream in = PropertiesUtils.class.getClassLoader().getResourceAsStream("details.properties");
Properties p = new Properties();
p.load(in);
formats = Arrays.asList(p.getProperty("formats").split(","));
}
catch (Exception e) {
e.printStackTrace();
}
return formats;
}
}
I wanted to add more functionality into the project, but before doing that I just wanted to know if my code follows:
- Code standards that an open source project should. I am aware of the fact that proper documentation is missing, and I am working on the same.
- Naming conventions.
- Coupling. I have got some reviews that my code is very tightly coupled. If you have the same view, please write some suggestions on how to overcome it.
- Am I writing the utility classes as they should be written? Mostly, the method definitions and declaring them static.