1010import java .util .MissingResourceException ;
1111import java .util .ResourceBundle ;
1212
13+ import org .jetbrains .annotations .NotNull ;
14+ import org .jetbrains .annotations .Nullable ;
1315import org .kohsuke .github .GitHub ;
1416import org .kohsuke .github .GitHubBuilder ;
1517import org .kohsuke .github .GHRelease ;
1618import org .kohsuke .github .GHRepository ;
1719
20+
1821/**
1922 * 负责构建和管理所有用户界面元素(菜单、按钮、对话框)
2023 */
@@ -26,7 +29,7 @@ public class GobangGameUI {
2629 private JComboBox <String > languageComboBox ;
2730
2831 // UI组件引用 (由GobangGame持有)
29- private JButton undoBtn , restartBtn , closeBtn , loadBtn , saveBtn ;
32+ private JButton undoBtn , restartBtn , closeBtn , loadBtn , saveBtn , updateBtn ;
3033 private JMenuItem openItem , saveItem , closeItem , undoItem , restartItem , settingItem , aboutItem ;
3134 private JMenu fileMenu , gameMenu , toolsMenu , aboutMenu ;
3235 private JLabel aiState , version ;
@@ -37,17 +40,25 @@ public GobangGameUI(GobangGame game, Locale initialLocale) {
3740 }
3841
3942 public double GetLatestVer () {
40- GHRelease release ;
41- try {
42- GitHub github = new GitHubBuilder ().withOAuthToken ("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" ).build ();
43- GHRepository repo = github .getRepository ("QIU2014/GobangGame" );
44- release = repo .getLatestRelease ();
45- double latestVer = Double .parseDouble (String .format ("%s" , release .getTagName ()).replace ("GobangGame_v" , "" ));
46- return latestVer ;
47- } catch (IOException e ) {
48- e .printStackTrace ();
49- return 0.0 ;
50- }
43+ try {
44+ GitHub github = new GitHubBuilder ().withOAuthToken ("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" ).build ();
45+ GHRepository repo = github .getRepository ("QIU2014/GobangGame" );
46+ GHRelease release = repo .getLatestRelease ();
47+ double latestVer = Double .parseDouble (String .format ("%s" , release .getTagName ()).replace ("GoBangGame_v" , "" ));
48+ return latestVer ;
49+ } catch (IOException e ) {
50+ e .printStackTrace ();
51+ return 0.0 ;
52+ }
53+ }
54+
55+ public String GetUpdateDownloadURI () throws IOException , URISyntaxException {
56+ GitHub github = new GitHubBuilder ().withOAuthToken ("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" ).build ();
57+ GHRepository repo = github .getRepository ("QIU2014/GobangGame" );
58+ GHRelease release = repo .getLatestRelease ();
59+ String updateDownloadURI = String .format ("https://github.com/QIU2014/GoBangGame/releases/tag/%s" , release .getTagName ());
60+ System .out .println (updateDownloadURI );
61+ return updateDownloadURI ;
5162 }
5263
5364 public ResourceBundle getMessages () {
@@ -109,6 +120,7 @@ public JPanel createButtonPanel() {
109120 // 回到原来的FlowLayout,但减少垂直间距
110121 buttonPanel .setLayout (new FlowLayout (FlowLayout .CENTER , 0 , 30 ));
111122 buttonPanel .setPreferredSize (new Dimension (game .getBUTTON_WIDTH (), game .getHeight ()));
123+ this .updateBtn = new JButton ("Update" );
112124 this .saveBtn = new JButton (messages .getString ("button.save" ));
113125 this .loadBtn = new JButton (messages .getString ("button.load" ));
114126 this .undoBtn = new JButton (messages .getString ("button.undo" ));
@@ -117,13 +129,62 @@ public JPanel createButtonPanel() {
117129
118130 this .aiState = new JLabel ("AI: IDLE" , SwingConstants .CENTER );
119131 try {
120- if (GetLatestVer () > GobangGame .VERSION ) {
121- this .version = new JLabel (messages .getString ("version.update" ) + "v" + GetLatestVer (), SwingConstants .CENTER );
122- version .setForeground (Color .RED );
123- } else {
124- this .version = new JLabel ("Version" + GobangGame .VERSION , SwingConstants .CENTER );
125- version .setForeground (Color .GREEN );
126- }
132+ // Initialize with "Please wait..."
133+ this .version = new JLabel ("Please wait..." , SwingConstants .CENTER );
134+ version .setForeground (Color .GRAY );
135+
136+ SwingWorker <Double , Void > versionWorker = new SwingWorker <Double , Void >() {
137+ @ Override
138+ protected Double doInBackground () throws Exception {
139+ return GetLatestVer ();
140+ }
141+
142+ @ Override
143+ protected void done () {
144+ try {
145+ double latestVer = get (); // This gets the result from doInBackground()
146+
147+ try {
148+ if (latestVer > GobangGame .VERSION ) {
149+ version .setText (messages .getString ("version.update" ) + "v" + latestVer );
150+ version .setForeground (Color .RED );
151+ updateBtn .addActionListener (e -> {
152+ try {
153+ Desktop .getDesktop ().browse (new URI (GetUpdateDownloadURI ()));
154+ JOptionPane .showMessageDialog (JOptionPane .getRootFrame (), "A browser window opened to the download page!" );
155+ } catch (IOException | URISyntaxException ex ) {
156+ throw new RuntimeException (ex );
157+ }
158+ });
159+ } else {
160+ version .setText ("Version " + GobangGame .VERSION );
161+ version .setForeground (Color .GREEN );
162+ updateBtn .addActionListener (e -> {
163+ JOptionPane .showMessageDialog (JOptionPane .getRootFrame (), "There are no updates Yet!" , "No Update Yet!" , JOptionPane .INFORMATION_MESSAGE );
164+ });
165+ }
166+ } catch (MissingResourceException e ) {
167+ e .printStackTrace ();
168+ System .out .println ("Missing resource! Falling back to hard-coded" );
169+ if (latestVer > GobangGame .VERSION ) {
170+ version .setText ("Update detected: v" + latestVer );
171+ version .setForeground (Color .RED );
172+ } else {
173+ version .setText ("GobangGame v" + GobangGame .VERSION );
174+ version .setForeground (Color .GREEN );
175+ }
176+ }
177+
178+ } catch (Exception e ) {
179+ e .printStackTrace ();
180+ version .setText ("Error checking version" );
181+ version .setForeground (Color .ORANGE );
182+ updateBtn .disable ();
183+ }
184+ }
185+ };
186+
187+ versionWorker .execute ();
127188 } catch (MissingResourceException e ) {
128189 e .printStackTrace ();
129190 System .out .println ("Missing resource! Falling back to hard-coded" );
@@ -139,13 +200,15 @@ public JPanel createButtonPanel() {
139200 Dimension btnSize = new Dimension (game .getBUTTON_WIDTH (), game .getBUTTON_HEIGHT ());
140201
141202 // 设置按钮属性
203+ updateBtn .setPreferredSize (btnSize );
142204 saveBtn .setPreferredSize (btnSize );
143205 loadBtn .setPreferredSize (btnSize );
144206 undoBtn .setPreferredSize (btnSize );
145207 restartBtn .setPreferredSize (btnSize );
146208 closeBtn .setPreferredSize (btnSize );
147209
148210 Font font = new Font ("宋体" , Font .PLAIN , 14 );
211+ updateBtn .setFont (font );
149212 saveBtn .setFont (font );
150213 loadBtn .setFont (font );
151214 undoBtn .setFont (font );
@@ -165,6 +228,7 @@ public JPanel createButtonPanel() {
165228 closeBtn .addActionListener (e -> System .exit (0 ));
166229
167230 // 直接添加组件到buttonPanel
231+ buttonPanel .add (updateBtn );
168232 buttonPanel .add (saveBtn );
169233 buttonPanel .add (loadBtn );
170234 buttonPanel .add (undoBtn );
0 commit comments