Java tutorial
/* * Copyright 2012 - 2016 Manuel Laggner * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.tinymediamanager.ui.moviesets.dialogs; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.commons.lang3.LocaleUtils; import org.jdesktop.beansbinding.AutoBinding; import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy; import org.jdesktop.beansbinding.BeanProperty; import org.jdesktop.beansbinding.Bindings; import org.jdesktop.observablecollections.ObservableCollections; import org.jdesktop.swingbinding.JTableBinding; import org.jdesktop.swingbinding.SwingBindings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinymediamanager.Globals; import org.tinymediamanager.core.movie.MovieModuleManager; import org.tinymediamanager.core.movie.entities.Movie; import org.tinymediamanager.core.movie.entities.MovieSet; import org.tinymediamanager.scraper.MediaScraper; import org.tinymediamanager.scraper.MediaSearchOptions; import org.tinymediamanager.scraper.MediaSearchResult; import org.tinymediamanager.scraper.ScraperType; import org.tinymediamanager.scraper.entities.MediaType; import org.tinymediamanager.scraper.mediaprovider.IMovieSetMetadataProvider; import org.tinymediamanager.ui.EqualsLayout; import org.tinymediamanager.ui.IconManager; import org.tinymediamanager.ui.TmmFontHelper; import org.tinymediamanager.ui.UTF8Control; import org.tinymediamanager.ui.components.ImageLabel; import org.tinymediamanager.ui.dialogs.TmmDialog; import org.tinymediamanager.ui.moviesets.MovieSetChooserModel; import org.tinymediamanager.ui.moviesets.MovieSetChooserModel.MovieInSet; import com.jgoodies.forms.factories.FormFactory; import com.jgoodies.forms.layout.ColumnSpec; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.RowSpec; /** * The Class MovieSetChooserPanel. * * @author Manuel Laggner */ public class MovieSetChooserDialog extends TmmDialog implements ActionListener { private static final long serialVersionUID = -1023959850452480592L; /** * @wbp.nls.resourceBundle messages */ private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("messages", new UTF8Control()); //$NON-NLS-1$ private static final Logger LOGGER = LoggerFactory.getLogger(MovieSetChooserDialog.class); private MovieSet movieSetToScrape; private List<MovieSetChooserModel> movieSetsFound = ObservableCollections .observableList(new ArrayList<MovieSetChooserModel>()); private final Action actionSearch = new SearchAction(); private boolean continueQueue = true; private JLabel lblProgressAction; private JProgressBar progressBar; private JTextField tfMovieSetName; private JTable tableMovieSets; private JTextArea lblMovieSetName; private ImageLabel lblMovieSetPoster; private JTable tableMovies; private JCheckBox cbAssignMovies; private JButton btnOk; /** * Instantiates a new movie set chooser panel. * * @param movieSet * the movie set */ public MovieSetChooserDialog(MovieSet movieSet, boolean inQueue) { super(BUNDLE.getString("movieset.search"), "movieSetChooser"); //$NON-NLS-1$ setBounds(5, 5, 865, 578); movieSetToScrape = movieSet; getContentPane().setLayout(new BorderLayout(0, 0)); JPanel panelHeader = new JPanel(); getContentPane().add(panelHeader, BorderLayout.NORTH); panelHeader.setLayout(new FormLayout( new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("114px:grow"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("100px"), ColumnSpec.decode("2dlu"), }, new RowSpec[] { FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("25px"), FormFactory.RELATED_GAP_ROWSPEC, })); { tfMovieSetName = new JTextField(); panelHeader.add(tfMovieSetName, "2, 2, fill, fill"); tfMovieSetName.setColumns(10); } { JButton btnSearch = new JButton(""); btnSearch.setAction(actionSearch); panelHeader.add(btnSearch, "4, 2, fill, top"); } { JSplitPane splitPane = new JSplitPane(); splitPane.setContinuousLayout(true); splitPane.setResizeWeight(0.5); getContentPane().add(splitPane, BorderLayout.CENTER); { JPanel panelResults = new JPanel(); panelResults.setLayout(new FormLayout( new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("300px:grow"), }, new RowSpec[] { FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("fill:403px:grow"), })); JScrollPane panelSearchResults = new JScrollPane(); panelResults.add(panelSearchResults, "2, 2, fill, fill"); splitPane.setLeftComponent(panelResults); { tableMovieSets = new JTable(); panelSearchResults.setViewportView(tableMovieSets); tableMovieSets.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); tableMovieSets.setBorder(new LineBorder(new Color(0, 0, 0))); ListSelectionModel rowSM = tableMovieSets.getSelectionModel(); rowSM.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { // Ignore extra messages. if (e.getValueIsAdjusting()) return; ListSelectionModel lsm = (ListSelectionModel) e.getSource(); if (!lsm.isSelectionEmpty()) { int selectedRow = lsm.getMinSelectionIndex(); selectedRow = tableMovieSets.convertRowIndexToModel(selectedRow); try { MovieSetChooserModel model = movieSetsFound.get(selectedRow); if (model != MovieSetChooserModel.emptyResult && !model.isScraped()) { ScrapeTask task = new ScrapeTask(model); task.execute(); } } catch (Exception ex) { LOGGER.warn(ex.getMessage()); } } } }); } } { JPanel panelSearchDetail = new JPanel(); splitPane.setRightComponent(panelSearchDetail); panelSearchDetail.setLayout(new FormLayout( new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("left:150px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("max(300px;default):grow"), FormFactory.RELATED_GAP_COLSPEC, }, new RowSpec[] { FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("250px"), FormFactory.PARAGRAPH_GAP_ROWSPEC, RowSpec.decode("top:default:grow"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC })); { lblMovieSetName = new JTextArea(""); lblMovieSetName.setLineWrap(true); lblMovieSetName.setOpaque(false); lblMovieSetName.setWrapStyleWord(true); TmmFontHelper.changeFont(lblMovieSetName, 1.166, Font.BOLD); panelSearchDetail.add(lblMovieSetName, "2, 1, 3, 1, fill, top"); } { lblMovieSetPoster = new ImageLabel(); lblMovieSetPoster.setAlternativeText(BUNDLE.getString("image.notfound.poster")); //$NON-NLS-1$ panelSearchDetail.add(lblMovieSetPoster, "2, 3, fill, fill"); } { JPanel panel = new JPanel(); panelSearchDetail.add(panel, "4, 3, fill, fill"); panel.setLayout(new FormLayout( new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("default:grow"), }, new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, })); } { JScrollPane scrollPane = new JScrollPane(); panelSearchDetail.add(scrollPane, "2, 5, 3, 1, fill, fill"); { tableMovies = new JTable(); scrollPane.setViewportView(tableMovies); } } { cbAssignMovies = new JCheckBox(BUNDLE.getString("movieset.movie.assign")); //$NON-NLS-1$ cbAssignMovies.setSelected(true); panelSearchDetail.add(cbAssignMovies, "2, 7, 3, 1"); } } } { JPanel bottomPane = new JPanel(); getContentPane().add(bottomPane, BorderLayout.SOUTH); { bottomPane.setLayout(new FormLayout(new ColumnSpec[] { ColumnSpec.decode("2dlu"), ColumnSpec.decode("185px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("18px:grow"), FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, ColumnSpec.decode("2dlu"), }, new RowSpec[] { FormFactory.LINE_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.LINE_GAP_ROWSPEC })); { progressBar = new JProgressBar(); bottomPane.add(progressBar, "2, 2, fill, center"); } { lblProgressAction = new JLabel(""); bottomPane.add(lblProgressAction, "4, 2, fill, center"); } { JPanel buttonPane = new JPanel(); bottomPane.add(buttonPane, "6, 2, fill, fill"); EqualsLayout layout = new EqualsLayout(5); buttonPane.setBorder(new EmptyBorder(4, 4, 4, 4)); layout.setMinWidth(100); buttonPane.setLayout(layout); btnOk = new JButton(BUNDLE.getString("Button.ok")); //$NON-NLS-1$ btnOk.setActionCommand("Save"); btnOk.setToolTipText(BUNDLE.getString("Button.ok")); //$NON-NLS-1$ btnOk.setIcon(IconManager.APPLY); btnOk.addActionListener(this); buttonPane.add(btnOk); JButton btnCancel = new JButton(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$ btnCancel.setActionCommand("Cancel"); btnCancel.setToolTipText(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$ btnCancel.setIcon(IconManager.CANCEL); btnCancel.addActionListener(this); buttonPane.add(btnCancel); if (inQueue) { JButton btnAbort = new JButton(BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$ btnAbort.setActionCommand("Abort"); btnAbort.setToolTipText(BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$ btnAbort.setIcon(IconManager.PROCESS_STOP); btnAbort.addActionListener(this); buttonPane.add(btnAbort, "6, 1, fill, top"); } } } } initDataBindings(); // adjust table columns tableMovies.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); tableMovies.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); tableMovieSets.getColumnModel().getColumn(0).setHeaderValue(BUNDLE.getString("chooser.searchresult")); tfMovieSetName.setText(movieSet.getTitle()); searchMovie(); } private void searchMovie() { SearchTask task = new SearchTask(tfMovieSetName.getText()); task.execute(); } private class SearchTask extends SwingWorker<Void, Void> { private String searchTerm; public SearchTask(String searchTerm) { this.searchTerm = searchTerm; } @Override public Void doInBackground() { startProgressBar(BUNDLE.getString("chooser.searchingfor") + " " + searchTerm); //$NON-NLS-1$ try { List<MediaScraper> sets = MediaScraper.getMediaScrapers(ScraperType.MOVIE_SET); if (sets != null && sets.size() > 0) { MediaScraper first = sets.get(0); // just get first IMovieSetMetadataProvider mp = (IMovieSetMetadataProvider) first.getMediaProvider(); MediaSearchOptions options = new MediaSearchOptions(MediaType.MOVIE_SET, searchTerm); options.setLanguage( LocaleUtils.toLocale(MovieModuleManager.MOVIE_SETTINGS.getScraperLanguage().name())); List<MediaSearchResult> movieSets = mp.search(options); movieSetsFound.clear(); if (movieSets.size() == 0) { movieSetsFound.add(MovieSetChooserModel.emptyResult); } else { for (MediaSearchResult collection : movieSets) { MovieSetChooserModel model = new MovieSetChooserModel(collection); movieSetsFound.add(model); } } } } catch (Exception e1) { LOGGER.warn("SearchTask", e1); } return null; } @Override public void done() { stopProgressBar(); } } private class SearchAction extends AbstractAction { private static final long serialVersionUID = -6561883838396668177L; public SearchAction() { putValue(NAME, BUNDLE.getString("Button.search")); //$NON-NLS-1$ putValue(SHORT_DESCRIPTION, BUNDLE.getString("movieset.search")); //$NON-NLS-1$ putValue(SMALL_ICON, IconManager.SEARCH); putValue(LARGE_ICON_KEY, IconManager.SEARCH); } @Override public void actionPerformed(ActionEvent e) { searchMovie(); } } @Override public void actionPerformed(ActionEvent arg0) { if ("Cancel".equals(arg0.getActionCommand())) { // cancel setVisible(false); } if ("Save".equals(arg0.getActionCommand())) { // save it int row = tableMovieSets.getSelectedRow(); if (row >= 0) { MovieSetChooserModel model = movieSetsFound.get(row); if (model != MovieSetChooserModel.emptyResult) { movieSetToScrape.setTitle(model.getName()); movieSetToScrape.setPlot(model.getOverview()); // movieSetToScrape.setArtworkUrl(model.getPosterUrl(), MediaFileType.POSTER); // movieSetToScrape.setArtworkUrl(model.getFanartUrl(), MediaFileType.FANART); movieSetToScrape.setTmdbId(model.getTmdbId()); movieSetToScrape.saveToDb(); // assign movies if (cbAssignMovies.isSelected()) { movieSetToScrape.removeAllMovies(); for (int i = 0; i < model.getMovies().size(); i++) { MovieInSet movieInSet = model.getMovies().get(i); Movie movie = movieInSet.getMovie(); if (movie == null) { continue; } // check if the found movie contains a matching set if (movie.getMovieSet() != null) { // unassign movie from set MovieSet mSet = movie.getMovieSet(); mSet.removeMovie(movie); } movie.setMovieSet(movieSetToScrape); movie.writeNFO(); movie.saveToDb(); movieSetToScrape.addMovie(movie); } // and finally save assignments movieSetToScrape.saveToDb(); } // get images? if (Globals.settings.getMovieScraperMetadataConfig().isArtwork()) { // get artwork asynchronous model.startArtworkScrapeTask(movieSetToScrape, Globals.settings.getMovieScraperMetadataConfig()); } } setVisible(false); } } // Abort queue if ("Abort".equals(arg0.getActionCommand())) { continueQueue = false; setVisible(false); } } private class ScrapeTask extends SwingWorker<Void, Void> { private MovieSetChooserModel model; public ScrapeTask(MovieSetChooserModel model) { this.model = model; } @Override public Void doInBackground() { startProgressBar(BUNDLE.getString("chooser.scrapeing") + " " + model.getName()); //$NON-NLS-1$ // disable ok button as long as its scraping btnOk.setEnabled(false); model.scrapeMetadata(); btnOk.setEnabled(true); return null; } @Override public void done() { stopProgressBar(); } } private void startProgressBar(final String description) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { lblProgressAction.setText(description); progressBar.setVisible(true); progressBar.setIndeterminate(true); } }); } private void stopProgressBar() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { lblProgressAction.setText(""); progressBar.setVisible(false); progressBar.setIndeterminate(false); } }); } /** * Inits the data bindings. */ protected void initDataBindings() { JTableBinding<MovieSetChooserModel, List<MovieSetChooserModel>, JTable> jTableBinding = SwingBindings .createJTableBinding(UpdateStrategy.READ, movieSetsFound, tableMovieSets); // BeanProperty<MovieSetChooserModel, String> movieSetChooserModelBeanProperty = BeanProperty.create("name"); jTableBinding.addColumnBinding(movieSetChooserModelBeanProperty).setEditable(false); // $NON-NLS-1$ // jTableBinding.bind(); // BeanProperty<JTable, List<MovieInSet>> jTableBeanProperty = BeanProperty.create("selectedElement.movies"); JTableBinding<MovieInSet, JTable, JTable> jTableBinding_1 = SwingBindings .createJTableBinding(UpdateStrategy.READ, tableMovieSets, jTableBeanProperty, tableMovies); // BeanProperty<MovieInSet, String> movieInSetBeanProperty = BeanProperty.create("name"); jTableBinding_1.addColumnBinding(movieInSetBeanProperty).setColumnName(BUNDLE.getString("tmm.movie")) //$NON-NLS-1$ .setEditable(false); // BeanProperty<MovieInSet, String> movieInSetBeanProperty_2 = BeanProperty.create("movie.title"); jTableBinding_1.addColumnBinding(movieInSetBeanProperty_2) .setColumnName(BUNDLE.getString("movieset.movie.matched")).setEditable(false); //$NON-NLS-1$ // jTableBinding_1.bind(); // BeanProperty<JTable, String> jTableBeanProperty_1 = BeanProperty.create("selectedElement.name"); BeanProperty<JTextArea, String> jTextAreaBeanProperty = BeanProperty.create("text"); AutoBinding<JTable, String, JTextArea, String> autoBinding = Bindings.createAutoBinding(UpdateStrategy.READ, tableMovieSets, jTableBeanProperty_1, lblMovieSetName, jTextAreaBeanProperty); autoBinding.bind(); // BeanProperty<JTable, String> jTableBeanProperty_2 = BeanProperty.create("selectedElement.posterUrl"); BeanProperty<ImageLabel, String> imageLabelBeanProperty = BeanProperty.create("imageUrl"); AutoBinding<JTable, String, ImageLabel, String> autoBinding_1 = Bindings.createAutoBinding( UpdateStrategy.READ, tableMovieSets, jTableBeanProperty_2, lblMovieSetPoster, imageLabelBeanProperty); autoBinding_1.bind(); } /** * Shows the dialog and returns whether the work on the queue should be continued. * * @return true, if successful */ public boolean showDialog() { setVisible(true); return continueQueue; } @Override public void pack() { // do not let it pack - it looks weird } }