Even though I have asked a question here related to my app using Swing and creating JPanel
, I still have other ones about best practice making applications. I'm using Java 8.
I have this class screening which contains Film
and Auditorium
classes. At the moment the class looks like this:
Screening.java
package cinema.schedule;
import cinema.Auditorium;
import cinema.film.Film;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Screening {
public final Auditorium auditorium;
public final Film film;
private float ticketPrice;
private LocalDateTime startDateTime;
public Screening(Film film, LocalDateTime startDateTime) {
this(new Auditorium(), 0, startDateTime, film);
}
public Screening(Film film, float ticketPrice, LocalDateTime startDateTime) {
this(new Auditorium(), ticketPrice, startDateTime, film);
}
public Screening(Auditorium auditorium, float ticketPrice, LocalDateTime startDateTime, Film film) {
this.auditorium = auditorium;
this.ticketPrice = ticketPrice;
this.startDateTime = startDateTime;
this.film = film;
}
public float getTicketPrice() {
return ticketPrice;
}
public void setTicketPrice(float ticketPrice) {
this.ticketPrice = ticketPrice;
}
public LocalTime getStartTime() {
return startDateTime.toLocalTime();
}
public void setStartTime(LocalDateTime startDateTime) {
this.startDateTime = startDateTime;
}
@Override
public String toString() {
return "Screening{" +
"switcher=" + auditorium +
", film=" + film +
", ticketPrice=" + ticketPrice +
", startDateTime=" + startDateTime +
'}';
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
Screening screening = (Screening) o;
if(Float.compare(screening.ticketPrice, ticketPrice) != 0) return false;
if(film != null ? !film.equals(screening.film) : screening.film != null) return false;
if(startDateTime != null ? !startDateTime.equals(screening.startDateTime) : screening.startDateTime != null)
return false;
if(auditorium != null ? !auditorium.equals(screening.auditorium) : screening.auditorium != null) return false;
return true;
}
@Override
public int hashCode() {
int result = auditorium != null ? auditorium.hashCode() : 0;
result = 31 * result + (film != null ? film.hashCode() : 0);
result = 31 * result + (ticketPrice != +0.0f ? Float.floatToIntBits(ticketPrice) : 0);
result = 31 * result + (startDateTime != null ? startDateTime.hashCode() : 0);
return result;
}
}
Auditorium.java
package cinema;
public class Auditorium {
private int totalSeats;
private int occupiedSeats;
public static Auditorium of(Auditorium auditorium) {
Auditorium instance = new Auditorium();
instance.occupiedSeats = auditorium.occupiedSeats;
instance.totalSeats = auditorium.totalSeats;
return instance;
}
public Auditorium() {
this(10);
}
public Auditorium(int totalSeats) {
this.totalSeats = totalSeats;
this.occupiedSeats = 0;
}
public void occupySeats(int count) {
if (getEmptySeats() >= count) {
occupiedSeats += count;
} else {
throw new IndexOutOfBoundsException("Not enough seats");
}
}
public boolean hasEmptySeats() {
return !(totalSeats <= occupiedSeats);
}
public int getEmptySeats() {
return totalSeats - occupiedSeats;
}
@Override
public String toString() {
return "Auditorium{" +
"totalSeats=" + totalSeats +
", occupiedSeats=" + occupiedSeats +
'}';
}
}
Film.java
package cinema.film;
import javax.swing.*;
import java.time.Duration;
public class Film {
private String title;
private Genre genre;
private String description;
private Duration duration;
private String pathToImage;
private Language language;
private Subtitles subtitles;
private RecommendedAge recommendedAge;
public Film() {}
public Film(String title, Genre genre, String filmLengthInDecimal, Language language, Subtitles subtitles, RecommendedAge recommendedAge, String description, String imageTitle, String pathToDir) {
this.title = title;
this.genre = genre;
this.description = description;
setLenghtInHours(filmLengthInDecimal);
this.pathToImage = pathToDir + imageTitle;
this.language = language;
this.subtitles = subtitles;
this.recommendedAge = recommendedAge;
}
public Film(Film film) {
this.title = film.title;
this.genre = film.genre;
this.description = film.description;
this.duration = film.duration;
this.pathToImage = film.pathToImage;
this.language = film.language;
this.subtitles = film.subtitles;
this.recommendedAge = film.recommendedAge;
}
public String getTitle() {
return title;
}
public Genre getGenre() {
return genre;
}
public String getDescription() {
return description;
}
public String getDurationTime() {
long s = duration.getSeconds();
return String.format("%d:%02d", s/3600, (s%3600)/60);
}
public Duration getDuration() {
return duration;
}
public Language getLanguage() {
return language;
}
public Subtitles getSubtitles() {
return subtitles;
}
public RecommendedAge getRecommendedAge() {
return recommendedAge;
}
public Icon getIcon() {
return new ImageIcon(pathToImage);
}
public void setTitle(String title) {
this.title = title;
}
public void setGenre(String genre) {
this.genre = Genre.valueOf(genre);
}
public void setDescription(String description) {
this.description = description;
}
public void setLenghtInHours(String lengthInHours) {
double timeInDecimal = Double.parseDouble(lengthInHours);
int fullHours = ((int) timeInDecimal);
int minutes = (int) ((timeInDecimal - fullHours + 0.001) * 100);
this.duration = Duration.ofMinutes((fullHours * 60) + minutes);
}
public void setPathToImage(String pathToImage) {
this.pathToImage = pathToImage;
}
public void setLanguage(String language) {
this.language = Language.valueOf(language);
}
public void setSubtitles(String subtitles) {
this.subtitles = Subtitles.valueOf(subtitles);
}
public void setRecommendedAge(String recommendedAge) {
this.recommendedAge = RecommendedAge.valueOf(recommendedAge);
}
@Override
public String toString() {
return "Movie{" +
"title='" + title + '\'' +
", genre='" + genre + '\'' +
", length='" + getDurationTime() + '\'' +
", imageTitle='" + pathToImage + '\'' +
", language='" + language + '\'' +
", subtitles='" + subtitles + '\'' +
", recommendedAge='" + getRecommendedAge() + '\'' +
", description='" + description + '\'' +
'}';
}
}
- Should I leave it like this or change something about public final instance variables? What are my options?
I'm using it in FilmsPanel.java.
package gui.panel.film;
import cinema.schedule.Screening;
import javax.swing.*;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class FilmsPanel extends JPanel {
private final JPanel container = new JPanel(new GridBagLayout());
private EventListenerList listenerList = new EventListenerList();
private List<JButton> filmButton = new ArrayList<>();
private List<Screening> screeningList;
public FilmsPanel(String title) {
if (title != null) {
container.setBorder(BorderFactory.createTitledBorder("Films"));
}
add(container);
}
public void setScreeningSet(List<Screening> screeningList) {
this.screeningList = screeningList;
updateDateButtons();
}
public void addFilmListener(FilmsListener listener) {
listenerList.add(FilmsListener.class, listener);
}
public void removeFilmListener(FilmsListener listener) {
listenerList.remove(FilmsListener.class, listener);
}
private void updateDateButtons(){
deleteDateButtons();
createDateButtons();
}
private void deleteDateButtons() {
filmButton.stream().forEach(container::remove);
filmButton = new ArrayList<>();
container.revalidate();
container.repaint();
}
private void createDateButtons() {
GridBagConstraints gbc = new GridBagConstraints(
0, 0, // grid x, y
1, 1, // grid width x, y
0.3, 0.5, // weight , x, y
GridBagConstraints.PAGE_START, // anchor
GridBagConstraints.BOTH, // fill
new Insets(5, 5, 5, 5),
0, -100 // ipad x, y
);
for(Screening screening : screeningList) {
JButton button = createScreeningButton(screening);
button.setToolTipText(getFilmInfo(screening));
button.addActionListener(e -> {
setSelectedButton(button);
FilmsEvent event = new FilmsEvent(e, screening);
fireFilmEvent(event);
}
);
container.add(button, gbc);
filmButton.add(button);
if(gbc.gridx == 1) {
gbc.gridx = 0;
gbc.gridy++;
} else {
gbc.gridx++;
}
}
}
private void setSelectedButton(JButton button) {
filmButton.stream().forEach(b -> b.setEnabled(true));
button.setEnabled(false);
}
private JButton createScreeningButton(Screening screening) {
int startHours = screening.getStartTime().getHour();
int startMinutes = screening.getStartTime().getMinute();
String fullTitle = "<html>" +
screening.film.getTitle() +
"<br /> sakums: " +
String.format("%02d:%02d", startHours, startMinutes) +
"<br /> garums: " +
screening.film.getDurationTime() +
"<br /> brivas vietas- " +
screening.auditorium.getEmptySeats() +
"<br /> biletes cena- " +
String.format("%.2f", screening.getTicketPrice()) +
"</html>";
JButton button = new JButton( fullTitle, screening.film.getIcon());
button.setDisabledIcon(screening.film.getIcon());
return button;
}
private void fireFilmEvent(FilmsEvent event) {
Object[] listeners = listenerList.getListenerList();
for(int index = 0; index < listeners.length; index += 2) {
if (listeners[index] == FilmsListener.class) {
((FilmsListener) listeners[index + 1]).moviesEventOccurred(event);
}
}
}
private String getFilmInfo(Screening screening) {
return "<html>" +
screening.film.getTitle() +
".<br /> zanrs: " +
screening.film.getGenre() +
"<br /> Apraksts: " +
splitString(screening.film.getDescription()) +
"<br /> garums: " +
screening.film.getDurationTime() +
".<br /> valoda: " +
screening.film.getLanguage() +
".<br /> subtitri: " +
screening.film.getSubtitles() +
".<br /> ieteicamais vecums: " +
screening.film.getRecommendedAge() +
"</html>";
}
public static String splitString(String string) {
String buf = "";
String tempString = string;
if (string != null) {
while(tempString.length() > 60)
{
String block = tempString.substring(0, 60);
int index = block.lastIndexOf(' ');
if(index < 0) {
index = tempString.indexOf(' ');
}
if (index >= 0){
buf += (tempString.substring(0, index) + "<BR>");
}
tempString = tempString.substring(index+1);
}
}
else {
tempString = " ";
}
buf += tempString;
return buf;
}
}
What are other things you notice about the code that I should change/improve/work on?
What are industry standards for making things similar to this? Should I make interfaces where it assembles for example button title, button image? It seems like a lot of classes for such a little thing.
.getAuditorium ()
andgetFilm
methods? And I should what would be the purpose of it? \$\endgroup\$