Adds composer to scraper. Various bug fixes in list selection.

This commit is contained in:
lantzelot-swe 2020-12-29 23:03:46 +01:00
parent 5e1061707a
commit d3bc3b664a
12 changed files with 203 additions and 56 deletions

View File

@ -95,7 +95,7 @@ public class BaseDialog extends JDialog
return buttonPanel; return buttonPanel;
} }
protected JButton getOkButton() public JButton getOkButton()
{ {
if (okButton == null) if (okButton == null)
{ {

View File

@ -181,8 +181,8 @@ public class ListPanel extends JPanel
{ {
indexToSelect = uiModel.getGameListModel().getSize() - 1; indexToSelect = uiModel.getGameListModel().getSize() - 1;
} }
list.clearSelection(); list.setSelectionInterval(indexToSelect, indexToSelect);
list.setSelectedIndex(indexToSelect); updateSelectedGame();
list.ensureIndexIsVisible(indexToSelect); list.ensureIndexIsVisible(indexToSelect);
} }
@ -350,7 +350,6 @@ public class ListPanel extends JPanel
private void updateSelectedGame() private void updateSelectedGame()
{ {
System.out.println("Update selected Game!!!");
SwingUtilities SwingUtilities
.invokeLater(() -> mainPanel.getGameDetailsBackgroundPanel().updateSelectedGame(list.getSelectedValue())); .invokeLater(() -> mainPanel.getGameDetailsBackgroundPanel().updateSelectedGame(list.getSelectedValue()));
} }

View File

@ -117,7 +117,7 @@ public class MainPanel extends JPanel
int currentSelectedIndex = getListPanel().getSelectedIndexInList(); int currentSelectedIndex = getListPanel().getSelectedIndexInList();
uiModel.deleteCurrentGame(); uiModel.deleteCurrentGame();
repaintAfterModifications(); repaintAfterModifications();
SwingUtilities.invokeLater(() -> getListPanel().setSelectedIndexInList(currentSelectedIndex)); getListPanel().setSelectedIndexInList(currentSelectedIndex);
} }
} }
} }

View File

@ -144,6 +144,7 @@ public class ScreenshotsPanel extends JPanel
String modelCoverFile = model.getCoverFile(); String modelCoverFile = model.getCoverFile();
if (modelCoverFile.isEmpty()) if (modelCoverFile.isEmpty())
{ {
currentCoverFile = "";
getCoverImageLabel().setIcon(getMissingCoverImageIcon()); getCoverImageLabel().setIcon(getMissingCoverImageIcon());
} }
else if (!modelCoverFile.equals(currentCoverFile)) else if (!modelCoverFile.equals(currentCoverFile))
@ -170,6 +171,7 @@ public class ScreenshotsPanel extends JPanel
String modelScreen1File = model.getScreens1File(); String modelScreen1File = model.getScreens1File();
if (modelScreen1File.isEmpty()) if (modelScreen1File.isEmpty())
{ {
currentScreen1File = "";
getScreen1ImageLabel().setIcon(getMissingScreenshotImageIcon()); getScreen1ImageLabel().setIcon(getMissingScreenshotImageIcon());
} }
else if (!model.getScreens1File().equals(currentScreen1File)) else if (!model.getScreens1File().equals(currentScreen1File))
@ -196,6 +198,7 @@ public class ScreenshotsPanel extends JPanel
String modelScreen2File = model.getScreens2File(); String modelScreen2File = model.getScreens2File();
if (modelScreen2File.isEmpty()) if (modelScreen2File.isEmpty())
{ {
currentScreen2File = "";
getScreen2ImageLabel().setIcon(getMissingScreenshotImageIcon()); getScreen2ImageLabel().setIcon(getMissingScreenshotImageIcon());
} }
else if (!modelScreen2File.equals(currentScreen2File)) else if (!modelScreen2File.equals(currentScreen2File))

View File

