package su.litvak.moviedb.gui;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import su.litvak.moviedb.Sessions;
import su.litvak.moviedb.entity.Movie;
import su.litvak.moviedb.entity.Person;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
public class MoviesPanel extends JPanel {
JTextField fldTitle = new JTextField();
JLabel lblTitle = new JLabel("Title");
JButton btnSearch = new JButton("Search");
JLabel lblYear = new JLabel("Year");
YearComboBox cmbYear = new YearComboBox();
Model tblModel = new Model();
JTable tblMovies = new JTable(tblModel);
JScrollPane spTable = new JScrollPane(tblMovies);
JButton btnInfo = new JButton("Show info");
JButton btnAdd = new JButton("Add");
JButton btnEdit = new JButton("Edit");
JButton btnDelete = new JButton("Delete");
static class YearComboBox extends JComboBox {
YearComboBox() {
try {
Sessions.beginTransaction();
addItem("Any");
for (Number number : (List<Number>) Sessions.getSession().createCriteria(Movie.class)
.setProjection(Projections.distinct(Projections.property("year")))
.addOrder(Order.desc("year"))
.list()) {
addItem(number.toString());
}
} finally {
Sessions.rollbackTransaction();
}
}
}
static class Model extends AbstractTableModel {
List<Movie> movies = new ArrayList<Movie>();
@Override
public int getRowCount() {
return movies.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Movie movie = movies.get(rowIndex);
switch (columnIndex) {
case 0:
return movie.title;
case 1:
return movie.year;
case 2:
return movie.time;
case 3:
return movie.rating;
}
return null;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return " Movie Title ";
case 1:
return " Year ";
case 2:
return " Length (minutes) ";
case 3:
return " Rating ";
}
return null;
}
}
public MoviesPanel() {
performLayout();
}
private void performLayout() {
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
layout.setHorizontalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(lblTitle)
.addComponent(fldTitle)
.addComponent(lblYear)
.addComponent(cmbYear, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnSearch)
)
.addComponent(spTable)
.addGroup(layout.createSequentialGroup()
.addComponent(btnInfo)
.addComponent(btnAdd)
.addComponent(btnEdit)
.addComponent(btnDelete)
)
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addComponent(lblTitle)
.addComponent(fldTitle, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblYear)
.addComponent(cmbYear, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnSearch)
)
.addComponent(spTable)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addComponent(btnInfo)
.addComponent(btnAdd)
.addComponent(btnEdit)
.addComponent(btnDelete)
)
);
/**
* Set up table
*/
tblMovies.getColumnModel().getColumn(1).setMaxWidth(40);
tblMovies.getColumnModel().getColumn(2).setPreferredWidth(110);
tblMovies.getColumnModel().getColumn(2).setMaxWidth(110);
tblMovies.getColumnModel().getColumn(3).setMaxWidth(48);
tblMovies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
/**
* Set up search function
*/
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
search();
}
};
btnSearch.addActionListener(al);
fldTitle.addActionListener(al);
/**
* Set up delete function
*/
btnDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
delete();
}
});
/**
* Set up add function
*/
btnAdd.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
save(showMoviePanel(null, false));
}
});
/**
* Set up edit function
*/
btnEdit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (tblMovies.getSelectedRow() < 0) {
return;
}
save(showMoviePanel(tblModel.movies.get(tblMovies.getSelectedRow()), true));
}
});
btnInfo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (tblMovies.getSelectedRow() < 0) {
return;
}
showMovieInfo(tblModel.movies.get(tblMovies.getSelectedRow()));
}
});
}
private void search() {
String s = fldTitle.getText().trim();
if (s.isEmpty()) {
tblModel.movies.clear();
} else {
Sessions.beginTransaction();
try {
Criteria c = Sessions.getSession().createCriteria(Movie.class)
.add(Restrictions.like("title", "%" + s + "%"))
.addOrder(Order.asc("title"));
if (cmbYear.getSelectedIndex() > 0) {
c.add(Restrictions.eq("year", Integer.valueOf(cmbYear.getSelectedItem().toString())));
}
tblModel.movies = c.list();
} finally {
Sessions.rollbackTransaction();
}
}
tblModel.fireTableDataChanged();
}
private void delete() {
int row = tblMovies.getSelectedRow();
if (row < 0) {
return;
}
Movie movie = tblModel.movies.get(row);
if (JOptionPane.showConfirmDialog(this, "Are you sure you want to delete '" + movie + "'?", "Delete movie", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
return;
}
Sessions.beginTransaction();
try {
Sessions.getSession().refresh(movie);
Sessions.getSession().delete(movie);
Sessions.commitTransaction();
JOptionPane.showMessageDialog(this, "Movie '" + movie + "' was successfully deleted", "Delete movie", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex) {
Sessions.rollbackTransaction();
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "Delete movie", JOptionPane.ERROR_MESSAGE);
}
}
private JFrame getFrame() {
Container parent = getParent();
while (!(parent instanceof JFrame)) {
parent = parent.getParent();
}
return (JFrame) parent;
}
private void save(MoviePanel moviePanel) {
if (moviePanel.saved) {
Sessions.beginTransaction();
Movie movie = moviePanel.movie;
try {
if (movie.id > 0) {
Sessions.getSession().update(movie);
}
Set<Person> toAdd = new HashSet<Person>();
toAdd.addAll(processNewPerson(movie.actors));
toAdd.addAll(processNewPerson(movie.directors));
toAdd.addAll(processNewPerson(movie.writers));
toAdd.addAll(processNewPerson(movie.producers));
if (!toAdd.isEmpty() &&
JOptionPane.showConfirmDialog(this, "Following persons " + toAdd + " don't exist in a database and will be added. Are you sure?", (movie.id > 0 ? "Update" : "Add") + " movie", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
Sessions.rollbackTransaction();
save(showMoviePanel(movie, false));
return;
}
Sessions.getSession().save(movie);
Sessions.commitTransaction();
JOptionPane.showMessageDialog(this, "Movie '" + movie + "' was successfully " + (movie.id > 0 ? "updated" : "added"), (movie.id > 0 ? "Update" : "Add") + " movie", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex) {
Sessions.rollbackTransaction();
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), (movie.id > 0 ? "Update" : "Add") + " movie", JOptionPane.ERROR_MESSAGE);
}
}
}
private Set<Person> processNewPerson(Set<Person> persons) {
Set<Person> toAdd = new HashSet<Person>();
for (Person person : persons) {
Person existing = (Person) Sessions.getSession().createCriteria(Person.class).add(Restrictions.eq("name", person.name)).uniqueResult();
if (existing == null) {
Sessions.getSession().save(person);
toAdd.add(person);
} else {
person.id = existing.id;
}
}
persons.addAll(toAdd);
return toAdd;
}
private MoviePanel showMoviePanel(Movie movie, boolean refresh) {
final JDialog dialog = new JDialog(getFrame(), (movie == null ? "Add" : "Edit") + " movie", true);
if (refresh) {
Sessions.beginTransaction();
movie = (Movie) Sessions.getSession().get(Movie.class, movie.id);
}
final MoviePanel moviePanel = movie == null ? new MoviePanel() : new MoviePanel(movie);
if (refresh) {
Sessions.rollbackTransaction();
}
/**
* Lay out buttons panel
*/
JButton btnSave = new JButton("Save");
JButton btnCancel = new JButton("Cancel");
JPanel jpButtons = new JPanel();
jpButtons.add(btnSave);
jpButtons.add(btnCancel);
/**
* Add listeners
*/
btnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
btnSave.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
moviePanel.save();
dialog.dispose();
}
});
/**
* Lay out main panel
*/
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(moviePanel), BorderLayout.CENTER);
panel.add(jpButtons, BorderLayout.PAGE_END);
/**
* Show dialog
*/
dialog.setContentPane(panel);
dialog.pack();
dialog.setVisible(true);
return moviePanel;
}
private void showMovieInfo(Movie movie) {
JDialog dialog = new JDialog(getFrame(), "Movie info", true);
Sessions.beginTransaction();
movie = (Movie) Sessions.getSession().get(Movie.class, movie.id);
MovieInfoPanel panel = new MovieInfoPanel(movie);
Sessions.rollbackTransaction();
/**
* Show dialog
*/
dialog.setContentPane(panel);
dialog.pack();
dialog.setVisible(true);
}
}