1 package com.ranfa.main;
3 import java.awt.BorderLayout;
4 import java.awt.CardLayout;
5 import java.awt.Desktop;
6 import java.awt.EventQueue;
8 import java.io.IOException;
10 import java.net.URISyntaxException;
11 import java.nio.file.Files;
12 import java.nio.file.Paths;
13 import java.text.Normalizer;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Random;
19 import java.util.concurrent.CompletableFuture;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
22 import java.util.function.BiConsumer;
23 import java.util.stream.Collectors;
25 import javax.swing.DefaultComboBoxModel;
26 import javax.swing.JButton;
27 import javax.swing.JCheckBox;
28 import javax.swing.JComboBox;
29 import javax.swing.JFrame;
30 import javax.swing.JLabel;
31 import javax.swing.JOptionPane;
32 import javax.swing.JPanel;
33 import javax.swing.JProgressBar;
34 import javax.swing.JScrollPane;
35 import javax.swing.JSpinner;
36 import javax.swing.JTabbedPane;
37 import javax.swing.JTextArea;
38 import javax.swing.border.EmptyBorder;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import com.jgoodies.forms.layout.ColumnSpec;
44 import com.jgoodies.forms.layout.FormLayout;
45 import com.jgoodies.forms.layout.FormSpecs;
46 import com.jgoodies.forms.layout.RowSpec;
47 import com.ranfa.lib.CheckVersion;
48 import com.ranfa.lib.Easter;
49 import com.ranfa.lib.ManualUpdateThreadImpl;
50 import com.ranfa.lib.SettingJSONProperty;
51 import com.ranfa.lib.Settings;
52 import com.ranfa.lib.Suffix;
53 import com.ranfa.lib.TwitterIntegration;
54 import com.ranfa.lib.Version;
55 import com.ranfa.lib.concurrent.CountedThreadFactory;
56 import com.ranfa.lib.database.EstimateAlbumTypeCycle;
57 import com.ranfa.lib.database.Scraping;
58 import com.ranfa.lib.database.Song;
59 import com.ranfa.lib.handler.CrashHandler;
60 import com.ranfa.lib.songinfo.FetchFromAPI;
62 @Version(major = 4, minor = 0, patch = 1, suffix = Suffix.BETA)
63 public class DelesteRandomSelector extends JFrame {
65 private static ArrayList<Song> selectedSongsList = new ArrayList<>();
67 private JPanel contentPane;
68 private SettingJSONProperty property = new SettingJSONProperty();
69 private String[] integratorArray;
70 private boolean integratorBool = false;
71 private CompletableFuture<Void> softwareUpdateFuture = null;
72 private CompletableFuture<Void> albumTypeEstimateFuture = null;
73 private String albumType = Messages.MSGAlbumTypeBeingCalculated.toString();
74 private Logger logger = LoggerFactory.getLogger(DelesteRandomSelector.class);
75 private ManualUpdateThreadImpl impl;
76 private List<Song> toolIntegrateList;
77 private FetchFromAPI fetchData;
78 private List<Map<String, String>> listToolMapData;
79 private CompletableFuture<List<Map<String, String>>> listToolMapDataFuture;
80 private Easter easter;
81 private JPanel panelMain;
82 private JPanel panelNorthMain;
83 private JLabel labelTitle;
84 private JLabel labelVersion;
85 private JPanel panelWestMain;
86 private JLabel labelDifficulty;
87 private JComboBox<String[]> comboDifficultySelect;
88 private JComboBox<String[]> comboAttribute;
89 private JLabel labelLevel;
90 private JSpinner spinnerLevel;
91 private JCheckBox checkLessLv;
92 private JCheckBox checkMoreLv;
93 private JLabel labelLvCaution;
94 private JPanel panelEastMain;
95 private JButton btnImport;
96 private JButton btnConfig;
97 private JButton btnStart;
98 private JButton btnManualUpdate;
99 private JButton btnTwitterIntegration;
100 private JButton btnExit;
101 private JPanel panelCenterMain;
102 private JScrollPane scrollPane;
103 private JTextArea textArea;
104 private JTabbedPane tabbedPane;
105 private JPanel panelInfo;
106 private JPanel panelNorthTool;
107 private JLabel labelSubToolTitle;
108 private JLabel labelVersionTool;
109 private JPanel panelCenterTool;
110 private JLabel labelInfoPlaySongs;
111 private JLabel labelSongNameToolTitle;
112 private JLabel labelSongNameToolTip;
113 private JLabel labelAttributeToolTitle;
114 private JLabel labelAttributeToolTip;
115 private JLabel labelDifficultyToolTitle;
116 private JLabel labelDifficultyToolTip;
117 private JLabel labelLevelToolTitle;
118 private JLabel labelLevelToolTip;
119 private JLabel labelNotesToolTitle;
120 private JLabel labelNotesToolTip;
121 private JButton btnPrevSongTool;
122 private JButton btnNextSongTool;
123 private JLabel labelSlashTool;
124 private JLabel labelCurrentSongOrderTool;
125 private JLabel labelSongLimitTool;
126 private JLabel labelLyricToolTitle;
127 private JLabel labelLyricToolTip;
128 private JLabel labelComposerToolTitle;
129 private JLabel labelArrangeToolTitle;
130 private JLabel labelComposerToolTip;
131 private JLabel labelArrangeToolTip;
132 private JLabel labelMemberToolTitle;
133 private JLabel labelMemberToolTip;
134 private JButton btnMoreInfoTool;
136 BiConsumer<ArrayList<Song>, ArrayList<Song>> updateConsumer = (list1, list2) -> {
137 this.logger.info("Checking database updates...");
138 if(list1.size() > list2.size()) {
139 long time = System.currentTimeMillis();
140 this.logger.info("{} Update detected.", (list1.size() - list2.size()));
141 Scraping.writeToJson(list1);
142 this.logger.info("Update completed in {} ms", (System.currentTimeMillis() - time));
143 this.logger.info("Updated database size: {}", list1.size());
145 this.logger.info("database is up-to-date.");
148 Runnable setEnabled = () -> {
150 Thread.sleep(3 * 1000L);
151 } catch (InterruptedException e1) {
152 this.logger.error("Thread has been interrupted during waiting cooldown.", e1);
154 this.btnImport.setEnabled(true);
155 this.btnImport.setText(Messages.MSGNarrowingDownSongs.toString());
157 private JLabel labelToolProgress;
158 public static JProgressBar progressTool;
159 public static JLabel labelInfoProgressSongName;
160 private JPanel panelScore;
161 private JPanel panelScoreNorth;
162 private JPanel panelScoreCenter;
163 private JLabel labelScoreTitle;
164 private JLabel labelScoreVersion;
167 * Launch the application.
169 public static void main(String[] args) {
170 EventQueue.invokeLater(() -> {
172 DelesteRandomSelector frame = new DelesteRandomSelector();
173 frame.setVisible(true);
174 } catch (Exception e) {
183 * this.getClass() + ":[LEVEL]: " +
189 public DelesteRandomSelector() {
190 ExecutorService es = Executors.newCachedThreadPool(new CountedThreadFactory(() -> "DRS", "AsyncEventInquerier", false));
191 this.contentPane = new JPanel();
192 // output system info phase
193 CompletableFuture.runAsync(() -> {
194 CrashHandler handle = new CrashHandler();
195 handle.outSystemInfo();
196 }, es).whenCompleteAsync((ret, ex) -> {
198 logger.error("Exception was thrown during concurrent process", ex);
199 CrashHandler handle = new CrashHandler(ex);
200 if(ex instanceof NullPointerException) {
203 handle = new CrashHandler(new IllegalStateException(ex));
207 boolean isFirst = !Scraping.databaseExists();
208 // database check phase
209 CompletableFuture.runAsync(() -> {
211 JOptionPane.showMessageDialog(this, Messages.MSGDatabaseNotExist.toString());
212 if(!Scraping.writeToJson(Scraping.getWholeData())) {
213 JOptionPane.showMessageDialog(this, "Exception:NullPointerException\nCannot Keep up! Please re-download this Application!");
214 throw new NullPointerException("FATAL: cannot continue!");
217 }, es).whenCompleteAsync((ret, ex) -> {
219 logger.error("Exception was thrown during concurrent process", ex);
220 CrashHandler handle = new CrashHandler(ex);
221 if(ex instanceof NullPointerException) {
224 handle = new CrashHandler(new IllegalStateException(ex));
228 CompletableFuture<ArrayList<Song>> getFromJsonFuture = CompletableFuture.supplyAsync(() -> Scraping.getFromJson(), es);
229 CompletableFuture<ArrayList<Song>> getWholeDataFuture = CompletableFuture.supplyAsync(() -> Scraping.getWholeData(), es);
230 // setting check phase
231 CompletableFuture.runAsync(() -> {
232 if(!Settings.fileExists() && !Settings.writeDownJSON()) {
233 JOptionPane.showMessageDialog(this, "Exception:NullPointerException\nPlease see crash report for more detail.");
234 CrashHandler handle = new CrashHandler("Failed to generate setting file.", new NullPointerException("FATAL: cannot continue!"));
237 }, es).whenCompleteAsync((ret, ex) -> {
239 logger.error("Exception was thrown during concurrent process", ex);
240 CrashHandler handle = new CrashHandler(ex);
241 if(ex instanceof NullPointerException) {
244 handle = new CrashHandler(new IllegalStateException(ex));
247 this.logger.debug("Loading settings...");
248 this.property.setCheckLibraryUpdates(Settings.needToCheckLibraryUpdates());
249 this.property.setCheckVersion(Settings.needToCheckVersion());
250 this.property.setWindowWidth(Settings.getWindowWidth());
251 this.property.setWindowHeight(Settings.getWindowHeight());
252 this.property.setSongLimit(Settings.getSongsLimit());
253 this.property.setSaveScoreLog(Settings.saveScoreLog());
254 this.logger.debug("Load settings done.");
255 this.logger.debug("Version check: {}", this.property.isCheckVersion());
256 this.logger.debug("Library update check: {}", this.property.isCheckLibraryUpdates());
257 this.logger.debug("Window Width: {}", this.property.getWindowWidth());
258 this.logger.debug("Window Height: {}", this.property.getWindowHeight());
259 this.logger.debug("Song Limit: {}", this.property.getSongLimit());
260 this.logger.debug("SaveScoreLog: {}", this.property.isSaveScoreLog());
261 this.setBounds(100, 100, this.property.getWindowWidth(), this.property.getWindowHeight());
262 if(this.property.isCheckVersion()) {
263 this.softwareUpdateFuture = CompletableFuture.runAsync(() -> CheckVersion.needToBeUpdated(), es);
265 if(this.property.isCheckLibraryUpdates()) {
266 CompletableFuture<Void> updatedFuture = getWholeDataFuture.thenAcceptBothAsync(getFromJsonFuture, updateConsumer, es);
267 updatedFuture.thenRunAsync(setEnabled, es);
270 CompletableFuture.runAsync(() -> {
271 EstimateAlbumTypeCycle.Initialization();
272 if(Files.exists(Paths.get("generated/albumCycle.json"))) {
273 this.albumType = EstimateAlbumTypeCycle.getCurrentCycle();
275 }, es).whenCompleteAsync((ret, ex) -> {
277 logger.error("Exception was thrown during concurrent process", ex);
278 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
282 getWholeDataFuture.thenAcceptAsync(list -> this.logger.info("Scraping data size:" + list.size()), es);
283 getFromJsonFuture.thenAcceptAsync(list -> this.logger.info("Currently database size:" + list.size()), es);
285 CompletableFuture.runAsync(() -> {
286 this.easter = new Easter();
287 this.setTitle(this.easter.getTodaysBirth());
289 this.logger.debug("Version: {}", CheckVersion.getVersion());
290 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
291 // this.setBounds(100, 100, 960, 643);
292 this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
293 this.setContentPane(this.contentPane);
294 contentPane.setLayout(new CardLayout(0, 0));
296 panelMain = new JPanel();
297 panelMain.setLayout(new BorderLayout(0, 0));
299 panelNorthMain = new JPanel();
300 panelMain.add(panelNorthMain, BorderLayout.NORTH);
301 panelNorthMain.setLayout(new FormLayout(new ColumnSpec[] {
302 ColumnSpec.decode("829px"),
303 FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
304 ColumnSpec.decode("center:94px"),},
306 RowSpec.decode("20px"),}));
308 labelTitle = new JLabel(Messages.MSGTitle.toString());
309 labelTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 16));
310 panelNorthMain.add(labelTitle, "1, 1, center, top");
312 labelVersion = new JLabel(CheckVersion.getVersion());
313 labelVersion.setFont(new Font("SansSerif", Font.BOLD, 12));
314 panelNorthMain.add(labelVersion, "3, 1, center, center");
316 panelWestMain = new JPanel();
317 panelMain.add(panelWestMain, BorderLayout.WEST);
318 panelWestMain.setLayout(new FormLayout(new ColumnSpec[] {
319 FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
320 ColumnSpec.decode("120px"),},
322 FormSpecs.LINE_GAP_ROWSPEC,
323 RowSpec.decode("25px"),
324 FormSpecs.RELATED_GAP_ROWSPEC,
325 FormSpecs.DEFAULT_ROWSPEC,
326 FormSpecs.RELATED_GAP_ROWSPEC,
327 FormSpecs.DEFAULT_ROWSPEC,
328 FormSpecs.RELATED_GAP_ROWSPEC,
329 FormSpecs.DEFAULT_ROWSPEC,
330 FormSpecs.RELATED_GAP_ROWSPEC,
331 FormSpecs.DEFAULT_ROWSPEC,
332 FormSpecs.RELATED_GAP_ROWSPEC,
333 FormSpecs.DEFAULT_ROWSPEC,
334 FormSpecs.RELATED_GAP_ROWSPEC,
335 FormSpecs.DEFAULT_ROWSPEC,
336 FormSpecs.RELATED_GAP_ROWSPEC,
337 RowSpec.decode("max(41dlu;default)"),}));
339 labelDifficulty = new JLabel(Messages.MSGSelectDifficulty.toString());
340 labelDifficulty.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
341 panelWestMain.add(labelDifficulty, "2, 2, center, center");
343 comboDifficultySelect = new JComboBox<>();
344 comboDifficultySelect.setModel(new DefaultComboBoxModel(new String[] {Messages.MSGNonSelected.toString(), "DEBUT", "REGULAR", "PRO", "MASTER", "MASTER+", "ⓁMASTER+", "LIGHT", "TRICK", "PIANO", "FORTE", "WITCH"}));
345 comboDifficultySelect.setFont(new Font("Dialog", Font.BOLD, 12));
346 panelWestMain.add(comboDifficultySelect, "2, 4, fill, fill");
348 comboAttribute = new JComboBox<>();
349 comboAttribute.setModel(new DefaultComboBoxModel(new String[] {Messages.MSGNonSelected.toString(), "全タイプ", "キュート", "クール", "パッション"}));
350 comboAttribute.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
351 panelWestMain.add(comboAttribute, "2, 6, fill, top");
353 labelLevel = new JLabel(Messages.MSGSongLevel.toString());
354 labelLevel.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
355 panelWestMain.add(labelLevel, "2, 8, center, center");
357 spinnerLevel = new JSpinner();
358 panelWestMain.add(spinnerLevel, "2, 10, fill, center");
360 checkLessLv = new JCheckBox(Messages.MSGBelowSpecificLevel.toString());
361 checkLessLv.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
362 panelWestMain.add(checkLessLv, "2, 12, left, top");
364 checkMoreLv = new JCheckBox(Messages.MSGOverSpecificLevel.toString());
365 checkMoreLv.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
366 panelWestMain.add(checkMoreLv, "2, 14, left, top");
368 labelLvCaution = new JLabel(Messages.MSGLevelCheckboxInfo.toString());
369 labelLvCaution.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
370 panelWestMain.add(labelLvCaution, "2, 16, left, center");
372 panelEastMain = new JPanel();
373 panelMain.add(panelEastMain, BorderLayout.EAST);
374 panelEastMain.setLayout(new FormLayout(new ColumnSpec[] {
375 FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
376 ColumnSpec.decode("100px"),},
378 FormSpecs.LINE_GAP_ROWSPEC,
379 RowSpec.decode("77px"),
380 FormSpecs.RELATED_GAP_ROWSPEC,
381 FormSpecs.DEFAULT_ROWSPEC,
382 FormSpecs.RELATED_GAP_ROWSPEC,
383 FormSpecs.DEFAULT_ROWSPEC,
384 FormSpecs.RELATED_GAP_ROWSPEC,
385 FormSpecs.DEFAULT_ROWSPEC,
386 FormSpecs.RELATED_GAP_ROWSPEC,
387 RowSpec.decode("max(36dlu;default)"),
388 FormSpecs.RELATED_GAP_ROWSPEC,
389 FormSpecs.DEFAULT_ROWSPEC,}));
391 btnImport = new JButton(Messages.MSGUpdatingDatabase.toString());
392 btnImport.addActionListener(e -> {
393 CompletableFuture.runAsync(() -> {
395 if(!impl.getFlag()) {
396 JOptionPane.showMessageDialog(null, Messages.MSGManualUpdateNotCompleteYet.toString());
399 ArrayList<Song> fromJson = Scraping.getFromJson();
400 ArrayList<Song> specificlevelList = Scraping.getSpecificLevelSongs(fromJson, (Integer)DelesteRandomSelector.this.spinnerLevel.getValue(), DelesteRandomSelector.this.checkLessLv.isSelected(), DelesteRandomSelector.this.checkMoreLv.isSelected());
401 ArrayList<Song> specificDifficultyList = Scraping.getSpecificDifficultySongs(specificlevelList, DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().toString());
402 ArrayList<Song> specificAttributeList = Scraping.getSpecificAttributeSongs(specificDifficultyList, DelesteRandomSelector.this.comboAttribute.getSelectedItem().toString());
403 ArrayList<Song> specificTypeList = Scraping.getSpecificAlbumTypeSongs(specificAttributeList, EstimateAlbumTypeCycle.getCurrentCycle());
404 if(!selectedSongsList.isEmpty()) {
405 selectedSongsList.clear();
407 selectedSongsList.addAll((DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.MASTERPLUS) || DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.LEGACYMASTERPLUS)) ? specificTypeList : specificAttributeList);
408 DelesteRandomSelector.this.logger.info("Songs are selected.We are Ready to go.");
409 JOptionPane.showMessageDialog(null, Messages.MSGCompleteNarrowDown.toString());
410 }, es).whenCompleteAsync((ret, ex) -> {
412 logger.error("Exception was thrown during concurrent process", ex);
413 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
418 btnImport.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
419 btnImport.setEnabled(false);
420 panelEastMain.add(btnImport, "2, 2, fill, fill");
422 btnConfig = new JButton(Messages.MSGConfigurations.toString());
423 btnConfig.addActionListener(e -> {
424 CompletableFuture.runAsync(() -> {
425 ProcessBuilder builder = new ProcessBuilder("java", "-jar", "Configurations.jar");
428 } catch (IOException e1) {
429 logger.error("Exception was thrown during concurrent process", e1);
430 CrashHandler handle = new CrashHandler(new IllegalStateException(e1));
433 }, es).whenCompleteAsync((ret, ex) -> {
435 logger.error("Exception was thrown during concurrent process", ex);
436 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
441 panelEastMain.add(btnConfig, "2, 6, fill, fill");
443 btnStart = new JButton(Messages.MSGCalcStart.toString());
444 btnStart.addActionListener(e -> {
445 CompletableFuture.runAsync(() -> {
446 Random random = new Random(System.currentTimeMillis());
447 toolIntegrateList = new ArrayList<>();
448 StringBuilder paneBuilder = new StringBuilder();
449 DelesteRandomSelector.this.integratorArray = new String[DelesteRandomSelector.this.property.getSongLimit()];
450 for(int i = 0; i < DelesteRandomSelector.this.property.getSongLimit(); i++) {
451 int randomInt = random.nextInt(selectedSongsList.size());
452 String typeString = DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.MASTERPLUS) || DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.LEGACYMASTERPLUS) ? EstimateAlbumTypeCycle.getCurrentCycle() : "";
453 paneBuilder.append(i + 1)
454 .append(Messages.MSGNumberOfSongs.toString())
456 .append(selectedSongsList.get(randomInt).getAttribute())
458 .append(selectedSongsList.get(randomInt).getDifficulty())
460 .append(selectedSongsList.get(randomInt).getName())
462 .append(selectedSongsList.get(randomInt).getLevel())
466 this.integratorArray[i] = selectedSongsList.get(randomInt).getName() + "(Lv" + selectedSongsList.get(randomInt).getLevel() + ")\n";
467 toolIntegrateList.add(selectedSongsList.get(randomInt));
469 paneBuilder.append(Messages.MSGThisPhrase.toString())
470 .append(this.property.getSongLimit())
471 .append(Messages.MSGPlayPhrase.toString());
472 DelesteRandomSelector.this.textArea.setText(paneBuilder.toString());
473 DelesteRandomSelector.this.integratorBool = true;
474 DelesteRandomSelector.this.logger.info("show up completed.");
475 labelCurrentSongOrderTool.setText("null");
476 progressTool.setValue(0);
477 listToolMapDataFuture = CompletableFuture.supplyAsync(() -> {
478 List<String> data = toolIntegrateList.stream()
479 .map(s -> s.getName())
480 .collect(Collectors.toList());
481 fetchData = new FetchFromAPI(data.toArray(new String[0]));
482 return fetchData.getInformation();
484 logger.debug("api fetch inquery published");
485 }, es).whenCompleteAsync((ret, ex) -> {
487 logger.error("Exception was thrown during concurrent process", ex);
488 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
493 btnStart.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
494 panelEastMain.add(btnStart, "2, 4, fill, fill");
496 btnManualUpdate = new JButton(Messages.MSGManualUpdate.toString());
497 btnManualUpdate.addActionListener(e -> {
498 impl = new ManualUpdateThreadImpl();
499 CompletableFuture.runAsync(impl, es).whenCompleteAsync((t, u) -> {
501 logger.warn("Exception while processing update manually.", u);
502 CrashHandler handle = new CrashHandler(new IllegalStateException(u));
504 JOptionPane.showMessageDialog(null, "There was a problem during processing library update manually.\nIf this appears repeatedly, please contact developer with your app log.");
508 panelEastMain.add(btnManualUpdate, "2, 8, fill, fill");
510 btnTwitterIntegration = new JButton(Messages.MSGTwitterIntegration.toString());
511 btnTwitterIntegration.addActionListener(e -> {
512 CompletableFuture.runAsync(() -> {
513 boolean authorizationStatus = TwitterIntegration.authorization();
514 String updatedStatus = Messages.MSGUsingThisAppPhrase.toString();
515 int lengthLimit = updatedStatus.length();
516 boolean isBroken = false;
517 if(!DelesteRandomSelector.this.integratorBool) {
518 JOptionPane.showMessageDialog(null, Messages.MSGNotPlayYet.toString());
521 for (String element : DelesteRandomSelector.this.integratorArray) {
522 updatedStatus = updatedStatus + element;
523 lengthLimit += element.length();
524 if(lengthLimit > 69) {
530 updatedStatus = updatedStatus + Messages.MSGTwitterPlayOtherwisePhrase.toString() + "\n#DelesteRandomSelector #デレステ ";
532 updatedStatus = updatedStatus + Messages.MSGTwitterPlayOnlyPhrase.toString() + "\n#DelesteRandomSelector #デレステ ";
534 DelesteRandomSelector.this.logger.info("status message constructed.");
535 lengthLimit = updatedStatus.length();
536 if(authorizationStatus) {
537 int option = JOptionPane.showConfirmDialog(null, Messages.MSGTwitterIntegrationConfirm.toString() + updatedStatus + Messages.MSGStringLength.toString() + lengthLimit);
538 DelesteRandomSelector.this.logger.info("user seletced: " + option);
540 case JOptionPane.OK_OPTION:
541 TwitterIntegration.PostTwitter(updatedStatus);
542 DelesteRandomSelector.this.logger.info("Success to update the status.");
543 JOptionPane.showMessageDialog(null, Messages.MSGCompletePost.toString());
545 case JOptionPane.NO_OPTION:
546 DelesteRandomSelector.this.logger.info("There is no will to post.");
548 case JOptionPane.CANCEL_OPTION:
549 DelesteRandomSelector.this.logger.info("The Operation was canceled by user.");
555 DelesteRandomSelector.this.logger.info("seems to reject the permission.it should need try again.");
557 }, es).whenCompleteAsync((ret, ex) -> {
559 logger.error("Exception was thrown during concurrent process", ex);
560 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
565 btnTwitterIntegration.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 11));
566 panelEastMain.add(btnTwitterIntegration, "2, 10, fill, fill");
568 btnExit = new JButton(Messages.MSGTerminate.toString());
569 btnExit.addActionListener(e -> {
570 if(DelesteRandomSelector.this.softwareUpdateFuture.isDone() || DelesteRandomSelector.this.albumTypeEstimateFuture.isDone() || !this.impl.getFlag()) {
571 DelesteRandomSelector.this.logger.info("Requested Exit by Button.");
572 logger.info("Shut down thread pool.");
576 JOptionPane.showMessageDialog(null, Messages.MSGInternalYpdateNotDoneYet.toString());
579 btnExit.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
580 panelEastMain.add(btnExit, "2, 12, fill, fill");
582 panelCenterMain = new JPanel();
583 panelMain.add(panelCenterMain, BorderLayout.CENTER);
584 panelCenterMain.setLayout(new BorderLayout(0, 0));
586 scrollPane = new JScrollPane();
587 panelCenterMain.add(scrollPane);
589 textArea = new JTextArea();
590 textArea.setText(Messages.MSGNarrowDownProcedure.toString() + property.getSongLimit() + Messages.MSGCurrentAlbumType.toString() + albumType);
591 textArea.setEditable(false);
592 scrollPane.setViewportView(textArea);
594 tabbedPane = new JTabbedPane(JTabbedPane.TOP);
595 tabbedPane.addChangeListener(e -> {
596 CompletableFuture.runAsync(() -> {
597 labelToolProgress.setText(Messages.MSGAPIWaitAPIFetch.toString());
598 String currentTabName = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
599 if(currentTabName.equals("SongInfo") && labelCurrentSongOrderTool.getText().equals("null")) {
600 logger.info("Detected switching tool tab");
601 listToolMapData = listToolMapDataFuture.join();
602 if(toolIntegrateList == null) {
605 Song firstSong = toolIntegrateList.get(0);
606 Map<String, String> fetchMap = new HashMap<>();
607 for(Map<String, String> tmpMap : listToolMapData) {
608 String normalizeApiName = Normalizer.normalize(tmpMap.get("songname").toString(), Normalizer.Form.NFKD);
609 String normalizeLocalName = Normalizer.normalize(firstSong.getName(), Normalizer.Form.NFKD);
610 if(normalizeApiName.equals(normalizeLocalName)) {
615 labelSongNameToolTip.setText(firstSong.getName());
616 labelAttributeToolTip.setText(firstSong.getAttribute());
617 labelDifficultyToolTip.setText(firstSong.getDifficulty());
618 labelLevelToolTip.setText(String.valueOf(firstSong.getLevel()));
619 labelNotesToolTip.setText(String.valueOf(firstSong.getNotes()));
620 labelCurrentSongOrderTool.setText("1");
621 labelLyricToolTip.setText(fetchMap.get("lyric"));
622 labelComposerToolTip.setText(fetchMap.get("composer"));
623 labelArrangeToolTip.setText(fetchMap.get("arrange"));
624 labelMemberToolTip.setText("<html><body>" + fetchMap.get("member") + "</html></body>");
626 }, es).whenCompleteAsync((ret, ex) -> {
627 labelToolProgress.setText("Information parse Complete.");
629 logger.error("Exception was thrown during concurrent process", ex);
630 CrashHandler handle = new CrashHandler(new IllegalStateException(ex));
635 tabbedPane.addTab("Main", null, panelMain, null);
636 contentPane.add(tabbedPane, "name_307238585319500");
638 panelInfo = new JPanel();
639 tabbedPane.addTab("SongInfo", null, panelInfo, null);
640 panelInfo.setLayout(new BorderLayout(0, 0));
642 panelNorthTool = new JPanel();
643 panelInfo.add(panelNorthTool, BorderLayout.NORTH);
644 panelNorthTool.setLayout(new FormLayout(new ColumnSpec[] {
645 ColumnSpec.decode("center:max(524dlu;default)"),
646 FormSpecs.RELATED_GAP_COLSPEC,
647 ColumnSpec.decode("max(30dlu;default)"),},
649 RowSpec.decode("max(16dlu;default)"),}));
651 labelSubToolTitle = new JLabel("楽曲情報");
652 labelSubToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 16));
653 panelNorthTool.add(labelSubToolTitle, "1, 1");
655 labelVersionTool = new JLabel(CheckVersion.getVersion());
656 labelVersionTool.setFont(new Font("SansSerif", Font.BOLD, 12));
657 panelNorthTool.add(labelVersionTool, "3, 1");
659 panelCenterTool = new JPanel();
660 panelInfo.add(panelCenterTool, BorderLayout.CENTER);
661 panelCenterTool.setLayout(new FormLayout(new ColumnSpec[] {
662 FormSpecs.RELATED_GAP_COLSPEC,
663 ColumnSpec.decode("max(40dlu;default)"),
664 FormSpecs.RELATED_GAP_COLSPEC,
665 ColumnSpec.decode("10dlu"),
666 FormSpecs.RELATED_GAP_COLSPEC,
667 ColumnSpec.decode("10dlu"),
668 FormSpecs.RELATED_GAP_COLSPEC,
669 ColumnSpec.decode("max(12dlu;default)"),
670 FormSpecs.RELATED_GAP_COLSPEC,
671 ColumnSpec.decode("max(90dlu;default)"),
672 FormSpecs.RELATED_GAP_COLSPEC,
673 ColumnSpec.decode("max(14dlu;default)"),
674 FormSpecs.RELATED_GAP_COLSPEC,
675 FormSpecs.RELATED_GAP_COLSPEC,
676 ColumnSpec.decode("max(14dlu;default)"),
677 FormSpecs.RELATED_GAP_COLSPEC,
678 ColumnSpec.decode("max(90dlu;default)"),
679 FormSpecs.RELATED_GAP_COLSPEC,
680 FormSpecs.DEFAULT_COLSPEC,
681 FormSpecs.RELATED_GAP_COLSPEC,
682 FormSpecs.DEFAULT_COLSPEC,
683 FormSpecs.RELATED_GAP_COLSPEC,
684 FormSpecs.DEFAULT_COLSPEC,
685 FormSpecs.RELATED_GAP_COLSPEC,
686 ColumnSpec.decode("max(90dlu;default)"),},
688 FormSpecs.RELATED_GAP_ROWSPEC,
689 FormSpecs.DEFAULT_ROWSPEC,
690 FormSpecs.RELATED_GAP_ROWSPEC,
691 FormSpecs.DEFAULT_ROWSPEC,
692 FormSpecs.RELATED_GAP_ROWSPEC,
693 FormSpecs.DEFAULT_ROWSPEC,
694 FormSpecs.RELATED_GAP_ROWSPEC,
695 FormSpecs.DEFAULT_ROWSPEC,
696 FormSpecs.RELATED_GAP_ROWSPEC,
697 FormSpecs.DEFAULT_ROWSPEC,
698 FormSpecs.RELATED_GAP_ROWSPEC,
699 FormSpecs.DEFAULT_ROWSPEC,
700 FormSpecs.RELATED_GAP_ROWSPEC,
701 FormSpecs.DEFAULT_ROWSPEC,
702 FormSpecs.RELATED_GAP_ROWSPEC,
703 FormSpecs.DEFAULT_ROWSPEC,
704 FormSpecs.RELATED_GAP_ROWSPEC,
705 FormSpecs.DEFAULT_ROWSPEC,
706 FormSpecs.RELATED_GAP_ROWSPEC,
707 FormSpecs.DEFAULT_ROWSPEC,
708 FormSpecs.RELATED_GAP_ROWSPEC,
709 FormSpecs.DEFAULT_ROWSPEC,
710 FormSpecs.RELATED_GAP_ROWSPEC,
711 FormSpecs.DEFAULT_ROWSPEC,
712 FormSpecs.RELATED_GAP_ROWSPEC,
713 FormSpecs.DEFAULT_ROWSPEC,
714 FormSpecs.RELATED_GAP_ROWSPEC,
715 FormSpecs.DEFAULT_ROWSPEC,
716 FormSpecs.RELATED_GAP_ROWSPEC,
717 FormSpecs.DEFAULT_ROWSPEC,
718 FormSpecs.RELATED_GAP_ROWSPEC,
719 FormSpecs.DEFAULT_ROWSPEC,
720 FormSpecs.RELATED_GAP_ROWSPEC,
721 FormSpecs.DEFAULT_ROWSPEC,
722 FormSpecs.RELATED_GAP_ROWSPEC,
723 FormSpecs.DEFAULT_ROWSPEC,
724 FormSpecs.RELATED_GAP_ROWSPEC,
725 FormSpecs.DEFAULT_ROWSPEC,
726 FormSpecs.RELATED_GAP_ROWSPEC,
727 FormSpecs.DEFAULT_ROWSPEC,
728 FormSpecs.RELATED_GAP_ROWSPEC,
729 FormSpecs.DEFAULT_ROWSPEC,}));
731 labelInfoPlaySongs = new JLabel(Messages.MSGInfoPlayedSongs.toString());
732 labelInfoPlaySongs.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
733 panelCenterTool.add(labelInfoPlaySongs, "2, 2, center, default");
735 labelSongNameToolTitle = new JLabel(Messages.MSGInfoSongName.toString());
736 labelSongNameToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
737 panelCenterTool.add(labelSongNameToolTitle, "2, 6, center, default");
739 labelSongNameToolTip = new JLabel(Messages.MSGInfoWait.toString());
740 labelSongNameToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
741 panelCenterTool.add(labelSongNameToolTip, "10, 6, center, default");
743 labelLyricToolTitle = new JLabel(Messages.MSGInfoLyricsBy.toString());
744 labelLyricToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
745 panelCenterTool.add(labelLyricToolTitle, "17, 6, center, default");
747 labelLyricToolTip = new JLabel(Messages.MSGInfoWait.toString());
748 labelLyricToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
749 panelCenterTool.add(labelLyricToolTip, "25, 6, center, default");
751 labelAttributeToolTitle = new JLabel(Messages.MSGInfoSongAttribute.toString());
752 labelAttributeToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
753 panelCenterTool.add(labelAttributeToolTitle, "2, 10, center, default");
755 labelAttributeToolTip = new JLabel(Messages.MSGInfoWait.toString());
756 labelAttributeToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
757 panelCenterTool.add(labelAttributeToolTip, "10, 10, center, default");
759 labelComposerToolTitle = new JLabel(Messages.MSGInfoComposedBy.toString());
760 labelComposerToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
761 panelCenterTool.add(labelComposerToolTitle, "17, 10, center, default");
763 labelComposerToolTip = new JLabel(Messages.MSGInfoWait.toString());
764 labelComposerToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
765 panelCenterTool.add(labelComposerToolTip, "25, 10, center, default");
767 labelDifficultyToolTitle = new JLabel(Messages.MSGInfoSongDifficulty.toString());
768 labelDifficultyToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
769 panelCenterTool.add(labelDifficultyToolTitle, "2, 14, center, default");
771 labelDifficultyToolTip = new JLabel(Messages.MSGInfoWait.toString());
772 labelDifficultyToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
773 panelCenterTool.add(labelDifficultyToolTip, "10, 14, center, default");
775 labelArrangeToolTitle = new JLabel(Messages.MSGInfoArrangedBy.toString());
776 labelArrangeToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
777 panelCenterTool.add(labelArrangeToolTitle, "17, 14, center, default");
779 labelArrangeToolTip = new JLabel(Messages.MSGInfoWait.toString());
780 labelArrangeToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
781 panelCenterTool.add(labelArrangeToolTip, "25, 14, center, default");
783 labelLevelToolTitle = new JLabel(Messages.MSGInfoSongLevel.toString());
784 labelLevelToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
785 panelCenterTool.add(labelLevelToolTitle, "2, 18, center, default");
787 labelLevelToolTip = new JLabel(Messages.MSGInfoWait.toString());
788 labelLevelToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
789 panelCenterTool.add(labelLevelToolTip, "10, 18, center, default");
791 labelMemberToolTitle = new JLabel(Messages.MSGInfoMember.toString());
792 labelMemberToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
793 panelCenterTool.add(labelMemberToolTitle, "17, 18, center, default");
795 labelMemberToolTip = new JLabel(Messages.MSGInfoWait.toString());
796 labelMemberToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
797 panelCenterTool.add(labelMemberToolTip, "25, 18, center, default");
799 labelNotesToolTitle = new JLabel(Messages.MSGInfoSongNotes.toString());
800 labelNotesToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
801 panelCenterTool.add(labelNotesToolTitle, "2, 22, center, default");
803 labelNotesToolTip = new JLabel(Messages.MSGInfoWait.toString());
804 labelNotesToolTip.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
805 panelCenterTool.add(labelNotesToolTip, "10, 22, center, default");
807 btnNextSongTool = new JButton("next");
808 btnNextSongTool.addActionListener(e -> {
809 CompletableFuture.runAsync(() -> {
810 int currentIndex = Integer.parseInt(labelCurrentSongOrderTool.getText()) - 1;
811 if(currentIndex != property.getSongLimit() - 1) {
812 Song nextSong = toolIntegrateList.get(currentIndex + 1);
813 logger.info("currently : {} Next: {}", currentIndex + 1, currentIndex + 2);
814 logger.info("nextSong: {}", nextSong);
815 Map<String, String> fetchMap = new HashMap<>();
816 for(Map<String, String> tmpMap : listToolMapData) {
817 String normalizeApiName = Normalizer.normalize(tmpMap.get("songname").toString(), Normalizer.Form.NFKD);
818 String normalizeLocalName = Normalizer.normalize(nextSong.getName(), Normalizer.Form.NFKD);
819 if(normalizeApiName.equals(normalizeLocalName)) {
824 labelSongNameToolTip.setText(nextSong.getName());
825 labelAttributeToolTip.setText(nextSong.getAttribute());
826 labelDifficultyToolTip.setText(nextSong.getDifficulty());
827 labelLevelToolTip.setText(String.valueOf(nextSong.getLevel()));
828 labelNotesToolTip.setText(String.valueOf(nextSong.getNotes()));
829 labelCurrentSongOrderTool.setText(String.valueOf(currentIndex + 2));
830 labelLyricToolTip.setText(fetchMap.get("lyric"));
831 labelComposerToolTip.setText(fetchMap.get("composer"));
832 labelArrangeToolTip.setText(fetchMap.get("arrange"));
833 labelMemberToolTip.setText("<html><body>" + fetchMap.get("member") + "</html></body>");
835 }, es).whenCompleteAsync((ret, ex) -> {
837 logger.error("Exception was thrown during concurrent process", ex);
842 btnPrevSongTool = new JButton("prev");
843 btnPrevSongTool.addActionListener(e -> {
844 CompletableFuture.runAsync(() -> {
845 int currentIndex = Integer.parseInt(labelCurrentSongOrderTool.getText()) - 1;
846 if(currentIndex != 0) {
847 Song prevSong = toolIntegrateList.get(currentIndex - 1);
848 logger.info("currently : {} Next: {}", currentIndex + 1, currentIndex);
849 logger.info("prevSong: {}", prevSong);
850 Map<String, String> fetchMap = new HashMap<>();
851 for(Map<String, String> tmpMap : listToolMapData) {
852 String normalizeApiName = Normalizer.normalize(tmpMap.get("songname").toString(), Normalizer.Form.NFKD);
853 String normalizeLocalName = Normalizer.normalize(prevSong.getName(), Normalizer.Form.NFKD);
854 if(normalizeApiName.equals(normalizeLocalName)) {
859 labelSongNameToolTip.setText(prevSong.getName());
860 labelAttributeToolTip.setText(prevSong.getAttribute());
861 labelDifficultyToolTip.setText(prevSong.getDifficulty());
862 labelLevelToolTip.setText(String.valueOf(prevSong.getLevel()));
863 labelNotesToolTip.setText(String.valueOf(prevSong.getNotes()));
864 labelCurrentSongOrderTool.setText(String.valueOf(currentIndex));
865 labelLyricToolTip.setText(fetchMap.get("lyric"));
866 labelComposerToolTip.setText(fetchMap.get("composer"));
867 labelArrangeToolTip.setText(fetchMap.get("arrange"));
868 labelMemberToolTip.setText("<html><body>" + fetchMap.get("member") + "</html></body>");
870 }, es).whenCompleteAsync((ret, ex) -> {
872 logger.error("Exception was thrown during concurrent process", ex);
876 btnPrevSongTool.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
877 panelCenterTool.add(btnPrevSongTool, "10, 28");
879 labelCurrentSongOrderTool = new JLabel("null");
880 panelCenterTool.add(labelCurrentSongOrderTool, "12, 28");
882 labelSlashTool = new JLabel("/");
883 panelCenterTool.add(labelSlashTool, "14, 28");
885 labelSongLimitTool = new JLabel(String.valueOf(this.property.getSongLimit()));
886 panelCenterTool.add(labelSongLimitTool, "15, 28");
887 btnNextSongTool.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
888 panelCenterTool.add(btnNextSongTool, "17, 28");
890 btnMoreInfoTool = new JButton(Messages.MSGInfoOpenBrowser.toString());
891 btnMoreInfoTool.addActionListener(e -> {
892 CompletableFuture.runAsync(() -> {
893 int currentIndex = Integer.parseInt(labelCurrentSongOrderTool.getText()) - 1;
894 Song currentSong = toolIntegrateList.get(currentIndex);
895 Map<String, String> fetchMap = new HashMap<>();
896 for(Map<String, String> tmpMap : listToolMapData) {
897 String normalizeApiName = Normalizer.normalize(tmpMap.get("songname").toString(), Normalizer.Form.NFKD);
898 String normalizeLocalName = Normalizer.normalize(currentSong.getName(), Normalizer.Form.NFKD);
899 if(normalizeApiName.equals(normalizeLocalName)) {
904 Desktop desk = Desktop.getDesktop();
905 String api = fetchMap.get("link");
909 logger.info("Opening default browser with : {}", uri);
911 } catch (URISyntaxException | IOException e1) {
912 JOptionPane.showMessageDialog(null, "このメッセージは仮です。Exception : " + e1.getClass().getSimpleName());
913 logger.error("Exception while opening default browser.", e1);
915 }, es).whenCompleteAsync((ret, ex) -> {
917 logger.warn("Exception was thrown during action events.", ex);
921 btnMoreInfoTool.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
922 panelCenterTool.add(btnMoreInfoTool, "25, 28");
924 labelToolProgress = new JLabel(Messages.MSGAPIWaitAPIFetch.toString());
925 labelToolProgress.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
926 panelCenterTool.add(labelToolProgress, "10, 32, center, default");
928 progressTool = new JProgressBar();
929 progressTool.setStringPainted(true);
930 progressTool.setValue(0);
931 progressTool.setMaximum(property.getSongLimit());
932 panelCenterTool.add(progressTool, "17, 32");
934 labelInfoProgressSongName = new JLabel("Processing:");
935 labelInfoProgressSongName.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 12));
936 panelCenterTool.add(labelInfoProgressSongName, "10, 34");
938 panelScore = new JPanel();
939 tabbedPane.addTab("Scores", null, panelScore, null);
940 panelScore.setLayout(new BorderLayout(0, 0));
942 panelScoreNorth = new JPanel();
943 panelScore.add(panelScoreNorth, BorderLayout.NORTH);
944 panelScoreNorth.setLayout(new FormLayout(new ColumnSpec[] {
945 ColumnSpec.decode("828px"),
946 FormSpecs.RELATED_GAP_COLSPEC,
947 ColumnSpec.decode("max(53dlu;default)"),},
949 RowSpec.decode("20px"),}));
951 labelScoreTitle = new JLabel("スコア、ファン計算");
952 labelScoreTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 16));
953 panelScoreNorth.add(labelScoreTitle, "1, 1, center, center");
955 labelScoreVersion = new JLabel(CheckVersion.getVersion());
956 labelScoreVersion.setFont(new Font("SansSerif", Font.BOLD, 12));
957 panelScoreNorth.add(labelScoreVersion, "3, 1, center, default");
959 panelScoreCenter = new JPanel();
960 panelScore.add(panelScoreCenter, BorderLayout.CENTER);
961 if(isFirst || !this.property.isCheckLibraryUpdates()) {