OSDN Git Service

chore: add rows
[delesterandomselector/DelesteRandomSelector.git] / src / com / ranfa / main / DelesteRandomSelector.java
1 package com.ranfa.main;
2
3 import java.awt.BorderLayout;
4 import java.awt.CardLayout;
5 import java.awt.EventQueue;
6 import java.awt.Font;
7 import java.io.IOException;
8 import java.nio.file.Files;
9 import java.nio.file.Paths;
10 import java.util.ArrayList;
11 import java.util.Random;
12 import java.util.concurrent.CompletableFuture;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.Executors;
15 import java.util.function.BiConsumer;
16
17 import javax.swing.DefaultComboBoxModel;
18 import javax.swing.JButton;
19 import javax.swing.JCheckBox;
20 import javax.swing.JComboBox;
21 import javax.swing.JFrame;
22 import javax.swing.JLabel;
23 import javax.swing.JOptionPane;
24 import javax.swing.JPanel;
25 import javax.swing.JScrollPane;
26 import javax.swing.JSpinner;
27 import javax.swing.JTabbedPane;
28 import javax.swing.JTextArea;
29 import javax.swing.border.EmptyBorder;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.jgoodies.forms.layout.ColumnSpec;
35 import com.jgoodies.forms.layout.FormLayout;
36 import com.jgoodies.forms.layout.FormSpecs;
37 import com.jgoodies.forms.layout.RowSpec;
38 import com.ranfa.lib.CheckVersion;
39 import com.ranfa.lib.Easter;
40 import com.ranfa.lib.EstimateAlbumTypeCycle;
41 import com.ranfa.lib.ManualUpdateThreadImpl;
42 import com.ranfa.lib.Scraping;
43 import com.ranfa.lib.SettingJSONProperty;
44 import com.ranfa.lib.Settings;
45 import com.ranfa.lib.Song;
46 import com.ranfa.lib.TwitterIntegration;
47 import com.ranfa.lib.Version;
48
49 @Version(major = 3, minor = 1, patch = 0)
50 public class DelesteRandomSelector extends JFrame {
51
52     private static ArrayList<Song> selectedSongsList = new ArrayList<>();
53
54     private JPanel contentPane;
55     private SettingJSONProperty property = new SettingJSONProperty();
56     private String[] integratorArray;
57     private boolean integratorBool = false;
58     private CompletableFuture<Void> softwareUpdateFuture = null;
59     private CompletableFuture<Void> albumTypeEstimateFuture = null;
60     private String albumType = Messages.MSGAlbumTypeBeingCalculated.toString();
61     private Logger logger = LoggerFactory.getLogger(DelesteRandomSelector.class);
62     private ManualUpdateThreadImpl impl;
63     private Thread manualUpdateThread;
64     private Easter easter;
65     private JPanel panelMain;
66     private JPanel panelNorthMain;
67     private JLabel labelTitle;
68     private JLabel labelVersion;
69     private JPanel panelWestMain;
70     private JLabel labelDifficulty;
71     private JComboBox comboDifficultySelect;
72     private JComboBox comboAttribute;
73     private JLabel labelLevel;
74     private JSpinner spinnerLevel;
75     private JCheckBox checkLessLv;
76     private JCheckBox checkMoreLv;
77     private JLabel labelLvCaution;
78     private JPanel panelEastMain;
79     private JButton btnImport;
80     private JButton btnConfig;
81     private JButton btnStart;
82     private JButton btnManualUpdate;
83     private JButton btnTwitterIntegration;
84     private JButton btnExit;
85     private JPanel panelCenterMain;
86     private JScrollPane scrollPane;
87     private JTextArea textArea;
88     private JTabbedPane tabbedPane;
89     private JPanel panelTool;
90     private JPanel panelNorthTool;
91     private JLabel labelSubToolTitle;
92     private JLabel labelVersionTool;
93     private JPanel panelCenterTool;
94     private JLabel lblNewLabel;
95
96     /**
97      * Launch the application.
98      */
99     public static void main(String[] args) {
100         EventQueue.invokeLater(() -> {
101             try {
102                 DelesteRandomSelector frame = new DelesteRandomSelector();
103                 frame.setVisible(true);
104             } catch (Exception e) {
105                 e.printStackTrace();
106             }
107
108         });
109     }
110
111     /**
112      * log file prefix:
113      *  this.getClass() + ":[LEVEL]: " +
114      */
115
116     /**
117      * Create the frame.
118      */
119     public DelesteRandomSelector() {
120         this.contentPane = new JPanel();
121         boolean isFirst = !Scraping.databaseExists();
122         if(isFirst) {
123             JOptionPane.showMessageDialog(this, Messages.MSGDatabaseNotExist.toString());
124             if(!Scraping.writeToJson(Scraping.getWholeData())) {
125                 JOptionPane.showMessageDialog(this, "Exception:NullPointerException\nCannot Keep up! Please re-download this Application!");
126                 throw new NullPointerException("FATAL: cannot continue!");
127             }
128         }
129         ExecutorService es = Executors.newWorkStealingPool();
130         CompletableFuture<ArrayList<Song>> getFromJsonFuture = CompletableFuture.supplyAsync(() -> Scraping.getFromJson(), es);
131         CompletableFuture<ArrayList<Song>> getWholeDataFuture = CompletableFuture.supplyAsync(() -> Scraping.getWholeData(), es);
132         if(!Settings.fileExists() && !Settings.writeDownJSON()) {
133             JOptionPane.showMessageDialog(this, "Exception:NullPointerException\nCannot Keep up! Please re-download this Application!");
134             throw new NullPointerException("FATAL: cannot continue!");
135         }
136         this.logger.debug("Loading settings...");
137         this.property.setCheckLibraryUpdates(Settings.needToCheckLibraryUpdates());
138         this.property.setCheckVersion(Settings.needToCheckVersion());
139         this.property.setWindowWidth(Settings.getWindowWidth());
140         this.property.setWindowHeight(Settings.getWindowHeight());
141         this.property.setSongLimit(Settings.getSongsLimit());
142         this.property.setSaveScoreLog(Settings.saveScoreLog());
143         this.logger.debug("Load settings done.");
144         this.logger.debug("Version check: {}", this.property.isCheckVersion());
145         this.logger.debug("Library update check: {}", this.property.isCheckLibraryUpdates());
146         this.logger.debug("Window Width: {}", this.property.getWindowWidth());
147         this.logger.debug("Window Height: {}", this.property.getWindowHeight());
148         this.logger.debug("Song Limit: {}", this.property.getSongLimit());
149         this.logger.debug("SaveScoreLog: {}", this.property.isSaveScoreLog());
150         EstimateAlbumTypeCycle.Initialization();
151         if(Files.exists(Paths.get("generated/albumCycle.json"))) {
152             this.albumType = EstimateAlbumTypeCycle.getCurrentCycle();
153         }
154         if(this.property.isCheckVersion()) {
155             this.softwareUpdateFuture = CompletableFuture.runAsync(() -> CheckVersion.needToBeUpdated(), es);
156         }
157         BiConsumer<ArrayList<Song>, ArrayList<Song>> updateConsumer = (list1, list2) -> {
158             this.logger.info("Checking database updates...");
159             if(list1.size() > list2.size()) {
160                 long time = System.currentTimeMillis();
161                 this.logger.info("{} Update detected.", (list1.size() - list2.size()));
162                 Scraping.writeToJson(list1);
163                 this.logger.info("Update completed in {} ms", (System.currentTimeMillis() - time));
164                 this.logger.info("Updated database size: {}", list1.size());
165             } else {
166                 this.logger.info("database is up-to-date.");
167             }
168         };
169         Runnable setEnabled = () -> {
170             try {
171                 Thread.sleep(3 * 1000L);
172             } catch (InterruptedException e1) {
173                 this.logger.error("Thread has been interrupted during waiting cooldown.", e1);
174             }
175             this.btnImport.setEnabled(true);
176             this.btnImport.setText(Messages.MSGNarrowingDownSongs.toString());
177         };
178         getWholeDataFuture.thenAcceptAsync(list -> this.logger.info("Scraping data size:" + list.size()), es);
179         getFromJsonFuture.thenAcceptAsync(list -> this.logger.info("Currently database size:" + list.size()), es);
180         if(this.property.isCheckLibraryUpdates()) {
181             CompletableFuture<Void> updatedFuture = getWholeDataFuture.thenAcceptBothAsync(getFromJsonFuture, updateConsumer, es);
182             updatedFuture.thenRunAsync(setEnabled, es);
183         }
184         this.easter = new Easter();
185         this.setTitle(this.easter.getTodaysBirth());
186         this.logger.debug("Version: {}", CheckVersion.getVersion());
187         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
188         // this.setBounds(100, 100, this.property.getWindowWidth(), this.property.getWindowHeight());
189         this.setBounds(100, 100, 960, 540);
190         this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
191         this.setContentPane(this.contentPane);
192         contentPane.setLayout(new CardLayout(0, 0));
193         
194         panelMain = new JPanel();
195         panelMain.setLayout(new BorderLayout(0, 0));
196         
197         panelNorthMain = new JPanel();
198         panelMain.add(panelNorthMain, BorderLayout.NORTH);
199         panelNorthMain.setLayout(new FormLayout(new ColumnSpec[] {
200                         ColumnSpec.decode("829px"),
201                         FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
202                         ColumnSpec.decode("center:94px"),},
203                 new RowSpec[] {
204                         RowSpec.decode("20px"),}));
205         
206         labelTitle = new JLabel(Messages.MSGTitle.toString());
207         labelTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 16));
208         panelNorthMain.add(labelTitle, "1, 1, center, top");
209         
210         labelVersion = new JLabel(CheckVersion.getVersion());
211         labelVersion.setFont(new Font("SansSerif", Font.BOLD, 12));
212         panelNorthMain.add(labelVersion, "3, 1, center, center");
213         
214         panelWestMain = new JPanel();
215         panelMain.add(panelWestMain, BorderLayout.WEST);
216         panelWestMain.setLayout(new FormLayout(new ColumnSpec[] {
217                         FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
218                         ColumnSpec.decode("120px"),},
219                 new RowSpec[] {
220                         FormSpecs.LINE_GAP_ROWSPEC,
221                         RowSpec.decode("25px"),
222                         FormSpecs.RELATED_GAP_ROWSPEC,
223                         FormSpecs.DEFAULT_ROWSPEC,
224                         FormSpecs.RELATED_GAP_ROWSPEC,
225                         FormSpecs.DEFAULT_ROWSPEC,
226                         FormSpecs.RELATED_GAP_ROWSPEC,
227                         FormSpecs.DEFAULT_ROWSPEC,
228                         FormSpecs.RELATED_GAP_ROWSPEC,
229                         FormSpecs.DEFAULT_ROWSPEC,
230                         FormSpecs.RELATED_GAP_ROWSPEC,
231                         FormSpecs.DEFAULT_ROWSPEC,
232                         FormSpecs.RELATED_GAP_ROWSPEC,
233                         FormSpecs.DEFAULT_ROWSPEC,
234                         FormSpecs.RELATED_GAP_ROWSPEC,
235                         RowSpec.decode("max(41dlu;default)"),}));
236         
237         labelDifficulty = new JLabel(Messages.MSGSelectDifficulty.toString());
238         labelDifficulty.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
239         panelWestMain.add(labelDifficulty, "2, 2, center, center");
240         
241         comboDifficultySelect = new JComboBox();
242         comboDifficultySelect.setModel(new DefaultComboBoxModel(new String[] {Messages.MSGNonSelected.toString(), "DEBUT", "REGULAR", "PRO", "MASTER", "MASTER+", "ⓁMASTER+", "LIGHT", "TRICK", "PIANO", "FORTE", "WITCH"}));
243         comboDifficultySelect.setFont(new Font("Dialog", Font.BOLD, 12));
244         panelWestMain.add(comboDifficultySelect, "2, 4, fill, fill");
245         
246         comboAttribute = new JComboBox();
247         comboAttribute.setModel(new DefaultComboBoxModel(new String[] {Messages.MSGNonSelected.toString(), "全タイプ", "キュート", "クール", "パッション"}));
248         comboAttribute.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
249         panelWestMain.add(comboAttribute, "2, 6, fill, top");
250         
251         labelLevel = new JLabel(Messages.MSGSongLevel.toString());
252         labelLevel.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
253         panelWestMain.add(labelLevel, "2, 8, center, center");
254         
255         spinnerLevel = new JSpinner();
256         panelWestMain.add(spinnerLevel, "2, 10, fill, center");
257         
258         checkLessLv = new JCheckBox(Messages.MSGBelowSpecificLevel.toString());
259         checkLessLv.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
260         panelWestMain.add(checkLessLv, "2, 12, left, top");
261         
262         checkMoreLv = new JCheckBox(Messages.MSGOverSpecificLevel.toString());
263         checkMoreLv.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
264         panelWestMain.add(checkMoreLv, "2, 14, left, top");
265         
266         labelLvCaution = new JLabel(Messages.MSGLevelCheckboxInfo.toString());
267         labelLvCaution.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
268         panelWestMain.add(labelLvCaution, "2, 16, left, center");
269         
270         panelEastMain = new JPanel();
271         panelMain.add(panelEastMain, BorderLayout.EAST);
272         panelEastMain.setLayout(new FormLayout(new ColumnSpec[] {
273                         FormSpecs.LABEL_COMPONENT_GAP_COLSPEC,
274                         ColumnSpec.decode("100px"),},
275                 new RowSpec[] {
276                         FormSpecs.LINE_GAP_ROWSPEC,
277                         RowSpec.decode("77px"),
278                         FormSpecs.RELATED_GAP_ROWSPEC,
279                         FormSpecs.DEFAULT_ROWSPEC,
280                         FormSpecs.RELATED_GAP_ROWSPEC,
281                         FormSpecs.DEFAULT_ROWSPEC,
282                         FormSpecs.RELATED_GAP_ROWSPEC,
283                         FormSpecs.DEFAULT_ROWSPEC,
284                         FormSpecs.RELATED_GAP_ROWSPEC,
285                         RowSpec.decode("max(36dlu;default)"),
286                         FormSpecs.RELATED_GAP_ROWSPEC,
287                         FormSpecs.DEFAULT_ROWSPEC,}));
288         
289         btnImport = new JButton(Messages.MSGUpdatingDatabase.toString());
290         btnImport.addActionListener(e -> {
291                 if(impl != null) {
292                         if(!impl.getFlag()) {
293                                 JOptionPane.showMessageDialog(null, Messages.MSGManualUpdateNotCompleteYet.toString());
294                         }
295                 }
296                 ArrayList<Song> fromJson = Scraping.getFromJson();
297                 ArrayList<Song> specificlevelList = Scraping.getSpecificLevelSongs(fromJson, (Integer)DelesteRandomSelector.this.spinnerLevel.getValue(), DelesteRandomSelector.this.checkLessLv.isSelected(), DelesteRandomSelector.this.checkMoreLv.isSelected());
298                 ArrayList<Song> specificDifficultyList = Scraping.getSpecificDifficultySongs(specificlevelList, DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().toString());
299                 ArrayList<Song> specificAttributeList = Scraping.getSpecificAttributeSongs(specificDifficultyList, DelesteRandomSelector.this.comboAttribute.getSelectedItem().toString());
300                 ArrayList<Song> specificTypeList = Scraping.getSpecificAlbumTypeSongs(specificAttributeList, EstimateAlbumTypeCycle.getCurrentCycle());
301                 if(!selectedSongsList.isEmpty()) {
302                         selectedSongsList.clear();
303                 }
304                 selectedSongsList.addAll((DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.MASTERPLUS) || DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.LEGACYMASTERPLUS)) ? specificTypeList : specificAttributeList);
305                 DelesteRandomSelector.this.logger.info("Songs are selected.We are Ready to go.");
306                 JOptionPane.showMessageDialog(null, Messages.MSGCompleteNarrowDown.toString());
307         });
308         btnImport.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
309         btnImport.setEnabled(false);
310         panelEastMain.add(btnImport, "2, 2, fill, fill");
311         
312         btnConfig = new JButton(Messages.MSGConfigurations.toString());
313         btnConfig.addActionListener(e -> {
314                 ProcessBuilder builder = new ProcessBuilder("java", "-jar", "Configurations.jar");
315                 try {
316                         builder.start();
317                 } catch (IOException e1) {
318                         logger.error("Cannot start external jar file. maybe are you running this with mac or linux?", e);
319                 }
320         });
321         panelEastMain.add(btnConfig, "2, 6, fill, fill");
322         
323         btnStart = new JButton(Messages.MSGCalcStart.toString());
324         btnStart.addActionListener(e -> {
325                 Random random = new Random(System.currentTimeMillis());
326                 String paneString = "";
327                 DelesteRandomSelector.this.integratorArray = new String[DelesteRandomSelector.this.property.getSongLimit()];
328                 for(int i = 0; i < DelesteRandomSelector.this.property.getSongLimit(); i++) {
329                         int randomInt = random.nextInt(selectedSongsList.size());
330                         String typeString = DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.MASTERPLUS) || DelesteRandomSelector.this.comboDifficultySelect.getSelectedItem().equals(Scraping.LEGACYMASTERPLUS) ? EstimateAlbumTypeCycle.getCurrentCycle() : "";
331                         paneString = paneString + (i + 1) + Messages.MSGNumberOfSongs.toString() + " " + selectedSongsList.get(randomInt).getAttribute() + " [" + selectedSongsList.get(randomInt).getDifficulty() + "]「" + selectedSongsList.get(randomInt).getName() + "」!(Lv:" + selectedSongsList.get(randomInt).getLevel() + " " + typeString + ")\n\n";
332                         DelesteRandomSelector.this.integratorArray[i] = selectedSongsList.get(randomInt).getName() + "(Lv" + selectedSongsList.get(randomInt).getLevel() + ")\n";
333                 }
334                 paneString = paneString + Messages.MSGThisPhrase.toString() + DelesteRandomSelector.this.property.getSongLimit() + Messages.MSGPlayPhrase.toString();
335                 DelesteRandomSelector.this.textArea.setText(paneString);
336                 DelesteRandomSelector.this.integratorBool = true;
337                 DelesteRandomSelector.this.logger.info("show up completed.");
338         });
339         btnStart.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
340         panelEastMain.add(btnStart, "2, 4, fill, fill");
341         
342         btnManualUpdate = new JButton(Messages.MSGManualUpdate.toString());
343         btnManualUpdate.addActionListener(e -> {
344                 impl = new ManualUpdateThreadImpl();
345                 es.submit(impl);
346         });
347         panelEastMain.add(btnManualUpdate, "2, 8, fill, fill");
348         
349         btnTwitterIntegration = new JButton(Messages.MSGTwitterIntegration.toString());
350         btnTwitterIntegration.addActionListener(e -> {
351                 boolean authorizationStatus = TwitterIntegration.authorization();
352                 String updatedStatus = Messages.MSGUsingThisAppPhrase.toString();
353                 int lengthLimit = updatedStatus.length();
354                 boolean isBroken = false;
355                 if(!DelesteRandomSelector.this.integratorBool) {
356                         JOptionPane.showMessageDialog(null, Messages.MSGNotPlayYet.toString());
357                         return;
358                 }
359                 for (String element : DelesteRandomSelector.this.integratorArray) {
360                         updatedStatus = updatedStatus + element;
361                         lengthLimit += element.length();
362                         if(lengthLimit > 69) {
363                                 isBroken = true;
364                                 break;
365                         }
366                 }
367                 if(isBroken) {
368                         updatedStatus = updatedStatus + Messages.MSGTwitterPlayOtherwisePhrase.toString() + "\n#DelesteRandomSelector #デレステ ";
369                 } else {
370                         updatedStatus = updatedStatus + Messages.MSGTwitterPlayOnlyPhrase.toString() + "\n#DelesteRandomSelector #デレステ ";
371                 }
372                 DelesteRandomSelector.this.logger.info("status message constructed.");
373                 lengthLimit = updatedStatus.length();
374                 if(authorizationStatus) {
375                         int option = JOptionPane.showConfirmDialog(null, Messages.MSGTwitterIntegrationConfirm.toString() + updatedStatus + Messages.MSGStringLength.toString() + lengthLimit);
376                         DelesteRandomSelector.this.logger.info("user seletced: " + option);
377                         switch(option) {
378                         case JOptionPane.OK_OPTION:
379                                 TwitterIntegration.PostTwitter(updatedStatus);
380                                 DelesteRandomSelector.this.logger.info("Success to update the status.");
381                                 JOptionPane.showMessageDialog(null, Messages.MSGCompletePost.toString());
382                                 break;
383                         case JOptionPane.NO_OPTION:
384                                 DelesteRandomSelector.this.logger.info("There is no will to post.");
385                                 break;
386                         case JOptionPane.CANCEL_OPTION:
387                                 DelesteRandomSelector.this.logger.info("The Operation was canceled by user.");
388                                 break;
389                         default:
390                                 break;
391                         }
392                 } else {
393                         DelesteRandomSelector.this.logger.info("seems to reject the permission.it should need try again.");
394                 }
395         });
396         btnTwitterIntegration.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 11));
397         panelEastMain.add(btnTwitterIntegration, "2, 10, fill, fill");
398         
399         btnExit = new JButton(Messages.MSGTerminate.toString());
400         btnExit.addActionListener(e -> {
401                 if(DelesteRandomSelector.this.softwareUpdateFuture.isDone() || DelesteRandomSelector.this.albumTypeEstimateFuture.isDone() || !this.impl.getFlag()) {
402                         DelesteRandomSelector.this.logger.info("Requested Exit by Button.");
403                         logger.info("Shut down thread pool.");
404                         es.shutdown();
405                         System.exit(0);
406                 } else {
407                         JOptionPane.showMessageDialog(null, Messages.MSGInternalYpdateNotDoneYet.toString());
408                 }
409         });
410         btnExit.setFont(new Font("UD デジタル 教科書体 NP-B", Font.BOLD, 13));
411         panelEastMain.add(btnExit, "2, 12, fill, fill");
412         
413         panelCenterMain = new JPanel();
414         panelMain.add(panelCenterMain, BorderLayout.CENTER);
415         panelCenterMain.setLayout(new BorderLayout(0, 0));
416         
417         scrollPane = new JScrollPane();
418         panelCenterMain.add(scrollPane);
419         
420         textArea = new JTextArea();
421         textArea.setText(Messages.MSGNarrowDownProcedure.toString() + property.getSongLimit() + Messages.MSGCurrentAlbumType.toString() + albumType);
422         textArea.setEditable(false);
423         scrollPane.setViewportView(textArea);
424         
425         tabbedPane = new JTabbedPane(JTabbedPane.TOP);
426         tabbedPane.addTab("Main", null, panelMain, null);
427         contentPane.add(tabbedPane, "name_307238585319500");
428         
429         panelTool = new JPanel();
430         tabbedPane.addTab("SubTools", null, panelTool, null);
431         panelTool.setLayout(new BorderLayout(0, 0));
432         
433         panelNorthTool = new JPanel();
434         panelTool.add(panelNorthTool, BorderLayout.NORTH);
435         panelNorthTool.setLayout(new FormLayout(new ColumnSpec[] {
436                         ColumnSpec.decode("center:max(524dlu;default)"),
437                         FormSpecs.RELATED_GAP_COLSPEC,
438                         ColumnSpec.decode("max(30dlu;default)"),},
439                 new RowSpec[] {
440                         RowSpec.decode("max(16dlu;default)"),}));
441         
442         labelSubToolTitle = new JLabel("補助ツール");
443         labelSubToolTitle.setFont(new Font("UD デジタル 教科書体 NP-B", Font.PLAIN, 16));
444         panelNorthTool.add(labelSubToolTitle, "1, 1");
445         
446         labelVersionTool = new JLabel(CheckVersion.getVersion());
447         labelVersionTool.setFont(new Font("SansSerif", Font.BOLD, 12));
448         panelNorthTool.add(labelVersionTool, "3, 1");
449         
450         panelCenterTool = new JPanel();
451         panelTool.add(panelCenterTool, BorderLayout.CENTER);
452         panelCenterTool.setLayout(new FormLayout(new ColumnSpec[] {
453                         FormSpecs.RELATED_GAP_COLSPEC,
454                         ColumnSpec.decode("max(166dlu;default)"),},
455                 new RowSpec[] {
456                         FormSpecs.RELATED_GAP_ROWSPEC,
457                         FormSpecs.DEFAULT_ROWSPEC,}));
458         
459         lblNewLabel = new JLabel("New label");
460         panelCenterTool.add(lblNewLabel, "2, 2, center, default");
461         if(isFirst || !this.property.isCheckLibraryUpdates()) {
462             setEnabled.run();
463         }
464     }
465
466 }