@ -8,6 +8,8 @@ import java.awt.GridBagLayout;
import java.awt.Insets; import java.awt.Insets;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -17,11 +19,12 @@ import javax.swing.JEditorPane;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkEvent;
import se.lantz.gui.BaseDialog;
import se.lantz.manager.ScraperManager; import se.lantz.manager.ScraperManager;
import se.lantz.model.MainViewModel;
import se.lantz.model.data.ScraperFields; import se.lantz.model.data.ScraperFields;
import se.lantz.util.ExceptionHandler; import se.lantz.util.ExceptionHandler;
@ -40,12 +43,12 @@ public class MobyGamesOptionsPanel extends JPanel
private ScraperManager scraper; private ScraperManager scraper;
private JButton connectButton; private JButton connectButton;
private JLabel connectionStatusLabel; private JLabel connectionStatusLabel;
private Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR); private Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR);
private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR); private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
private JButton okButton; private JButton okButton;
private JCheckBox genreCheckBox; private JCheckBox genreCheckBox;
private JCheckBox composerCheckBox;
public MobyGamesOptionsPanel(ScraperManager scraper, JButton okButton) public MobyGamesOptionsPanel(ScraperManager scraper, JButton okButton)
{ {
@ -124,12 +127,23 @@ public class MobyGamesOptionsPanel extends JPanel
return infoEditorPane; return infoEditorPane;
} }
private JTextField getUrlTextField() JTextField getUrlTextField()
{ {
if (urlTextField == null) if (urlTextField == null)
{ {
urlTextField = new JTextField(); urlTextField = new JTextField();
urlTextField.setText("https://www.mobygames.com/game/"); urlTextField.setText("https://www.mobygames.com/game/");
urlTextField.addKeyListener(new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
getConnectButton().doClick();
}
}
});
} }
return urlTextField; return urlTextField;
} }
@ -161,11 +175,17 @@ public class MobyGamesOptionsPanel extends JPanel
gbc_authorCheckBox.gridx = 0; gbc_authorCheckBox.gridx = 0;
gbc_authorCheckBox.gridy = 2; gbc_authorCheckBox.gridy = 2;
fieldsPanel.add(getAuthorCheckBox(), gbc_authorCheckBox); fieldsPanel.add(getAuthorCheckBox(), gbc_authorCheckBox);
GridBagConstraints gbc_composerCheckBox = new GridBagConstraints();
gbc_composerCheckBox.anchor = GridBagConstraints.WEST;
gbc_composerCheckBox.insets = new Insets(0, 0, 5, 5);
gbc_composerCheckBox.gridx = 1;
gbc_composerCheckBox.gridy = 2;
fieldsPanel.add(getComposerCheckBox(), gbc_composerCheckBox);
GridBagConstraints gbc_coverCheckBox = new GridBagConstraints(); GridBagConstraints gbc_coverCheckBox = new GridBagConstraints();
gbc_coverCheckBox.anchor = GridBagConstraints.WEST; gbc_coverCheckBox.anchor = GridBagConstraints.WEST;
gbc_coverCheckBox.insets = new Insets(0, 0, 5, 0); gbc_coverCheckBox.insets = new Insets(0, 0, 5, 5);
gbc_coverCheckBox.gridx = 1; gbc_coverCheckBox.gridx = 1;
gbc_coverCheckBox.gridy = 2; gbc_coverCheckBox.gridy = 3;
fieldsPanel.add(getCoverCheckBox(), gbc_coverCheckBox); fieldsPanel.add(getCoverCheckBox(), gbc_coverCheckBox);
GridBagConstraints gbc_yearCheckBox = new GridBagConstraints(); GridBagConstraints gbc_yearCheckBox = new GridBagConstraints();
gbc_yearCheckBox.insets = new Insets(0, 0, 5, 5); gbc_yearCheckBox.insets = new Insets(0, 0, 5, 5);
@ -174,22 +194,22 @@ public class MobyGamesOptionsPanel extends JPanel
gbc_yearCheckBox.gridy = 3; gbc_yearCheckBox.gridy = 3;
fieldsPanel.add(getYearCheckBox(), gbc_yearCheckBox); fieldsPanel.add(getYearCheckBox(), gbc_yearCheckBox);
GridBagConstraints gbc_descriptionCheckBox = new GridBagConstraints(); GridBagConstraints gbc_descriptionCheckBox = new GridBagConstraints();
gbc_descriptionCheckBox.insets = new Insets(0, 0, 5, 0); gbc_descriptionCheckBox.insets = new Insets(0, 0, 5, 5);
gbc_descriptionCheckBox.anchor = GridBagConstraints.WEST; gbc_descriptionCheckBox.anchor = GridBagConstraints.WEST;
gbc_descriptionCheckBox.gridx = 1; gbc_descriptionCheckBox.gridx = 1;
gbc_descriptionCheckBox.gridy = 1; gbc_descriptionCheckBox.gridy = 1;
fieldsPanel.add(getDescriptionCheckBox(), gbc_descriptionCheckBox); fieldsPanel.add(getDescriptionCheckBox(), gbc_descriptionCheckBox);
GridBagConstraints gbc_genreCheckBox = new GridBagConstraints(); GridBagConstraints gbc_genreCheckBox = new GridBagConstraints();
gbc_genreCheckBox.insets = new Insets(0, 0, 5, 5); gbc_genreCheckBox.insets = new Insets(0, 0, 0, 5);
gbc_genreCheckBox.anchor = GridBagConstraints.WEST; gbc_genreCheckBox.anchor = GridBagConstraints.WEST;
gbc_genreCheckBox.gridx = 0; gbc_genreCheckBox.gridx = 0;
gbc_genreCheckBox.gridy = 4; gbc_genreCheckBox.gridy = 4;
fieldsPanel.add(getGenreCheckBox(), gbc_genreCheckBox); fieldsPanel.add(getGenreCheckBox(), gbc_genreCheckBox);
GridBagConstraints gbc_screensCheckBox = new GridBagConstraints(); GridBagConstraints gbc_screensCheckBox = new GridBagConstraints();
gbc_screensCheckBox.insets = new Insets(0, 0, 5, 0); gbc_screensCheckBox.insets = new Insets(0, 0, 0, 5);
gbc_screensCheckBox.anchor = GridBagConstraints.WEST; gbc_screensCheckBox.anchor = GridBagConstraints.WEST;
gbc_screensCheckBox.gridx = 1; gbc_screensCheckBox.gridx = 1;
gbc_screensCheckBox.gridy = 3; gbc_screensCheckBox.gridy = 4;
fieldsPanel.add(getScreensCheckBox(), gbc_screensCheckBox); fieldsPanel.add(getScreensCheckBox(), gbc_screensCheckBox);
} }
return fieldsPanel; return fieldsPanel;
@ -269,7 +289,7 @@ public class MobyGamesOptionsPanel extends JPanel
} }
return screensCheckBox; return screensCheckBox;
} }
private void enableCheckBoxes(boolean enable) private void enableCheckBoxes(boolean enable)
{ {
titleCheckBox.setEnabled(enable); titleCheckBox.setEnabled(enable);
@ -279,8 +299,9 @@ public class MobyGamesOptionsPanel extends JPanel
coverCheckBox.setEnabled(enable); coverCheckBox.setEnabled(enable);
screensCheckBox.setEnabled(enable); screensCheckBox.setEnabled(enable);
genreCheckBox.setEnabled(enable); genreCheckBox.setEnabled(enable);
composerCheckBox.setEnabled(enable);
} }
public ScraperFields getScraperFields() public ScraperFields getScraperFields()
{ {
ScraperFields returnValue = new ScraperFields(); ScraperFields returnValue = new ScraperFields();
@ -291,47 +312,72 @@ public class MobyGamesOptionsPanel extends JPanel
returnValue.setDescription(descriptionCheckBox.isSelected()); returnValue.setDescription(descriptionCheckBox.isSelected());
returnValue.setCover(coverCheckBox.isSelected()); returnValue.setCover(coverCheckBox.isSelected());
returnValue.setScreenshots(screensCheckBox.isSelected()); returnValue.setScreenshots(screensCheckBox.isSelected());
returnValue.setComposer(composerCheckBox.isSelected());
return returnValue; return returnValue;
} }
private JButton getConnectButton() {
if (connectButton == null) { JButton getConnectButton()
connectButton = new JButton("Connect"); {
connectButton.addActionListener(new ActionListener() { if (connectButton == null)
public void actionPerformed(ActionEvent e) { {
try connectButton = new JButton("Connect");
connectButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{ {
MobyGamesOptionsPanel.this.setCursor(waitCursor); try
scraper.connectScraper(urlTextField.getText()); {
getConnectionStatusLabel().setText("Connection status: OK"); MobyGamesOptionsPanel.this.setCursor(waitCursor);
enableCheckBoxes(true); scraper.connectScraper(urlTextField.getText());
okButton.setEnabled(true); getConnectionStatusLabel().setText("Connection status: OK");
MobyGamesOptionsPanel.this.setCursor(defaultCursor); enableCheckBoxes(true);
okButton.setEnabled(true);
MobyGamesOptionsPanel.this.setCursor(defaultCursor);
SwingUtilities.invokeLater(() -> SwingUtilities.getRootPane(connectButton).setDefaultButton(okButton));
}
catch (Exception e2)
{
getConnectionStatusLabel().setText("Connection status: Error. Invalid URL?");
enableCheckBoxes(false);
okButton.setEnabled(false);
MobyGamesOptionsPanel.this.setCursor(defaultCursor);
SwingUtilities.invokeLater(() -> SwingUtilities.getRootPane(connectButton).setDefaultButton(connectButton));
}
} }
catch (Exception e2) });
{
getConnectionStatusLabel().setText("Connection status: Error. Invalid URL?");
enableCheckBoxes(false);
okButton.setEnabled(false);
MobyGamesOptionsPanel.this.setCursor(defaultCursor);
}
}
});
} }
return connectButton; return connectButton;
} }
private JLabel getConnectionStatusLabel() {
if (connectionStatusLabel == null) { private JLabel getConnectionStatusLabel()
connectionStatusLabel = new JLabel(" "); {
connectionStatusLabel.setFont(connectionStatusLabel.getFont().deriveFont(Font.BOLD)); if (connectionStatusLabel == null)
{
connectionStatusLabel = new JLabel(" ");
connectionStatusLabel.setFont(connectionStatusLabel.getFont().deriveFont(Font.BOLD));
} }
return connectionStatusLabel; return connectionStatusLabel;
} }
private JCheckBox getGenreCheckBox() {
if (genreCheckBox == null) { private JCheckBox getGenreCheckBox()
genreCheckBox = new JCheckBox("Genre"); {
genreCheckBox.setSelected(true); if (genreCheckBox == null)
genreCheckBox.setEnabled(false); {
genreCheckBox = new JCheckBox("Genre");
genreCheckBox.setSelected(true);
genreCheckBox.setEnabled(false);
} }
return genreCheckBox; return genreCheckBox;
} }
private JCheckBox getComposerCheckBox()
{
if (composerCheckBox == null)
{
composerCheckBox = new JCheckBox("Composer");
composerCheckBox.setSelected(true);
composerCheckBox.setEnabled(false);
}
return composerCheckBox;
}
} }

