Make list of non public class - java

I have a java file in which I have two classes in which one is public and another is default like this -
import java.util.List;
public class TaskAnswers {
private float ratings;
private List<Image> imageList;
public float getRatings() {
return ratings;
}
public void setRatings(float ratings) {
this.ratings = ratings;
}
public List<Image> getImageList() {
return imageList;
}
public void setImageList(List<Image> imageList) {
this.imageList = imageList;
}
}
class Image {
private String image;
private String caption;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this.caption = caption;
}
}
I want to make a list of Image class type in another class. And when we write like this than that java file is called as what?

Java only allows one public class per source file. Try making the Image class public and you will get compiler errors. You need to call the file TaskAnswers.java since it is a requirement that the name of the source file match the name of the public class contained in that file.
As user #NwDx mentioned the Image class is package protected, which means you will only be able to instantiate it from other Java classes that share the same package. If you need to access the Image class in a separate package, it would be a better design choice to move it into its own public class file rather than making it an inner class.
And the code example you posted in your original problem looks just fine.

If you need the class Image in other packages, you have to make it public, but in this case you need to move it to an inner class of TaskAnswers or make an own class (file).
public class TaskAnswers {
private float ratings;
private List<Image> imageList;
public float getRatings() {
return ratings;
}
public void setRatings(float ratings) {
this.ratings = ratings;
}
public List<Image> getImageList() {
return imageList;
}
public void setImageList(List<Image> imageList) {
this.imageList = imageList;
}
public static class Image {
private String image;
private String caption;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this.caption = caption;
}
}
}
For more information please look in the Java Nested Classes Tutorial

Image class is called as utility class and TaskAnswers is called as functionality implementation class you can use it in following manner and you are using the concept of high cohesion
List<Image> list = new ArrayList<Image>();

Related

Bridge design pattern implementation

I have created one example for bridge design pattern. is it correct way to implement this or there is something I missed it?
Scenario : there is abstraction class Home which have abstract method paint implement by concreate classes(Flat and Apartment) and paint is another abstract class which having abstract method of paint(to paint the house). and one enum for color pickup.
abstract class Home {
private String homeType;
private Paint paint;
public Home(String type, Paint paint) {
this.homeType = type;
this.paint = paint;
}
abstract void paintTheHome();
public String getHomeType() {
return homeType;
}
public Paint getPaint() {
return paint;
}
}
public class Flat extends Home{
public static final String Type="Flat";
public Flat(Paint paint) {
super(Type,paint);
}
#Override
void paintTheHome() {
getPaint().paint(this);
}
}
public class Apartment extends Home {
public static final String Type="Apartment";
Apartment(Paint paint){
super(Type,paint);
}
#Override
void paintTheHome() {
getPaint().paint(this);
}
}
public abstract class Paint {
private Color color;
private String brand;
public Paint(Color color, String brand) {
this.color=color;
this.brand = brand;
}
public Color getColor() {
return color;
}
public String getBrand() {
return brand;
}
abstract void paint(Home home);
}
public class AsianPaint extends Paint{
public static final String brand = "Asian Paint";
public AsianPaint(Color color) {
super(color,brand);
}
#Override
void paint(Home home) {
System.out.println("Painting Started for "+home.getHomeType());
System.out.println("Brand of Color"+this.getBrand());
System.out.println("Name of Color"+this.getColor());
System.out.println("painting Ended");
}
}
public class ShalimarPaint extends Paint{
public static final String brand = "Shalimar Paint";
public ShalimarPaint(Color color) {
super(color,brand);
}
#Override
void paint(Home home) {
System.out.println("Painting Started for "+home.getHomeType());
System.out.println("Brand of Color"+this.getBrand());
System.out.println("Name of Color"+this.getColor());
System.out.println("painting Ended");
}
}
public enum Color {
RED("Red"),
GREEN("Green"),
BLUE("Blue"),
WHITE("White"),
YELLOW("Yellow");
String colorName;
Color(String string) {
this.colorName = string;
}
String getColor(){
return colorName;
}
}
public class client {
public static void main(String[] args) {
Home home = new Apartment(new AsianPaint(Color.RED));
home.paintTheHome();
home = new Flat(new ShalimarPaint(Color.GREEN));
home.paintTheHome();
}
}