View File

@ -38,4 +38,13 @@ public class ScraperDialog extends BaseDialog
{ {
return getMobyGamesPanel().getScraperFields(); return getMobyGamesPanel().getScraperFields();
} }
@Override
public boolean showDialog()
{
getMobyGamesPanel().getUrlTextField().requestFocusInWindow();
this.getRootPane().setDefaultButton(getMobyGamesPanel().getConnectButton());
return super.showDialog();
}
} }

View File

@ -26,7 +26,10 @@ public class ScraperWorker extends SwingWorker<Void, String>
{ {
scraperManager.scrapeGameInformation(fields); scraperManager.scrapeGameInformation(fields);
publish(""); publish("");
scraperManager.scrapeScreenshots(); if (fields.isScreenshots())
{
scraperManager.scrapeScreenshots();
}
return null; return null;
} }

View File

@ -68,6 +68,10 @@ public class ScraperManager
infoModel.setGenre(genre); infoModel.setGenre(genre);
} }
} }
if (fields.isComposer())
{
infoModel.setComposer(scraper.getComposer());
}
if (fields.isCover()) if (fields.isCover())
{ {
infoModel.setCoverImage(scraper.getCover()); infoModel.setCoverImage(scraper.getCover());

View File

@ -67,6 +67,24 @@ public class MainViewModel extends AbstractModel
resetDataChangedAfterInit(); resetDataChangedAfterInit();
} }
@Override
public void disableChangeNotification(boolean disable)
{
super.disableChangeNotification(disable);
infoModel.disableChangeNotification(disable);
joy1Model.disableChangeNotification(disable);
joy2Model.disableChangeNotification(disable);
systemModel.disableChangeNotification(disable);
}
protected void notifyChangeForAllModels()
{
infoModel.notifyChange();
joy1Model.notifyChange();
joy2Model.notifyChange();
systemModel.notifyChange();
}
private void setupGameViews() private void setupGameViews()
{ {
//Setup game views //Setup game views
@ -79,7 +97,7 @@ public class MainViewModel extends AbstractModel
favoritesView.setName("Favorites"); favoritesView.setName("Favorites");
favoritesView.setSqlQuery(" WHERE Favorite = 1"); favoritesView.setSqlQuery(" WHERE Favorite = 1");
gameViewModel.addElement(favoritesView); gameViewModel.addElement(favoritesView);
List<GameView> gameViewList = dbConnector.loadGameViews(); List<GameView> gameViewList = dbConnector.loadGameViews();
Collections.sort(gameViewList); Collections.sort(gameViewList);
for (GameView gameView : gameViewList) for (GameView gameView : gameViewList)
@ -116,6 +134,8 @@ public class MainViewModel extends AbstractModel
// Read from db, update all models after that. // Read from db, update all models after that.
details = dbConnector.getGameDetails(selectedData.getGameId()); details = dbConnector.getGameDetails(selectedData.getGameId());
} }
disableChangeNotification(true);
// Map to models // Map to models
infoModel.setTitleFromDb(details.getTitle()); infoModel.setTitleFromDb(details.getTitle());
@ -132,20 +152,25 @@ public class MainViewModel extends AbstractModel
//Reset and images that where added previously //Reset and images that where added previously
infoModel.resetImages(); infoModel.resetImages();
infoModel.resetDataChanged();
joy1Model.setConfigStringFromDb(details.getJoy1()); joy1Model.setConfigStringFromDb(details.getJoy1());
joy1Model.resetDataChanged();
joy2Model.setConfigStringFromDb(details.getJoy2()); joy2Model.setConfigStringFromDb(details.getJoy2());
joy2Model.resetDataChanged();
systemModel.setConfigStringFromDb(details.getSystem()); systemModel.setConfigStringFromDb(details.getSystem());
systemModel.setVerticalShift(details.getVerticalShift()); systemModel.setVerticalShift(details.getVerticalShift());
systemModel.resetDataChanged();
//Set empty title to trigger a change //Set empty title to trigger a change
if (selectedData.getGameId().isEmpty()) if (selectedData.getGameId().isEmpty())
{ {
infoModel.setTitle(""); infoModel.setTitle("");
} }
disableChangeNotification(false);
notifyChangeForAllModels();
//Do not reset unsaved for new entry
if (!selectedData.getGameId().isEmpty())
{
resetDataChanged();
}
} }
public StringBuilder importGameInfo(List<String> rowValues, ImportManager.Options option, boolean addAsFavorite) public StringBuilder importGameInfo(List<String> rowValues, ImportManager.Options option, boolean addAsFavorite)
@ -426,7 +451,7 @@ public class MainViewModel extends AbstractModel
resetDataChanged(); resetDataChanged();
} }
} }
public void toggleFavorite(GameListData data) public void toggleFavorite(GameListData data)
{ {
if (data != null && !data.getGameId().isEmpty()) if (data != null && !data.getGameId().isEmpty())
@ -436,7 +461,7 @@ public class MainViewModel extends AbstractModel
gameListModel.notifyChange(); gameListModel.notifyChange();
} }
} }
public void runGameInVice() public void runGameInVice()
{ {
fileManager.runGameInVice(); fileManager.runGameInVice();

View File

@ -139,6 +139,7 @@ public class SystemModel extends AbstractModel
resetValues(); resetValues();
if (configString == null || configString.isEmpty()) if (configString == null || configString.isEmpty())
{ {
disableChangeNotification(false);
return; return;
} }
else else
@ -154,6 +155,7 @@ public class SystemModel extends AbstractModel
{ {
setC64(true); setC64(true);
setPal(true); setPal(true);
setVic(false);
setAccurateDisk(false); setAccurateDisk(false);
setDriveIcon(false); setDriveIcon(false);
setReadOnly(false); setReadOnly(false);

View File

@ -9,6 +9,7 @@ public class ScraperFields
private boolean genre = true; private boolean genre = true;
private boolean cover = true; private boolean cover = true;
private boolean screenshots = true; private boolean screenshots = true;
private boolean composer = true;
public ScraperFields() public ScraperFields()
{ {
@ -69,5 +70,13 @@ public class ScraperFields
{ {
this.genre = genre; this.genre = genre;
} }
public boolean isComposer()
{
return composer;
}
public void setComposer(boolean composer)
{
this.composer = composer;
}
} }

View File

@ -16,6 +16,7 @@ import org.jsoup.Connection;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode; import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -57,6 +58,8 @@ public class MobyGamesScraper
private String scrapedDescription = ""; private String scrapedDescription = "";
private String scrapedGenre = ""; private String scrapedGenre = "";
private String scrapedComposer = "";
private BufferedImage scrapedCover = null; private BufferedImage scrapedCover = null;
@ -120,10 +123,15 @@ public class MobyGamesScraper
scrapedGenre = genre; scrapedGenre = genre;
} }
} }
if (fields.isComposer())
{
scrapedComposer = scrapeComposer(doc);
}
if (fields.isCover()) if (fields.isCover())
{ {
scrapedCover = scrapeCover(doc); scrapedCover = scrapeCover(doc);
} }
} }
catch (IOException e) catch (IOException e)
{ {
@ -155,6 +163,11 @@ public class MobyGamesScraper
{ {
return scrapedGenre; return scrapedGenre;
} }
public String getComposer()
{
return scrapedComposer;
}
public BufferedImage getCover() public BufferedImage getCover()
{ {
@ -215,6 +228,40 @@ public class MobyGamesScraper
} }
return value; return value;
} }
public String scrapeComposer(Document doc)
{
String value = "";
//Look for div with music in sidebar
String cssQuery = ".sideBarContent";
Elements queryElements = doc.select(cssQuery);
Element first = queryElements.first();
if (first != null)
{
boolean musicFound = false;
for (Node node : first.childNodes())
{
if (node instanceof TextNode)
{
String test = ((TextNode)node).text();
//TODO: Add more possible labels
if (test.contains("Music") || test.contains("music"))
{
musicFound = true;
}
}
else if (node instanceof Element && musicFound)
{
value = ((Element)node).text();
if (!value.isEmpty())
{
break;
}
}
}
}
return value;
}
public BufferedImage scrapeCover(Document doc) public BufferedImage scrapeCover(Document doc)
{ {