Get reference of the object from a separate class

Currently, there are 3 classes which are not inheriting to each other. Each class has a property in it that references to an instance of another class as below.
import java.util.ArrayList;
class Region {
private Directory areaDirectory;
public Region() {
areaDirectory = new Directory();
}
public Directory getAreaDirectory() {
return areaDirectory;
}
public void setAreaDirectory(Directory areaDirectory) {
this.areaDirectory = areaDirectory;
}
}
class Directory {
private ArrayList<Area> areaList;
public Directory() {
areaList = new ArrayList<>();
}
public ArrayList<Area> getAreaList() {
return areaList;
}
public void setAreaList(ArrayList<Area> areaList) {
this.areaList = areaList;
}
public Area addNewArea(){
Area area = new Area();
return area;
}
}
class Area {
private String Name;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public Region getAreaRegion() {
// This returns a new region but need the region it was created in
return new Region();
}
}
public class Scratch {
public static void main(String args[]) {
Region r = new Region();
Area a = r.getAreaDirectory().addNewArea();
a.setName("Demo");
//See getAreaRegion() method in Area class
System.out.println(a.getAreaRegion());
}
}
How to implement a method like getAreaRegion() such that it returns the region object r? How to setup inheritance in this example to get parent objects?
I have understood the business logic which you want to describe with codes as below:
There is a region. Every region has a directory. And every directory has an area.
In this case I think it would be nice if :
Region class holds reference to Directory field;
And Directory class also has reference for its own Region;
Directory class holds reference to Area field;
And Area class also has reference for its own Directory.
Then we can create classes in following way:
1.Region class
public class Region {
private Directory directory;
public Directory getDirectory() {
return directory;
}
public void setDirectory(Directory directory) {
this.directory = directory;
}
}
2.Directory class
class Directory{
private Region region;
private Area area;
public Region getRegion() {
return region;
}
public void setRegion(Region region) {
this.region = region;
}
public Area getArea() {
return area;
}
public void setArea(Area area) {
this.area = area;
}
}
3.Area class
class Area{
private Directory directory;
private String Name;
public Directory getDirectory() {
return directory;
}
public void setDirectory(Directory directory) {
this.directory = directory;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
So we can get region of area as following:
area.getDirectory().getRegion();
I think this shows business logic better and simply. Hope it would be helpful for someone:)

Using POJOs as model layer in JavaFX application

I'm creating simple JavaFX application. I want my model layer to be completely independent from JavaFX - no StringProperty, IntegerProperty and etc. as fields. I want it to be POJO. Main reason to do so is that I want it to be Serializable.
I've created DataRepository - simple CRUD-like interface and some implementations of it, so I can at anytime change where I store my data - XML file, SQLite database or anything else. I also have to somehow connect my data storage with JavaFX (to display its content in TableView), so I decided to create my implementation of ObservableList which wraps my repository. My question is - is there any other way? ObservableList contains about 30 methods to implement and it looks like I'm doing something wrong.
My (simplified) model:
public class Movie implements Serializable {
private String title;
private String director;
public Movie() {
}
public Movie(String title, String director) {
this.title = title;
this.director = director;
}
// Getters and setters, equals etc...
}
MovieRepository:
public interface MovieRepository {
public void add(Movie movie);
public void remove(String title);
public void remove(int index);
public Movie get(String title);
public Movie get(int index);
public List<Movie> getAll();
}
Controller for my main view:
public class MainController {
#FXML
private TableView<Movie> movieTable;
#FXML
private TableColumn<Movie, String> movieTitleColumn;
#FXML
private Label titleLabel;
private MovieRepository movies = new DBMovieRepository(); //MovieRepository implementation which uses SQLite DB to store data
private MainApp app;
#FXML
private void initialize() {
movieTable.setItems(new ObservableMovies(movies));
// ObservableMovies is my implementation of ObservableList
// It basically wraps methods from MovieRepository
// and notifies listeners
showMovieDetails(null);
movieTitleColumn.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getTitle()));
movieTable.getSelectionModel().selectedItemProperty()
.addListener((observable, oldValue, newValue) -> showMovieDetails(newValue));
}
private void showMovieDetails(Movie movie) {
if(movie != null) {
titleLabel.setText(movie.getTitle());
} else {
titleLabel.setText("");
}
}
#FXML
private void handleNew() {
Movie movie = new Movie();
app.showNewMovieDialog(movie);
movieTable.getItems().add(movie);
}
public void setApp(MainApp app) {
this.app = app;
}
}
You have a couple of options here (maybe more), which are covered in other questions on this site. However, for convenience, I'll summarize them here too.
1. Use JavaFX Properties and make the class Serializable
You can do this with a custom serialized form. Make the JavaFX properties transient and implement readObject and writeObject to store the values they wrap:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Objects;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Movie implements Serializable {
private transient StringProperty title = new SimpleStringProperty();
private transient StringProperty director = new SimpleStringProperty();
public Movie() {
}
public Movie(String title, String director) {
setTitle(title);
setDirector(director);
}
#Override
public int hashCode() {
return Objects.hash(getDirector(), getTitle());
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Movie other = (Movie) obj;
return Objects.equals(getTitle(), other.getTitle())
&& Objects.equals(getDirector(), other.getDirector());
}
public final StringProperty titleProperty() {
return this.title;
}
public final String getTitle() {
return this.titleProperty().get();
}
public final void setTitle(final String title) {
this.titleProperty().set(title);
}
public final StringProperty directorProperty() {
return this.director;
}
public final String getDirector() {
return this.directorProperty().get();
}
public final void setDirector(final String director) {
this.directorProperty().set(director);
}
private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
s.defaultReadObject();
title = new SimpleStringProperty((String) s.readObject());
director = new SimpleStringProperty((String) s.readObject());
}
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeObject(getTitle());
s.writeObject(getDirector());
}
}
2. Use a POJO with "bound properties".
See JavaBean wrapping with JavaFX Properties for details. In brief:
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Movie {
private String title ;
private String director ;
private final PropertyChangeSupport propertySupport ;
public Movie(String title, String director) {
this.title = title ;
this.director = director ;
this.propertySupport = new PropertyChangeSupport(this);
}
public Movie() {
this("", "");
}
public String getTitle() {
return title ;
}
public String setTitle(String title) {
String oldTitle = this.title ;
this.title = title ;
propertySupport.firePropertyChange("title", oldTitle, title);
}
// similarly for director...
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
// hashCode and equals...
}
For wanting to wrap your repository as an observable list, instead wrap it with a repository implementation that uses an observable list:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class ObservableMovieRepository implements MovieRepository {
private final MovieRepository repository ;
private final ObservableList<Movie> movieList;
public ObservableMovieRepository(MovieRepository repository) {
this.repository = repository ;
this.movieList = FXCollections.observableArrayList(repository.getAll());
}
#Override
public void add(Movie movie) {
repository.add(movie);
movieList.add(movie);
}
#Override
public void remove(String title) {
Movie movie = get(title);
repository.remove(title);
movieList.remove(title);
}
#Override
public void remove(int index) {
repository.remove(index);
movieList.remove(index);
}
#Override
public Movie get(String title) {
return repository.get(title);
}
#Override
public Movie get(int index) {
return movieList.get(index);
}
#Override
public ObservableList<Movie> getAll() {
return movieList ;
}
}
This uses the standard ObservableList implementation that copies an existing list on creation, and the implementation keeps that list in sync with the list in the wrapped repository. Now your UI code can do
ObservableMovieRepository movies = new ObservableMovieRepository(new DBMovieRepository());
// ...
movieTable.setItems(movies.getAll());
With the Movie class above, you would just do
movieTitleColumn.setCellValueFactory(cellData -> cellData.getValue().titleProperty());
If you use the POJO version you can do
movieTitleColumn.setCellValueFactory(cellData -> {
try {
return new JavaBeanStringPropertyBuilder()
.bean(cellData.getValue())
.name("title")
.build();
} catch (Exception e) { throw new RuntimeException(e); }
}
There seem to be multiple question in here, so I'm not really sure, if I understood you correctly, but I will try to split it up a bit.
I want my model layer to be completely independent from JavaFX - no
StringProperty, IntegerProperty and etc. as fields. I want it to be
POJO.
You could mark your properties as transient. Then you just need to wrap them around your values and it will be both JavaFX compliant and Serializable. You just have to propagate changes back to your backing attributes.
I also have to somehow connect my data storage with JavaFX (to display
its content in TableView), so I decided to create my implementation of
ObservableList which wraps my repository. My question is - is there
any other way?
Very limited information on this and I really don't know, why you would need to create your own implementation of ObservableList, but to keep it POJO, you could maintain plain java.util.Collections in your bean and provide transient ObservableLists, which you can create on creation by wrapping your java.util.Lists in your POJO. You can find those methods in the FXCollections utility class.
ObservableList contains about 30 methods to implement and it looks
like I'm doing something wrong.
If you really need to implement it, you can inherit from ObservableListBase.

how to save a hashmap and an image to the same file

I wanted to know how to save and load a HashMap(String, List(Object)) to a file.The Object class is shown below:
public class FlashCard implements Serializable{
private String question;
private Picture picture;
private ArrayList<String> answers = new ArrayList<>();
private ArrayList<Picture> pictures = new ArrayList<>();
public FlashCard(){
}
// Method should set a list of answers
public void setAnswers(ArrayList<String> answers){
this.answers = answers;
}
// Method should add an answer to a list of answers
public void setAnswer(String answer){
answers.add(answer);
}
// Method should set a list of answers
public void setPictures(ArrayList<Picture> pictures){
this.pictures = pictures;
}
// Method should add an answer to a list of answers
public void setPicture(Picture picture){
pictures.add(picture);
}
public void setQuestion(String question){
this.question = question;
}
public ArrayList<String> getAnswers(){
return answers;
}
public ArrayList<Picture> getPictures(){
return pictures;
}
public String getQuestion(){
return question;
}
}
The picture class converts from any picture format to a BufferedImage image.I read that the BufferedImage class is not serializable. Does it mean that I cannot save both of them into the same file?Thanks.
You should be able to extend BufferedImage and have that class implement Serializable. Something like this:
public class SerializableImage extends BufferedImage implements Serializable{
...
}
Then use SerializableImage in place of BufferedImage and you should be good to go!

Json Jackson deserialization without inner classes

I have a question concerning Json deserialization using Jackson.
I would like to deserialize a Json file using a class like this one:
(taken from http://wiki.fasterxml.com/JacksonInFiveMinutes)
public class User
{
public enum Gender { MALE, FEMALE };
public static class Name {
private String _first, _last;
public String getFirst() { return _first; }
public String getLast() { return _last; }
public void setFirst(String s) { _first = s; }
public void setLast(String s) { _last = s; }
}
private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;
public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }
public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }
}
A Json file can be deserialized using the so called "Full Data Binding" in this way:
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("user.json"), User.class);
My problem is the usage of the inner class "Name". I would like to do the same thing without using inner classes. The "User" class would became like that:
import Name;
import Gender;
public class User
{
private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;
public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }
public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }
}
This means to find a way to specify to the mapper all the required classes in order to perform the deserialization.
Is this possible? I looked at the documentation but I cannot find any solution.
My need comes from the fact that I use the Javassist library to create such classes, and it does not support inner or anonymous classes.
Thank you in advance
There should be no difference between the static inner class Name, and the top-level class of the same name. The Jackson runtime should not be able to meaningfully distinguish between the two situations.
Have you tried moving the Name class out of User, changing it into a top-level class? It should still work as before.
edit: I just tried this, and it works fine when Name is a top-level class. The example had it as an inner class for the sake of brevity, I suspect.
mr. Skaffman's answer is right on. The only additional thing to mention is that unlike JAXB, Jackson does not generally require you to specify classes you operate on, except for the root class (and not always even that, if you use Polymorphic Handling).

Categories

Resources