@ -0,0 +1,118 @@ |
|||||||
|
package com.fr.design.onlineupdate.actions; |
||||||
|
|
||||||
|
import com.fr.design.onlineupdate.domain.UpdateConstants; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.design.onlineupdate.domain.DownloadItem; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
|
||||||
|
import javax.swing.JOptionPane; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.net.URL; |
||||||
|
import java.net.URLConnection; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public abstract class FileDownloader extends SwingWorker<Boolean, DownloadItem> { |
||||||
|
private static final int REPEAT_DOWNLOAD_TIMES = 3; |
||||||
|
private DownloadItem[] files; |
||||||
|
private String saveDir; |
||||||
|
//已经完成的大小
|
||||||
|
private long completeSize; |
||||||
|
|
||||||
|
public FileDownloader(DownloadItem[] files, String saveDir) { |
||||||
|
this.files = files; |
||||||
|
this.saveDir = saveDir; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Boolean doInBackground() throws Exception { |
||||||
|
if (ArrayUtils.isNotEmpty(files)) { |
||||||
|
setCompleteSize(0L); |
||||||
|
for (DownloadItem item : files) { |
||||||
|
for (int i = 0; i < REPEAT_DOWNLOAD_TIMES; i++) { |
||||||
|
item.setTotalLength(0); |
||||||
|
item.setDownloadLength(0); |
||||||
|
download(item); |
||||||
|
if (item.getTotalLength() == item.getDownloadLength()) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (item.getTotalLength() != item.getDownloadLength()) { |
||||||
|
JOptionPane.showMessageDialog(null, |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Download_Failed"), |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Alert"), JOptionPane.ERROR_MESSAGE); |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
item.setDownloadLength(0); |
||||||
|
completeSize += item.getTotalLength(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
boolean success = false; |
||||||
|
try { |
||||||
|
success = get(); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} catch (ExecutionException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
if (success) { |
||||||
|
onDownloadSuccess(); |
||||||
|
} else { |
||||||
|
onDownloadFailed(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void download(DownloadItem item) throws Exception { |
||||||
|
URL url = new URL(item.getUrl()); |
||||||
|
URLConnection connection = url.openConnection(); |
||||||
|
int total = connection.getContentLength(); |
||||||
|
item.setTotalLength(total); |
||||||
|
InputStream reader = connection.getInputStream(); |
||||||
|
File tempFile = new File(StableUtils.pathJoin(saveDir, item.getName())); |
||||||
|
StableUtils.makesureFileExist(tempFile); |
||||||
|
FileOutputStream writer = new FileOutputStream(tempFile); |
||||||
|
byte[] buffer = new byte[UpdateConstants.BYTE]; |
||||||
|
int bytesRead = 0; |
||||||
|
int totalBytesRead = 0; |
||||||
|
while ((bytesRead = reader.read(buffer)) != -1) { |
||||||
|
writer.write(buffer, 0, bytesRead); |
||||||
|
buffer = new byte[UpdateConstants.BYTE]; |
||||||
|
totalBytesRead += bytesRead; |
||||||
|
item.setDownloadLength(totalBytesRead); |
||||||
|
publish(item); |
||||||
|
} |
||||||
|
reader.close(); |
||||||
|
writer.close(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 下载成功 |
||||||
|
*/ |
||||||
|
public abstract void onDownloadSuccess(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 下载失败 |
||||||
|
*/ |
||||||
|
public abstract void onDownloadFailed(); |
||||||
|
|
||||||
|
public long getCompleteSize() { |
||||||
|
return completeSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCompleteSize(long completeSize) { |
||||||
|
this.completeSize = completeSize; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.fr.design.onlineupdate.actions; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.onlineupdate.ui.dialog.UpdateMainDialog; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
|
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class SoftwareUpdateAction extends UpdateAction { |
||||||
|
|
||||||
|
|
||||||
|
public SoftwareUpdateAction() { |
||||||
|
setName(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_UpdateAndUpgrade")); |
||||||
|
setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/update/update_new.png")); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 事件响应 |
||||||
|
* |
||||||
|
* @param e 事件 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
UpdateMainDialog dialog = new UpdateMainDialog(DesignerContext.getDesignerFrame()); |
||||||
|
dialog.showDialog(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,102 @@ |
|||||||
|
package com.fr.design.onlineupdate.domain; |
||||||
|
|
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class DownloadItem { |
||||||
|
|
||||||
|
//显示为百分比
|
||||||
|
private static final int PERCENTAGE_RATIO = 100; |
||||||
|
//显示kB
|
||||||
|
private static final int BYTETOKB_RATIO = 1000; |
||||||
|
|
||||||
|
private String name; |
||||||
|
private String url; |
||||||
|
private long size; |
||||||
|
|
||||||
|
private int totalLength; |
||||||
|
private int downloadLength; |
||||||
|
|
||||||
|
public DownloadItem(JSONObject json) { |
||||||
|
this(json.optString("name"), json.optString("url"), json.optLong("size")); |
||||||
|
} |
||||||
|
|
||||||
|
public DownloadItem(String name, String url, long size) { |
||||||
|
this.name = name; |
||||||
|
this.url = url; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUrl() { |
||||||
|
return url + "?v=" + new Date().getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public long getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSize(long size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTotalLength() { |
||||||
|
return totalLength; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDownloadLength() { |
||||||
|
return downloadLength; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTotalLength(int totalLength) { |
||||||
|
this.totalLength = totalLength; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDownloadLength(int downloadLength) { |
||||||
|
this.downloadLength = downloadLength; |
||||||
|
} |
||||||
|
|
||||||
|
public int getProgressValue() { |
||||||
|
return (int) ((downloadLength / (double) totalLength) * PERCENTAGE_RATIO); |
||||||
|
} |
||||||
|
|
||||||
|
public String getProgressString() { |
||||||
|
return downloadLength / BYTETOKB_RATIO + "KB/" + totalLength / BYTETOKB_RATIO + "KB"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 转化为字符串 |
||||||
|
* |
||||||
|
* @return 字符串 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "name:" + name + ";download:" + getProgressString(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
return obj instanceof DownloadItem |
||||||
|
&& ComparatorUtils.equals(((DownloadItem) obj).name, name) |
||||||
|
&& ComparatorUtils.equals(((DownloadItem) obj).url, url); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回一个hash码 |
||||||
|
* |
||||||
|
* @return hash码 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
return name.hashCode(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.fr.design.onlineupdate.domain; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
|
||||||
|
import java.awt.Color; |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新升级的常量 |
||||||
|
*/ |
||||||
|
public interface UpdateConstants { |
||||||
|
|
||||||
|
String APPS_FOLDER_NAME = "webapps"; |
||||||
|
|
||||||
|
int CONNECTION_TIMEOUT = 1000 * 5; |
||||||
|
Color BAR_COLOR = new Color(0x3384F0); |
||||||
|
|
||||||
|
String CHANGELOG_X_START = "2018-07-11"; |
||||||
|
|
||||||
|
String DEFAULT_APP_NAME = "FineReport"; |
||||||
|
String DOWNLOAD_DIR = "update"; |
||||||
|
String DESIGNER_BACKUP_DIR = "designerbackup"; |
||||||
|
|
||||||
|
String UPDATE_CACHE_CONFIG_X = "updateCacheConfig10"; |
||||||
|
String UPDATE_CACHE_INFO_X = "updateCacheInfo10"; |
||||||
|
|
||||||
|
|
||||||
|
int BYTE = 153600; |
||||||
|
|
||||||
|
String[] JARS_FOR_SERVER_X = new String[]{ |
||||||
|
"fine-activator-10.0.jar", |
||||||
|
"fine-core-10.0.jar", |
||||||
|
"fine-report-engine-10.0.jar", |
||||||
|
"fine-decision-10.0.jar", |
||||||
|
"fine-decision-report-10.0.jar", |
||||||
|
"fine-schedule-10.0.jar", |
||||||
|
"fine-schedule-report-10.0.jar", |
||||||
|
"fine-swift-log-adaptor-10.0.jar", |
||||||
|
"fine-webui-10.0.jar", |
||||||
|
"fine-datasource-10.0.jar", |
||||||
|
"fine-third-10.0.jar" |
||||||
|
}; |
||||||
|
|
||||||
|
String[] JARS_FOR_DESIGNER_X = new String[]{ |
||||||
|
"fine-report-designer-10.0.jar", |
||||||
|
"aspectjrt.jar" |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
String[] LOG_TYPE = new String[]{ |
||||||
|
"REPORT", "MOBILE", "CHART", "PFC", "BI" |
||||||
|
}; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
package com.fr.design.onlineupdate.domain; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.util.Properties; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateInfoCachePropertyManager { |
||||||
|
private Properties prop; |
||||||
|
private String filePath; |
||||||
|
|
||||||
|
public UpdateInfoCachePropertyManager(String filePath) { |
||||||
|
this.filePath = filePath; |
||||||
|
prop = new Properties(); |
||||||
|
try { |
||||||
|
prop.load(new FileInputStream(filePath)); |
||||||
|
} catch (Exception ignored) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void updateProperty(String keyName, String keyValue) { |
||||||
|
try { |
||||||
|
OutputStream fos = new FileOutputStream(filePath); |
||||||
|
prop.setProperty(keyName, keyValue); |
||||||
|
prop.store(fos, null); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String readProperty(String keyName) { |
||||||
|
return prop.getProperty(keyName); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
package com.fr.design.onlineupdate.factory; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
|
||||||
|
import java.io.BufferedInputStream; |
||||||
|
import java.io.BufferedOutputStream; |
||||||
|
import java.io.DataInputStream; |
||||||
|
import java.io.DataOutputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileFilter; |
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class DirectoryOperationFactory { |
||||||
|
/** |
||||||
|
* 新建一个目录 |
||||||
|
* |
||||||
|
* @param dirPath 目录路径 |
||||||
|
*/ |
||||||
|
public static void createNewDirectory(String dirPath) { |
||||||
|
try { |
||||||
|
File newDirPath = new File(dirPath); |
||||||
|
if (!newDirPath.exists()) { |
||||||
|
StableUtils.mkdirs(newDirPath); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除目录 |
||||||
|
* |
||||||
|
* @param dirPath 目录路径 |
||||||
|
*/ |
||||||
|
public static void deleteDirectory(String dirPath) { |
||||||
|
try { |
||||||
|
File dir = new File(dirPath); |
||||||
|
if (dir.isDirectory()) { |
||||||
|
File[] file = dir.listFiles(); |
||||||
|
for (File fileTemp : file) { |
||||||
|
deleteDirectory(fileTemp.toString()); |
||||||
|
fileTemp.delete(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
dir.delete(); |
||||||
|
} |
||||||
|
dir.delete(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 复制目录 |
||||||
|
* |
||||||
|
* @param oldDirPath 被复制目录 |
||||||
|
* @param newDirPath 新目录 |
||||||
|
*/ |
||||||
|
public static void copyDirectory(String oldDirPath, String newDirPath) { |
||||||
|
File oldDir = new File(oldDirPath); |
||||||
|
if (oldDir.isDirectory()) { |
||||||
|
StableUtils.mkdirs(new File(newDirPath)); |
||||||
|
File[] files = oldDir.listFiles(); |
||||||
|
for (File fileTemp : files) { |
||||||
|
copyDirectory(fileTemp.toString(), newDirPath + "/" + fileTemp.getName()); |
||||||
|
} |
||||||
|
} else { |
||||||
|
try { |
||||||
|
copy(oldDirPath, newDirPath); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void copy(String path1, String path2) throws IOException { |
||||||
|
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(path1))); |
||||||
|
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path2))); |
||||||
|
byte[] date = new byte[in.available()]; |
||||||
|
|
||||||
|
in.read(date); |
||||||
|
out.write(date); |
||||||
|
|
||||||
|
in.close(); |
||||||
|
out.close(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 移动目录 |
||||||
|
* |
||||||
|
* @param oldDirPath 被移动目录 |
||||||
|
* @param newDirPath 新目录 |
||||||
|
*/ |
||||||
|
public static void moveDirectory(String oldDirPath, String newDirPath) { |
||||||
|
copyDirectory(oldDirPath, newDirPath); |
||||||
|
deleteDirectory(oldDirPath); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 列出过滤后的文件 |
||||||
|
* |
||||||
|
* @param installHome 安装目录 |
||||||
|
* @param backupdir 备份目录 |
||||||
|
* @return String数组 |
||||||
|
*/ |
||||||
|
public static String[] listFilteredFiles(String installHome, String backupdir) { |
||||||
|
File backupDir = new File(StableUtils.pathJoin(installHome, backupdir)); |
||||||
|
StableUtils.mkdirs(backupDir); |
||||||
|
File[] fileNames = backupDir.listFiles(new FileFilter() { |
||||||
|
@Override |
||||||
|
public boolean accept(File pathname) { |
||||||
|
return pathname.isDirectory(); |
||||||
|
} |
||||||
|
}); |
||||||
|
String[] jarFileName = new String[fileNames.length]; |
||||||
|
int j = 0; |
||||||
|
for (File fileName : fileNames) { |
||||||
|
if ((fileName.isDirectory()) && (ArrayUtils.getLength(fileName.listFiles()) > 0)) {//判断备份文件夹中是否为空,为空不显示
|
||||||
|
jarFileName[j++] = fileName.getName(); |
||||||
|
} |
||||||
|
} |
||||||
|
return Arrays.copyOf(jarFileName, j); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,122 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.dialog; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.onlineupdate.domain.UpdateConstants; |
||||||
|
import com.fr.design.onlineupdate.factory.DirectoryOperationFactory; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.ColorfulCellRender; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
|
||||||
|
import javax.swing.BoxLayout; |
||||||
|
import javax.swing.JDialog; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JScrollPane; |
||||||
|
import javax.swing.ScrollPaneConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Frame; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class RestoreDialog extends JDialog { |
||||||
|
private static final int LISTCELLHEIGHT = 30; |
||||||
|
private static final Dimension RESTOREJAR = new Dimension(523, 480); |
||||||
|
private static final Dimension RESTOREJAR_NORTHPANE = new Dimension(500, 392); |
||||||
|
//一个页面上最少显示13个元素
|
||||||
|
private static final int NUMOFCELL_LEAST = 13; |
||||||
|
|
||||||
|
private UIButton okButton; |
||||||
|
private UIButton cancelButton; |
||||||
|
private JPanel buttonPanel; |
||||||
|
private String jarSelected; |
||||||
|
|
||||||
|
public RestoreDialog(Dialog parent, boolean modal) { |
||||||
|
super(parent, modal); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
public RestoreDialog(Frame parent, boolean modal) { |
||||||
|
super(parent, modal); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initButton() { |
||||||
|
okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Ok")); |
||||||
|
cancelButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Cancel")); |
||||||
|
|
||||||
|
okButton.setEnabled(false); |
||||||
|
okButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
RestoreResultDialog dialog = new RestoreResultDialog(DesignerContext.getDesignerFrame(), true, jarSelected); |
||||||
|
dialog.showDialog(); |
||||||
|
} |
||||||
|
}); |
||||||
|
cancelButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
dispose(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
|
||||||
|
this.setResizable(false); |
||||||
|
JPanel pane = FRGUIPaneFactory.createBorderLayout_L_Pane(); |
||||||
|
this.setContentPane(pane); |
||||||
|
|
||||||
|
initButton(); |
||||||
|
|
||||||
|
buttonPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); |
||||||
|
buttonPanel.add(okButton); |
||||||
|
buttonPanel.add(cancelButton); |
||||||
|
pane.add(buttonPanel, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
JPanel jarListPane = new JPanel(); |
||||||
|
jarListPane.setLayout(new BoxLayout(jarListPane, BoxLayout.Y_AXIS)); |
||||||
|
String[] jarBackupFiles = DirectoryOperationFactory.listFilteredFiles(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR); |
||||||
|
|
||||||
|
ArrayUtils.reverse(jarBackupFiles); |
||||||
|
String[] jarFilesList = ((jarBackupFiles.length < NUMOFCELL_LEAST) ? Arrays.copyOf(jarBackupFiles, NUMOFCELL_LEAST) : jarBackupFiles); |
||||||
|
final JList jarList = new JList(jarFilesList); |
||||||
|
jarList.setFixedCellHeight(LISTCELLHEIGHT); |
||||||
|
jarList.setCellRenderer(new ColorfulCellRender()); |
||||||
|
jarList.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
super.mousePressed(e); |
||||||
|
jarSelected = (String) jarList.getSelectedValue(); |
||||||
|
okButton.setEnabled((jarSelected != null)); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
JScrollPane jsp = new JScrollPane(jarList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); |
||||||
|
jsp.setPreferredSize(RESTOREJAR_NORTHPANE); |
||||||
|
pane.add(jsp, BorderLayout.NORTH); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 显示窗口 |
||||||
|
*/ |
||||||
|
public void showDialog() { |
||||||
|
this.setSize(RESTOREJAR); |
||||||
|
this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Jar_Restore")); |
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
this.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,182 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.dialog; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.design.RestartHelper; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.onlineupdate.domain.UpdateConstants; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
import javax.swing.AbstractAction; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JDialog; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JTextArea; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.Frame; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class RestoreResultDialog extends JDialog { |
||||||
|
private static final Dimension RESTORE = new Dimension(340, 100); |
||||||
|
|
||||||
|
private static final Dimension RESTORE_OLD_VERSION = new Dimension(340, 135); |
||||||
|
|
||||||
|
private String jarRestoreDir; |
||||||
|
|
||||||
|
public RestoreResultDialog(Dialog parent, boolean modal) { |
||||||
|
super(parent, modal); |
||||||
|
initCommonComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
public RestoreResultDialog(Frame parent, boolean modal, String jarDir) { |
||||||
|
super(parent, modal); |
||||||
|
this.jarRestoreDir = jarDir; |
||||||
|
if (ComparatorUtils.equals(jarDir, com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Restore_Old_Version"))) { |
||||||
|
initOldVersionRestoreComps(); |
||||||
|
} else { |
||||||
|
initCommonComponents(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initCommonComponents() { |
||||||
|
this.setResizable(false); |
||||||
|
JPanel pane = new JPanel(); |
||||||
|
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10)); |
||||||
|
pane.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.setContentPane(pane); |
||||||
|
|
||||||
|
UIButton restartButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restart_Designer")); |
||||||
|
UIButton restartLaterButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Restart_Later")); |
||||||
|
|
||||||
|
restartButton.setFont(new Font("Default", Font.PLAIN, 12)); |
||||||
|
restartButton.setEnabled(false); |
||||||
|
restartButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
RestartHelper.restart(); |
||||||
|
} |
||||||
|
}); |
||||||
|
restartLaterButton.setFont(new Font("Default", Font.PLAIN, 12)); |
||||||
|
restartLaterButton.setEnabled(false); |
||||||
|
restartLaterButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
dispose(); |
||||||
|
} |
||||||
|
}); |
||||||
|
JPanel buttonPane = new JPanel(); |
||||||
|
buttonPane.add(restartLaterButton); |
||||||
|
buttonPane.add(restartButton); |
||||||
|
pane.add(buttonPane, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
JPanel progressLabelPane = new JPanel(new BorderLayout()); |
||||||
|
UILabel jarProgressLabel = new UILabel((com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restore_To")) + " " + jarRestoreDir + " " + (com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_WorksAfterRestart"))); |
||||||
|
jarProgressLabel.setFont(new Font("Default", Font.PLAIN, 12)); |
||||||
|
jarProgressLabel.setVisible(true); |
||||||
|
progressLabelPane.add(jarProgressLabel); |
||||||
|
pane.add(progressLabelPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
UpdateMainDialog.deletePreviousPropertyFile(); |
||||||
|
|
||||||
|
putJarBackupFiles(); |
||||||
|
restartButton.setEnabled(true); |
||||||
|
restartLaterButton.setEnabled(true); |
||||||
|
this.setSize(RESTORE); |
||||||
|
this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Jar_Restore")); |
||||||
|
} |
||||||
|
|
||||||
|
private void initOldVersionRestoreComps() { |
||||||
|
this.setResizable(false); |
||||||
|
JPanel pane = new JPanel(); |
||||||
|
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10)); |
||||||
|
pane.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.setContentPane(pane); |
||||||
|
|
||||||
|
UIButton okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Ok")); |
||||||
|
okButton.setFont(new Font("Default", Font.PLAIN, 12)); |
||||||
|
okButton.addActionListener(new AbstractAction() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
dispose(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
JPanel buttonPane = new JPanel(); |
||||||
|
buttonPane.add(okButton); |
||||||
|
pane.add(buttonPane, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
JPanel infoPane = new JPanel(new BorderLayout()); |
||||||
|
JTextArea jTextArea = new JTextArea( |
||||||
|
com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Already_Backup_Old_Project") |
||||||
|
+ StringUtils.BLANK |
||||||
|
+ StableUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR) |
||||||
|
+ com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Unzip_Replace_Restore") |
||||||
|
); |
||||||
|
jTextArea.setLineWrap(true); |
||||||
|
jTextArea.setEditable(false); |
||||||
|
jTextArea.setBackground(null); |
||||||
|
jTextArea.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); |
||||||
|
jTextArea.setFont(new Font("Default", Font.PLAIN, 12)); |
||||||
|
infoPane.add(jTextArea); |
||||||
|
pane.add(infoPane, BorderLayout.CENTER); |
||||||
|
|
||||||
|
this.setSize(RESTORE_OLD_VERSION); |
||||||
|
this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Designer_Updater_Restore_to_V8")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 显示窗口 |
||||||
|
*/ |
||||||
|
public void showDialog() { |
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
this.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void putJarBackupFiles() { |
||||||
|
Map<String, String> map = new HashMap<String, String>(); |
||||||
|
java.util.List<String> list = new ArrayList<String>(); |
||||||
|
String installHome = StableUtils.getInstallHome(); |
||||||
|
|
||||||
|
putJarBackupFilesToInstallLib(installHome, map, list); |
||||||
|
putJarBackupFilesToInstallEnv(installHome, map, list); |
||||||
|
RestartHelper.saveFilesWhichToMove(map); |
||||||
|
RestartHelper.saveFilesWhichToDelete(list.toArray(new String[list.size()])); |
||||||
|
} |
||||||
|
|
||||||
|
private void putJarBackupFilesToInstallLib(String installHome, Map<String, String> map, java.util.List<String> list) { |
||||||
|
String[] files = UpdateConstants.JARS_FOR_DESIGNER_X; |
||||||
|
String backupDir = UpdateConstants.DESIGNER_BACKUP_DIR; |
||||||
|
for (String file : files) { |
||||||
|
map.put(StableUtils.pathJoin(installHome, backupDir, jarRestoreDir, file), |
||||||
|
StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); |
||||||
|
list.add(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void putJarBackupFilesToInstallEnv(String installHome, Map<String, String> map, java.util.List<String> list) { |
||||||
|
String[] files = UpdateConstants.JARS_FOR_SERVER_X; |
||||||
|
String backupDir = UpdateConstants.DESIGNER_BACKUP_DIR; |
||||||
|
for (String file : files) { |
||||||
|
map.put(StableUtils.pathJoin(installHome, backupDir, jarRestoreDir, file), |
||||||
|
StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); |
||||||
|
list.add(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,821 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.dialog; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.design.RestartHelper; |
||||||
|
import com.fr.design.constants.LayoutConstants; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.onlineupdate.actions.FileDownloader; |
||||||
|
import com.fr.design.onlineupdate.domain.DownloadItem; |
||||||
|
import com.fr.design.onlineupdate.domain.UpdateConstants; |
||||||
|
import com.fr.design.onlineupdate.domain.UpdateInfoCachePropertyManager; |
||||||
|
import com.fr.design.onlineupdate.factory.DirectoryOperationFactory; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.LoadingLabel; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.UpdateActionLabel; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.UpdateInfoTable; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.UpdateInfoTableCellRender; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.UpdateInfoTableModel; |
||||||
|
import com.fr.design.onlineupdate.ui.widget.UpdateInfoTextAreaCellRender; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.DateUtils; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.general.SiteCenter; |
||||||
|
import com.fr.general.http.HttpClient; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.ProductConstants; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.sun.java.swing.plaf.motif.MotifProgressBarUI; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JProgressBar; |
||||||
|
import javax.swing.RowSorter; |
||||||
|
import javax.swing.SortOrder; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
import javax.swing.event.DocumentEvent; |
||||||
|
import javax.swing.event.DocumentListener; |
||||||
|
import javax.swing.table.TableRowSorter; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dialog; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Frame; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.BufferedWriter; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileReader; |
||||||
|
import java.io.FileWriter; |
||||||
|
import java.io.IOException; |
||||||
|
import java.text.ParsePosition; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Locale; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateMainDialog extends UIDialog { |
||||||
|
public static final Dimension DEFAULT = new Dimension(660, 620); |
||||||
|
|
||||||
|
private static final Dimension PROGRESSBAR = new Dimension(120, 15); |
||||||
|
private static final Dimension UPDATE_BUTTON = new Dimension(80, 24); |
||||||
|
private static final int UPDATE_PANE_ROW_SIZE = 30; |
||||||
|
private static final int UPDATE_CONTENT_PANE_ROW_SIZE = 10; |
||||||
|
private static final int UPDATE_CONTENT_PANE_COLUMN_SIZE = 10; |
||||||
|
private static final int UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE = 100; |
||||||
|
private static final int SEARCH_PANE_ROW_SIZE = 50; |
||||||
|
private static final int SEARCH_PANE_TEXT_COLUMN = 130; |
||||||
|
private static final int SEARCH_PANE_COLUMN_GAP = 3; |
||||||
|
private static final int UPDATE_INFO_TABLE_HEADER_TIME_WIDTH = 120; |
||||||
|
private static final int UPDATE_CONTENT_PANE_BORDER_COLOR = 0xCCCCCC; |
||||||
|
private static final int RESTORE_LABEL_COLOR = 0x3384F0; |
||||||
|
|
||||||
|
private static final String UPDATE_CACHE_STATE_FAIL = "fail"; |
||||||
|
private static final String UPDATE_CACHE_STATE_SUCCESS = "success"; |
||||||
|
|
||||||
|
private static final SimpleDateFormat CHANGELOG_FORMAT = new SimpleDateFormat("M/d/y, h:m:s a", Locale.ENGLISH); |
||||||
|
private static final SimpleDateFormat UPDATE_INFO_TABLE_FORMAT = new SimpleDateFormat("yyyy.MM.dd"); |
||||||
|
|
||||||
|
private Set<DownloadItem> downloadItems = new HashSet<DownloadItem>(); |
||||||
|
private JSONObject downloadFileConfig; |
||||||
|
//最新版本标签
|
||||||
|
private LoadingLabel loadingLabel; |
||||||
|
//更新按钮
|
||||||
|
private UIButton updateButton; |
||||||
|
//有新版本提示标签
|
||||||
|
private UILabel updateLabel; |
||||||
|
|
||||||
|
//jar包版本信息面板,包括当前版本和最新版本
|
||||||
|
private JPanel jarVersionInfoPane; |
||||||
|
//jar包更新信息面板,包括每个版本更新的信息
|
||||||
|
private JPanel jarUpdateInfoPane; |
||||||
|
//jar包更新操作面板,包括更新重启按钮和进度条
|
||||||
|
private JPanel updateActionPane; |
||||||
|
//进度条
|
||||||
|
private JProgressBar progressBar; |
||||||
|
//更新版本提示面板
|
||||||
|
private JPanel updateVersionReminderPane; |
||||||
|
//jar包版本标签
|
||||||
|
private UILabel jarCurrentLabel; |
||||||
|
//jar包还原标签
|
||||||
|
private UILabel jarRestoreLabel; |
||||||
|
//更新信息搜索按钮
|
||||||
|
private UIButton searchUpdateInfoBtn; |
||||||
|
//搜索更新信息关键词文本框
|
||||||
|
private UITextField searchUpdateInfoKeyword; |
||||||
|
|
||||||
|
private boolean updateSuccessful; |
||||||
|
|
||||||
|
private UpdateInfoTable updateInfoTable; |
||||||
|
|
||||||
|
private ArrayList<Object[]> updateInfoList; |
||||||
|
|
||||||
|
private boolean getUpdateInfoSuccess; |
||||||
|
|
||||||
|
private UpdateInfoCachePropertyManager cacheProperty; |
||||||
|
private String lastUpdateCacheTime; |
||||||
|
private String lastUpdateCacheState = UPDATE_CACHE_STATE_FAIL; |
||||||
|
|
||||||
|
public UpdateMainDialog(Dialog parent) { |
||||||
|
super(parent); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateMainDialog(Frame parent) { |
||||||
|
super(parent); |
||||||
|
setModal(true); |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initUpdateActionPane() { |
||||||
|
double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; |
||||||
|
double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; |
||||||
|
double[] columnUpdateSubContentPaneProgressSize = {TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
JPanel progressBarPane = new JPanel(new BorderLayout()); |
||||||
|
|
||||||
|
progressBar = new JProgressBar(); |
||||||
|
progressBar.setUI(new MotifProgressBarUI()); |
||||||
|
progressBar.setForeground(UpdateConstants.BAR_COLOR); |
||||||
|
progressBar.setVisible(false); |
||||||
|
progressBar.setStringPainted(true); |
||||||
|
progressBar.setPreferredSize(PROGRESSBAR); |
||||||
|
|
||||||
|
updateLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_New_Version_Available")); |
||||||
|
updateLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||||
|
updateLabel.setVisible(false); |
||||||
|
|
||||||
|
progressBarPane.add(GUICoreUtils.createBorderLayoutPane( |
||||||
|
progressBar, BorderLayout.CENTER, |
||||||
|
updateLabel, BorderLayout.EAST |
||||||
|
), BorderLayout.CENTER); |
||||||
|
|
||||||
|
updateActionPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), initPaneContent(getBackground(), rowUpdateContentPaneSize, columnUpdateSubContentPaneProgressSize, progressBarPane, updateButton), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()} |
||||||
|
}, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel initPaneContent(Color color, double[] row, double[] column, Component... var) { |
||||||
|
JPanel paneContent = TableLayoutHelper.createTableLayoutPane(new Component[][]{var}, row, column); |
||||||
|
paneContent.setBackground(color); |
||||||
|
return paneContent; |
||||||
|
} |
||||||
|
|
||||||
|
private void initJarVersionInfoPane() { |
||||||
|
double[] rowUpdatePaneSize = {UPDATE_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED}; |
||||||
|
double[] columnUpdatePaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; |
||||||
|
double[] columnUpdateContentPaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; |
||||||
|
double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
double[] columnUpdateSubContentPaneLabelSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; |
||||||
|
|
||||||
|
JPanel jarUpdateContentPane = new JPanel(); |
||||||
|
jarUpdateContentPane.setLayout(new BorderLayout()); |
||||||
|
jarUpdateContentPane.setBorder(BorderFactory.createLineBorder(new Color(UPDATE_CONTENT_PANE_BORDER_COLOR))); |
||||||
|
|
||||||
|
JPanel jarUpdateContentPane2 = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), updateVersionReminderPane, new UILabel()}, |
||||||
|
new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_JAR_Version")), jarCurrentLabel), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Latest_JAR")), loadingLabel), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()} |
||||||
|
}, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE); |
||||||
|
jarUpdateContentPane2.setBackground(Color.WHITE); |
||||||
|
jarUpdateContentPane.add(jarUpdateContentPane2); |
||||||
|
jarVersionInfoPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), initPaneContent(getBackground(), rowUpdateContentPaneSize, columnUpdateContentPaneSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_JarUpdate")), new UILabel(), jarRestoreLabel), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), jarUpdateContentPane, new UILabel()} |
||||||
|
}, rowUpdatePaneSize, columnUpdatePaneSize, LayoutConstants.VGAP_LARGE); |
||||||
|
} |
||||||
|
|
||||||
|
private void initJarUpdateInfoPane() { |
||||||
|
double[] rowUpdatePaneSize = {SEARCH_PANE_ROW_SIZE, TableLayout.FILL}; |
||||||
|
double[] columnUpdatePaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; |
||||||
|
|
||||||
|
double[] searchRow = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, SEARCH_PANE_COLUMN_GAP * 2}; |
||||||
|
double[] searchColumn = {TableLayout.FILL, SEARCH_PANE_TEXT_COLUMN, TableLayout.PREFERRED}; |
||||||
|
initUpdateInfoSearchPane(); |
||||||
|
JPanel searchPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()}, |
||||||
|
new Component[]{new UILabel(), searchUpdateInfoKeyword, searchUpdateInfoBtn}, |
||||||
|
new Component[]{new UILabel(), new UILabel(), new UILabel()} |
||||||
|
}, searchRow, searchColumn, LayoutConstants.VGAP_LARGE); |
||||||
|
|
||||||
|
String[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Date"), com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Content"), com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_SignHeader")}; |
||||||
|
initUpdateInfoTable(columnNames); |
||||||
|
|
||||||
|
UIScrollPane uiScrollPane = new UIScrollPane(updateInfoTable); |
||||||
|
jarUpdateInfoPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ |
||||||
|
new Component[]{new UILabel(), searchPane, new UILabel()}, |
||||||
|
new Component[]{new UILabel(), uiScrollPane, new UILabel()} |
||||||
|
}, rowUpdatePaneSize, columnUpdatePaneSize, LayoutConstants.VGAP_LARGE); |
||||||
|
} |
||||||
|
|
||||||
|
private void initUpdateInfoTable(String[] columnNames) { |
||||||
|
int updateTimeColIndex = 0; |
||||||
|
int updateTitleColIndex = 1; |
||||||
|
int updateSignColIndex = 2; |
||||||
|
|
||||||
|
updateInfoTable = new UpdateInfoTable(columnNames); |
||||||
|
|
||||||
|
updateInfoTable.setShowGrid(false); |
||||||
|
updateInfoTable.setCellSelectionEnabled(false); |
||||||
|
TableRowSorter<UpdateInfoTableModel> sorter = new TableRowSorter<UpdateInfoTableModel>(updateInfoTable.getDataModel()); |
||||||
|
sorter.setSortable(updateTimeColIndex, true); |
||||||
|
sorter.setSortable(updateTitleColIndex, false); |
||||||
|
sorter.setSortable(updateSignColIndex, false); |
||||||
|
updateInfoTable.setRowSorter(sorter); |
||||||
|
List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); |
||||||
|
sortKeys.add(new RowSorter.SortKey(updateTimeColIndex, SortOrder.DESCENDING)); |
||||||
|
sorter.setSortKeys(sortKeys); |
||||||
|
|
||||||
|
updateInfoTable.getTableHeader().setReorderingAllowed(false); |
||||||
|
updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMaxWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); |
||||||
|
updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMinWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); |
||||||
|
updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); |
||||||
|
updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); |
||||||
|
updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); |
||||||
|
updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); |
||||||
|
updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Date")).setCellRenderer(new UpdateInfoTableCellRender()); |
||||||
|
updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Content")).setCellRenderer(new UpdateInfoTextAreaCellRender()); |
||||||
|
} |
||||||
|
|
||||||
|
private void initUpdateInfoSearchPane() { |
||||||
|
searchUpdateInfoKeyword = new UITextField(); |
||||||
|
searchUpdateInfoKeyword.getDocument().addDocumentListener(new DocumentListener() { |
||||||
|
@Override |
||||||
|
public void insertUpdate(DocumentEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeUpdate(DocumentEvent e) { |
||||||
|
String keyword = searchUpdateInfoKeyword.getText(); |
||||||
|
if (ComparatorUtils.equals(keyword, StringUtils.EMPTY) && getUpdateInfoSuccess) { |
||||||
|
updateInfoList.clear(); |
||||||
|
getUpdateInfo(keyword).execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void changedUpdate(DocumentEvent e) { |
||||||
|
} |
||||||
|
}); |
||||||
|
searchUpdateInfoBtn = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Search")); |
||||||
|
searchUpdateInfoBtn.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (getUpdateInfoSuccess) { |
||||||
|
updateInfoList.clear(); |
||||||
|
getUpdateInfo(searchUpdateInfoKeyword.getText()).execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void initButtonAndLabel() { |
||||||
|
loadingLabel = new LoadingLabel(); |
||||||
|
loadingLabel.setText(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Checking_Jar_Update")); |
||||||
|
updateButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Update")); |
||||||
|
updateButton.setPreferredSize(UPDATE_BUTTON); |
||||||
|
updateButton.setEnabled(false); |
||||||
|
|
||||||
|
double[] rowSize = {TableLayout.PREFERRED}; |
||||||
|
|
||||||
|
double[] colSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; |
||||||
|
updateVersionReminderPane = initPaneContent( |
||||||
|
Color.WHITE, rowSize, colSize, |
||||||
|
new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Designer_Version")), |
||||||
|
new UILabel(UpdateConstants.DEFAULT_APP_NAME + StringUtils.BLANK + ProductConstants.VERSION) |
||||||
|
); |
||||||
|
|
||||||
|
|
||||||
|
jarCurrentLabel = new UILabel(StringUtils.isEmpty(GeneralUtils.readBuildNO()) ? com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Not_Install_Version") : GeneralUtils.readBuildNO(), SwingConstants.CENTER); |
||||||
|
UILabel noJarPreviousRevision = new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_No_Previous_Version")); |
||||||
|
UpdateActionLabel jarRestorePreviousRevision = new UpdateActionLabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restore"), false); |
||||||
|
jarRestorePreviousRevision.setForeground(new Color(RESTORE_LABEL_COLOR)); |
||||||
|
jarRestorePreviousRevision.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
RestoreDialog dialog = new RestoreDialog(DesignerContext.getDesignerFrame(), true); |
||||||
|
dialog.showDialog(); |
||||||
|
} |
||||||
|
}); |
||||||
|
//choose RestoreLabel to show
|
||||||
|
boolean isNeedRestore = ArrayUtils.isNotEmpty(DirectoryOperationFactory.listFilteredFiles(StableUtils.getInstallHome(), getBackupDirectory())); |
||||||
|
jarRestoreLabel = isNeedRestore ? jarRestorePreviousRevision : noJarPreviousRevision; |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponents() { |
||||||
|
JPanel contentPane = (JPanel) getContentPane(); |
||||||
|
contentPane.setLayout(new BorderLayout()); |
||||||
|
|
||||||
|
|
||||||
|
initButtonAndLabel(); |
||||||
|
|
||||||
|
initJarVersionInfoPane(); |
||||||
|
initJarUpdateInfoPane(); |
||||||
|
initUpdateActionPane(); |
||||||
|
|
||||||
|
add(jarVersionInfoPane, BorderLayout.NORTH); |
||||||
|
add(jarUpdateInfoPane, BorderLayout.CENTER); |
||||||
|
add(updateActionPane, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
addActionListenerForUpdateBtn(); |
||||||
|
|
||||||
|
new SwingWorker<JSONObject, Void>() { |
||||||
|
@Override |
||||||
|
protected JSONObject doInBackground() throws Exception { |
||||||
|
HttpClient hc = new HttpClient(SiteCenter.getInstance().acquireUrlByKind("jar10.update")); |
||||||
|
hc.setTimeout(UpdateConstants.CONNECTION_TIMEOUT); |
||||||
|
return new JSONObject(hc.getResponseText()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
downloadFileConfig = get(); |
||||||
|
showDownLoadInfo(); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
stopLoading(); |
||||||
|
} catch (ExecutionException e) { |
||||||
|
stopLoading(); |
||||||
|
} finally { |
||||||
|
getUpdateInfo(StringUtils.EMPTY).execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
private SwingWorker<JSONArray, Void> getUpdateInfo(final String keyword) { |
||||||
|
updateInfoList = new ArrayList<Object[]>(); |
||||||
|
lastUpdateCacheTime = UpdateConstants.CHANGELOG_X_START; |
||||||
|
String cacheConfigPath = getUpdateCacheConfig(); |
||||||
|
cacheProperty = new UpdateInfoCachePropertyManager(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres", cacheConfigPath)); |
||||||
|
String recordUpdateTime = cacheProperty.readProperty("updateTime"); |
||||||
|
if (StringUtils.isNotEmpty(recordUpdateTime)) { |
||||||
|
lastUpdateCacheTime = recordUpdateTime; |
||||||
|
} |
||||||
|
String recordUpdateState = cacheProperty.readProperty("updateState"); |
||||||
|
if (StringUtils.isNotEmpty(recordUpdateState)) { |
||||||
|
lastUpdateCacheState = recordUpdateState; |
||||||
|
} |
||||||
|
return new SwingWorker<JSONArray, Void>() { |
||||||
|
@Override |
||||||
|
protected JSONArray doInBackground() { |
||||||
|
try { |
||||||
|
getUpdateInfoSuccess = false; |
||||||
|
//step1:read from cache file
|
||||||
|
getCachedUpdateInfo(keyword); |
||||||
|
//step2:read from website,start from cacheRecordTime
|
||||||
|
if (downloadFileConfig == null) { |
||||||
|
throw new Exception("network error."); |
||||||
|
} |
||||||
|
HttpClient hc = new HttpClient(SiteCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); |
||||||
|
hc.asGet(); |
||||||
|
hc.setTimeout(UpdateConstants.CONNECTION_TIMEOUT * 2); |
||||||
|
String responseText = hc.getResponseText(); |
||||||
|
JSONArray array = JSONArray.create(); |
||||||
|
//假如返回"-1",说明socket出错了
|
||||||
|
if (!ComparatorUtils.equals(responseText, "-1")) { |
||||||
|
array = new JSONArray(responseText); |
||||||
|
} |
||||||
|
hc.release(); |
||||||
|
return array; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
return JSONArray.create(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
JSONArray jsonArray = get(); |
||||||
|
//step3:generateInfoTableList
|
||||||
|
updateInfoTable.getDataModel().populateBean(generateUpdateInfoList(jsonArray, keyword)); |
||||||
|
|
||||||
|
getUpdateInfoSuccess = true; |
||||||
|
//step4:update cache file,start from cacheRecordTime,end latest server jartime
|
||||||
|
updateCachedInfoFile(jsonArray); |
||||||
|
} catch (Exception e) { |
||||||
|
getUpdateInfoSuccess = true; |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
//从文件中读取缓存的更新信息
|
||||||
|
private void getCachedUpdateInfo(String keyword) throws Exception { |
||||||
|
String cacheInfoPath = getUpdateCacheInfo(); |
||||||
|
File cacheFile = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres", cacheInfoPath)); |
||||||
|
if (!ComparatorUtils.equals(lastUpdateCacheState, "success")) { |
||||||
|
cacheFile.delete(); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (cacheFile.exists()) { |
||||||
|
FileReader reader = new FileReader(cacheFile); |
||||||
|
BufferedReader br = new BufferedReader(reader); |
||||||
|
String readStr, updateTimeStr; |
||||||
|
|
||||||
|
while ((readStr = br.readLine()) != null) { |
||||||
|
String[] updateInfo = readStr.split("\\t"); |
||||||
|
if (updateInfo.length == 2) { |
||||||
|
updateTimeStr = updateInfo[0]; |
||||||
|
Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); |
||||||
|
//形如 Build#release-2018.07.31.03.03.52.80
|
||||||
|
String currentNO = GeneralUtils.readBuildNO(); |
||||||
|
Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); |
||||||
|
if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { |
||||||
|
if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateInfo[1], keyword)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
if (isValidLogInfo(updateInfo[1])) { |
||||||
|
updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateInfo[1], updateTime.after(curJarDate)}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
br.close(); |
||||||
|
reader.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void updateCachedInfoFile(JSONArray jsonArray) throws Exception { |
||||||
|
String cacheDirPath = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres"); |
||||||
|
File cacheFileDir = new File(cacheDirPath); |
||||||
|
if (!StableUtils.mkdirs(cacheFileDir)) { |
||||||
|
FineLoggerFactory.getLogger().error("make dir error."); |
||||||
|
return; |
||||||
|
} |
||||||
|
final File cacheFile = new File(StableUtils.pathJoin(cacheDirPath, getUpdateCacheInfo())); |
||||||
|
if (!cacheFile.exists()) { |
||||||
|
cacheFile.createNewFile(); |
||||||
|
lastUpdateCacheTime = UpdateConstants.CHANGELOG_X_START; |
||||||
|
lastUpdateCacheState = UPDATE_CACHE_STATE_FAIL; |
||||||
|
} |
||||||
|
if (downloadFileConfig == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String endTime = getLatestJARTimeStr(); |
||||||
|
if (endTime.equals(lastUpdateCacheTime) || jsonArray.length() == 0 || ComparatorUtils.compare(endTime, lastUpdateCacheTime) <= 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
FileWriter fileWriter = new FileWriter(cacheFile, true); |
||||||
|
BufferedWriter bufferWriter = new BufferedWriter(fileWriter); |
||||||
|
for (int i = 0; i < jsonArray.length(); i++) { |
||||||
|
JSONObject jo = (JSONObject) jsonArray.get(i); |
||||||
|
bufferWriter.write((String) jo.get("update") + '\t' + jo.get("title")); |
||||||
|
bufferWriter.newLine(); |
||||||
|
bufferWriter.flush(); |
||||||
|
} |
||||||
|
bufferWriter.close(); |
||||||
|
fileWriter.close(); |
||||||
|
lastUpdateCacheState = UPDATE_CACHE_STATE_SUCCESS; |
||||||
|
lastUpdateCacheTime = endTime; |
||||||
|
cacheProperty.updateProperty("updateTime", lastUpdateCacheTime); |
||||||
|
cacheProperty.updateProperty("updateState", lastUpdateCacheState); |
||||||
|
} |
||||||
|
|
||||||
|
private ArrayList<Object[]> generateUpdateInfoList(JSONArray jsonArray, String keyword) throws Exception { |
||||||
|
for (int i = 0; i < jsonArray.length(); i++) { |
||||||
|
JSONObject jo = (JSONObject) jsonArray.get(i); |
||||||
|
String updateTitle = (String) jo.get("title"); |
||||||
|
String updateTimeStr = (String) jo.get("update"); |
||||||
|
Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); |
||||||
|
//形如 Build#release-2018.07.31.03.03.52.80
|
||||||
|
String currentNO = GeneralUtils.readBuildNO(); |
||||||
|
Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); |
||||||
|
if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { |
||||||
|
if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateTitle, keyword)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
if (isValidLogInfo(updateTitle)) { |
||||||
|
updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateTitle, updateTime.after(curJarDate)}); |
||||||
|
} |
||||||
|
} |
||||||
|
return new ArrayList<Object[]>(updateInfoList); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean containsKeyword(String str, String keyword) { |
||||||
|
return str.toUpperCase().contains(keyword.toUpperCase()); |
||||||
|
} |
||||||
|
|
||||||
|
private void stopLoading() { |
||||||
|
loadingLabel.stopLoading(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Connect_VersionUpdateServer_Failed")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void showDownLoadInfo() { |
||||||
|
//形如 Build#release-2018.07.31.03.03.52.80
|
||||||
|
String buildNO = downloadFileConfig.optString("buildNO"); |
||||||
|
Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); |
||||||
|
String serverVersionNO = downloadFileConfig.optString("versionNO"); |
||||||
|
String currentVersionNO = ProductConstants.RELEASE_VERSION; |
||||||
|
String[] serverVersionSplitStr = serverVersionNO.split("\\."); |
||||||
|
String[] currentVersionSplitStr = currentVersionNO.split("\\."); |
||||||
|
int index = 0; |
||||||
|
int compareResult; |
||||||
|
int versionLength = Math.min(serverVersionSplitStr.length, currentVersionSplitStr.length); |
||||||
|
|
||||||
|
//形如 Build#release-2018.07.31.03.03.52.80
|
||||||
|
String currentNO = GeneralUtils.readBuildNO(); |
||||||
|
if (!".".equals(StableUtils.getInstallHome())) { |
||||||
|
Date currentDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); |
||||||
|
if (DateUtils.subtractDate(jarDate, currentDate, DateUtils.DAY) > 0) { |
||||||
|
updateButton.setEnabled(true); |
||||||
|
updateLabel.setVisible(true); |
||||||
|
loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); |
||||||
|
} else { |
||||||
|
loadingLabel.stopLoading(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Already_Latest_Version")); |
||||||
|
} |
||||||
|
} else { |
||||||
|
updateButton.setEnabled(true); |
||||||
|
updateLabel.setVisible(true); |
||||||
|
loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); |
||||||
|
} |
||||||
|
|
||||||
|
while (index < versionLength) { |
||||||
|
compareResult = serverVersionSplitStr[index].length() - currentVersionSplitStr[index].length(); |
||||||
|
if (0 == compareResult) { |
||||||
|
compareResult = serverVersionSplitStr[index].compareTo(currentVersionSplitStr[index]); |
||||||
|
if (0 == compareResult) { |
||||||
|
++index; |
||||||
|
continue; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
initMapWithInfo(downloadFileConfig); |
||||||
|
} |
||||||
|
|
||||||
|
public void initMapWithInfo(JSONObject result) { |
||||||
|
addJarNameToMap(result, "designer"); |
||||||
|
addJarNameToMap(result, "server"); |
||||||
|
} |
||||||
|
|
||||||
|
private void addJarNameToMap(JSONObject result, String category) { |
||||||
|
JSONArray jsonArray = result.optJSONArray(category); |
||||||
|
if (jsonArray != null) { |
||||||
|
for (int i = 0, len = jsonArray.length(); i < len; i++) { |
||||||
|
JSONObject jo = jsonArray.optJSONObject(i); |
||||||
|
String downloadName = jo.optString("name"); |
||||||
|
String downloadUrl = jo.optString("url"); |
||||||
|
long downloadSize = jo.optLong("size"); |
||||||
|
if (ComparatorUtils.equals(category, "server")) { |
||||||
|
File currentJAR = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), ProjectConstants.LIB_NAME, downloadName)); |
||||||
|
if (currentJAR.exists() && ComparatorUtils.equals(currentJAR.length(), downloadSize)) { |
||||||
|
//假如大小一样的jar包就不要下载了
|
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
downloadItems.add(new DownloadItem(downloadName, downloadUrl, downloadSize)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* jar包更新按钮监听器 |
||||||
|
*/ |
||||||
|
private void addActionListenerForUpdateBtn() { |
||||||
|
updateButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
if (updateSuccessful) { |
||||||
|
RestartHelper.restart(); |
||||||
|
} else { |
||||||
|
deletePreviousPropertyFile(); |
||||||
|
updateButton.setEnabled(false); |
||||||
|
progressBar.setVisible(true); |
||||||
|
updateLabel.setVisible(false); |
||||||
|
|
||||||
|
new FileDownloader( |
||||||
|
downloadItems.toArray(new DownloadItem[downloadItems.size()]), |
||||||
|
StableUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DOWNLOAD_DIR)) { |
||||||
|
@Override |
||||||
|
protected void process(java.util.List<DownloadItem> chunks) { |
||||||
|
DownloadItem fileInfo = chunks.get(chunks.size() - 1); |
||||||
|
progressBar.setString(fileInfo.getName() + " " + fileInfo.getProgressString()); |
||||||
|
progressBar.setValue(fileInfo.getProgressValue()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDownloadSuccess() { |
||||||
|
updateButton.setEnabled(true); |
||||||
|
progressBar.setVisible(false); |
||||||
|
backup(); |
||||||
|
putNewFiles(); |
||||||
|
updateSuccessful = true; |
||||||
|
updateButton.setText(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restart_Designer")); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDownloadFailed() { |
||||||
|
progressBar.setVisible(false); |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 确保升级更新之前删除以前的配置文件 |
||||||
|
*/ |
||||||
|
public static void deletePreviousPropertyFile() { |
||||||
|
//在进行更新升级之前确保move和delete.properties删除
|
||||||
|
File moveFile = new File(RestartHelper.MOVE_FILE); |
||||||
|
File delFile = new File(RestartHelper.RECORD_FILE); |
||||||
|
if ((moveFile.exists()) && (!moveFile.delete())) { |
||||||
|
FineLoggerFactory.getLogger().error(RestartHelper.MOVE_FILE + "delete failed!"); |
||||||
|
} |
||||||
|
if ((delFile.exists()) && (!delFile.delete())) { |
||||||
|
FineLoggerFactory.getLogger().error(RestartHelper.RECORD_FILE + "delete failed!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* JAR包更新的时候备份老的jar包,包括设计器相关的和服务器相关的几个 |
||||||
|
*/ |
||||||
|
private void backup() { |
||||||
|
String installHome = StableUtils.getInstallHome(); |
||||||
|
//jar包备份文件的目录为"backup/"+jar包当前版本号
|
||||||
|
String todayBackupDir = StableUtils.pathJoin(installHome, getBackupDirectory(), (GeneralUtils.readBuildNO())); |
||||||
|
backupFilesFromInstallEnv(installHome, todayBackupDir, getJARList4Server()); |
||||||
|
backupFilesFromInstallLib(installHome, todayBackupDir, getJARList4Designer()); |
||||||
|
jarCurrentLabel.setText(downloadFileConfig.optString("buildNO")); |
||||||
|
} |
||||||
|
|
||||||
|
private void backupFilesFromInstallEnv(String installHome, String todayBackupDir, String[] files) { |
||||||
|
for (String file : files) { |
||||||
|
try { |
||||||
|
IOUtils.copy( |
||||||
|
new File(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)), |
||||||
|
new File(StableUtils.pathJoin(todayBackupDir))); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void backupFilesFromInstallLib(String installHome, String todayBackupDir, String[] files) { |
||||||
|
for (String file : files) { |
||||||
|
try { |
||||||
|
IOUtils.copy( |
||||||
|
new File(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)), |
||||||
|
new File(StableUtils.pathJoin(todayBackupDir))); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void putNewFiles() { |
||||||
|
Map<String, String> map = new HashMap<String, String>(); |
||||||
|
java.util.List<String> list = new ArrayList<String>(); |
||||||
|
String installHome = StableUtils.getInstallHome(); |
||||||
|
putNewFilesToInstallLib(installHome, getDownLoadJAR4Designer(), map, list); |
||||||
|
putNewFilesToInstallEnv(installHome, getDownLoadJAR4Server(), map, list); |
||||||
|
RestartHelper.saveFilesWhichToMove(map); |
||||||
|
RestartHelper.saveFilesWhichToDelete(list.toArray(new String[list.size()])); |
||||||
|
} |
||||||
|
|
||||||
|
private void putNewFilesToInstallLib(String installHome, String[] files, Map<String, String> map, java.util.List<String> list) { |
||||||
|
for (String file : files) { |
||||||
|
map.put(StableUtils.pathJoin(installHome, UpdateConstants.DOWNLOAD_DIR, file), |
||||||
|
StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); |
||||||
|
list.add(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void putNewFilesToInstallEnv(String installHome, String[] files, Map<String, String> map, java.util.List<String> list) { |
||||||
|
for (String file : files) { |
||||||
|
map.put(StableUtils.pathJoin(installHome, UpdateConstants.DOWNLOAD_DIR, file), |
||||||
|
StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); |
||||||
|
list.add(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//获取备份目录
|
||||||
|
private String getBackupDirectory() { |
||||||
|
return UpdateConstants.DESIGNER_BACKUP_DIR; |
||||||
|
} |
||||||
|
|
||||||
|
//获取服务器jar包列表
|
||||||
|
private String[] getJARList4Server() { |
||||||
|
return UpdateConstants.JARS_FOR_SERVER_X; |
||||||
|
} |
||||||
|
|
||||||
|
//获取设计器jar包列表
|
||||||
|
private String[] getJARList4Designer() { |
||||||
|
return UpdateConstants.JARS_FOR_DESIGNER_X; |
||||||
|
} |
||||||
|
|
||||||
|
//获取服务器jar包下载列表
|
||||||
|
private String[] getDownLoadJAR4Server() { |
||||||
|
ArrayList<String> jarList = new ArrayList<String>(); |
||||||
|
for (DownloadItem downloadItem : downloadItems) { |
||||||
|
String downloadItemName = downloadItem.getName(); |
||||||
|
if (ArrayUtils.contains(getJARList4Server(), downloadItemName)) { |
||||||
|
jarList.add(downloadItemName); |
||||||
|
} |
||||||
|
} |
||||||
|
return jarList.toArray(new String[jarList.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
//获取设计器jar包下载列表
|
||||||
|
private String[] getDownLoadJAR4Designer() { |
||||||
|
ArrayList<String> jarList = new ArrayList<String>(); |
||||||
|
for (DownloadItem downloadItem : downloadItems) { |
||||||
|
String downloadItemName = downloadItem.getName(); |
||||||
|
if (ArrayUtils.contains(getJARList4Designer(), downloadItemName)) { |
||||||
|
jarList.add(downloadItemName); |
||||||
|
} |
||||||
|
} |
||||||
|
return jarList.toArray(new String[jarList.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
//获取更新日志缓存配置文件名
|
||||||
|
private String getUpdateCacheConfig() { |
||||||
|
return UpdateConstants.UPDATE_CACHE_CONFIG_X; |
||||||
|
} |
||||||
|
|
||||||
|
//获取更新日志缓存内容文件名
|
||||||
|
private String getUpdateCacheInfo() { |
||||||
|
return UpdateConstants.UPDATE_CACHE_INFO_X; |
||||||
|
} |
||||||
|
|
||||||
|
//获取最新的jar包时间字符串
|
||||||
|
private String getLatestJARTimeStr() { |
||||||
|
if (downloadFileConfig == null) { |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
String buildNO = downloadFileConfig.optString("buildNO"); |
||||||
|
Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); |
||||||
|
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); |
||||||
|
return df.format(jarDate); |
||||||
|
} |
||||||
|
|
||||||
|
//判断是否是有效的日志内容
|
||||||
|
private boolean isValidLogInfo(String logContent) { |
||||||
|
String log = logContent.toUpperCase(); |
||||||
|
for (String s : UpdateConstants.LOG_TYPE) { |
||||||
|
if (log.startsWith(s)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 显示窗口 |
||||||
|
*/ |
||||||
|
public void showDialog() { |
||||||
|
setSize(DEFAULT); |
||||||
|
setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_UpdateAndUpgrade")); |
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查有效性 |
||||||
|
* |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void checkValid() throws Exception { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.Graphics; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class ColorfulCellRender extends JPanel implements ListCellRenderer { |
||||||
|
private static int CELLCOLOR_DARK = 0xf6f6f6; |
||||||
|
private static int CELLCOLOR_LIGHT = 0xffffff; |
||||||
|
private static int CELLCOLOR_SELECTED = 0xdfecfd; |
||||||
|
private static int TEXT_COORDINATE_X = 10; |
||||||
|
private static int TEXT_COORDINATE_Y = 20; |
||||||
|
private static final int LISTFONTSIZE = 12; |
||||||
|
private Color[] colors = new Color[]{new Color(CELLCOLOR_DARK), new Color(CELLCOLOR_LIGHT)}; |
||||||
|
|
||||||
|
private String text; |
||||||
|
|
||||||
|
public ColorfulCellRender() { |
||||||
|
setOpaque(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||||
|
text = ((null != value) ? (value.toString()) : null); |
||||||
|
|
||||||
|
Color background; |
||||||
|
Color foreground = Color.BLACK; |
||||||
|
//当前Renderer是否是拖拽目标
|
||||||
|
JList.DropLocation dropLocation = list.getDropLocation(); |
||||||
|
if (dropLocation != null |
||||||
|
&& !dropLocation.isInsert() |
||||||
|
&& dropLocation.getIndex() == index) { |
||||||
|
|
||||||
|
background = new Color(CELLCOLOR_SELECTED); |
||||||
|
//当前Renderer是否被选中
|
||||||
|
} else if (isSelected) { |
||||||
|
background = new Color(CELLCOLOR_SELECTED); |
||||||
|
} else { |
||||||
|
background = colors[index % 2]; |
||||||
|
} |
||||||
|
|
||||||
|
setBackground(background); |
||||||
|
setForeground(foreground); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paintComponent(Graphics g) { |
||||||
|
g.setColor(getBackground()); |
||||||
|
g.fillRect(0, 0, getWidth(), getHeight()); |
||||||
|
g.setColor(getForeground()); |
||||||
|
g.setFont(new Font("Default", Font.PLAIN, LISTFONTSIZE)); |
||||||
|
if (text != null) { |
||||||
|
g.drawString(text, TEXT_COORDINATE_X, TEXT_COORDINATE_Y); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import javax.swing.Timer; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class LoadingLabel extends UILabel { |
||||||
|
private Icon[] busyIcons = new Icon[15]; |
||||||
|
private Timer busyIconTimer; |
||||||
|
private int busyIconIndex; |
||||||
|
|
||||||
|
public LoadingLabel() { |
||||||
|
for (int i = 0; i < busyIcons.length; i++) { |
||||||
|
busyIcons[i] = IOUtils.readIcon("/com/fr/design/images/update/busy-icon" + i + ".png"); |
||||||
|
} |
||||||
|
int busyAnimationRate = 30; |
||||||
|
|
||||||
|
busyIconTimer = new Timer(busyAnimationRate, new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
busyIconIndex = (busyIconIndex + 1) % busyIcons.length; |
||||||
|
setIcon(busyIcons[busyIconIndex]); |
||||||
|
setHorizontalAlignment(SwingConstants.CENTER); |
||||||
|
} |
||||||
|
}); |
||||||
|
busyIconTimer.start(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 停止加载,并显示 |
||||||
|
* |
||||||
|
* @param text 要显示的字段 |
||||||
|
*/ |
||||||
|
public void stopLoading(String text) { |
||||||
|
busyIconTimer.stop(); |
||||||
|
setIcon(null); |
||||||
|
setText(text); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
|
||||||
|
import javax.swing.event.MouseInputAdapter; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateActionLabel extends UILabel { |
||||||
|
private ActionListener actionListener; |
||||||
|
private boolean drawLine = true; |
||||||
|
|
||||||
|
public UpdateActionLabel(String text, boolean drawUnderLine) { |
||||||
|
super(text); |
||||||
|
this.drawLine = drawUnderLine; |
||||||
|
this.setForeground(Color.BLUE); |
||||||
|
this.addMouseListener(mouseInputAdapter); |
||||||
|
this.addMouseMotionListener(mouseInputAdapter); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 增加事件监听 |
||||||
|
* |
||||||
|
* @param actionListener 监听器 |
||||||
|
*/ |
||||||
|
public void addActionListener(ActionListener actionListener) { |
||||||
|
this.actionListener = actionListener; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Repaints the text. |
||||||
|
*/ |
||||||
|
public void paintComponent(Graphics _gfx) { |
||||||
|
super.paintComponent(_gfx); |
||||||
|
|
||||||
|
_gfx.setColor(Color.BLUE); |
||||||
|
if (drawLine) { |
||||||
|
_gfx.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private MouseInputAdapter mouseInputAdapter = new MouseInputAdapter() { |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseReleased(MouseEvent evt) { |
||||||
|
Object source = evt.getSource(); |
||||||
|
|
||||||
|
if (source instanceof UILabel) { |
||||||
|
//Action.
|
||||||
|
if (actionListener != null) { |
||||||
|
ActionEvent actionEvent = new ActionEvent(source, 99, ""); |
||||||
|
actionListener.actionPerformed(actionEvent); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseEntered(MouseEvent evt) { |
||||||
|
Object source = evt.getSource(); |
||||||
|
|
||||||
|
if (source instanceof UILabel) { |
||||||
|
((UILabel) source).setCursor(new Cursor(Cursor.HAND_CURSOR)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseExited(MouseEvent evt) { |
||||||
|
Object source = evt.getSource(); |
||||||
|
|
||||||
|
if (source instanceof UILabel) { |
||||||
|
((UILabel) source).setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseDragged(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseMoved(MouseEvent evt) { |
||||||
|
Object source = evt.getSource(); |
||||||
|
|
||||||
|
if (source instanceof UILabel) { |
||||||
|
((UILabel) source).setCursor(new Cursor(Cursor.HAND_CURSOR)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.table.TableModel; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Vector; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateInfoTable extends JTable { |
||||||
|
private UpdateInfoTableModel dataModel; |
||||||
|
|
||||||
|
public UpdateInfoTable(TableModel dm) { |
||||||
|
super(dm); |
||||||
|
dataModel = (UpdateInfoTableModel) dm; |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTable() { |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTable(String[] columnNames) { |
||||||
|
this(new UpdateInfoTableModel(columnNames, new ArrayList<Object[]>())); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTable(List<Object[]> data, String[] columnNames) { |
||||||
|
this(new UpdateInfoTableModel(columnNames, data)); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTable(Vector rowData, Vector columnNames) { |
||||||
|
super(rowData, columnNames); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTable(int numRows, int numColumns) { |
||||||
|
super(numRows, numColumns); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateInfoTableModel getDataModel() { |
||||||
|
return dataModel; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataModel(UpdateInfoTableModel dataModel) { |
||||||
|
this.dataModel = dataModel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.JLabel; |
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.table.DefaultTableCellRenderer; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateInfoTableCellRender extends DefaultTableCellRenderer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||||
|
Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); |
||||||
|
cell.setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); |
||||||
|
if ((Boolean) table.getValueAt(row, 2)) { |
||||||
|
cell.setBackground(new Color(0xdfecfd)); |
||||||
|
} |
||||||
|
if (column == 0) { |
||||||
|
//设置首列日期居中显示
|
||||||
|
setHorizontalAlignment(JLabel.CENTER); |
||||||
|
|
||||||
|
for (int i = 1; row - i >= 0; i++) { |
||||||
|
if (ComparatorUtils.equals(table.getValueAt(row - i, 0), value)) { |
||||||
|
//调用的父类JLabel的setText,table本身的值不变
|
||||||
|
setText(StringUtils.EMPTY); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return cell; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setForeground(Color c) { |
||||||
|
super.setForeground(c); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setBackground(Color c) { |
||||||
|
super.setBackground(c); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import javax.swing.table.AbstractTableModel; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateInfoTableModel extends AbstractTableModel { |
||||||
|
private String[] titles; |
||||||
|
private List<Object[]> data; |
||||||
|
|
||||||
|
public UpdateInfoTableModel(String[] titles, List<Object[]> data) { |
||||||
|
this.titles = titles; |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
public void populateBean(List<Object[]> data) { |
||||||
|
if (data == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
clear(); |
||||||
|
this.data = data; |
||||||
|
fireTableDataChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void clear() { |
||||||
|
data.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
public List<Object[]> updateBean() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getRowCount() { |
||||||
|
return data.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getColumnCount() { |
||||||
|
return titles.length; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) { |
||||||
|
return data.get(rowIndex)[columnIndex]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(int column) { |
||||||
|
return titles[column]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCellEditable(int rowIndex, int columnIndex) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { |
||||||
|
super.setValueAt(aValue, rowIndex, columnIndex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
package com.fr.design.onlineupdate.ui.widget; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.JTextArea; |
||||||
|
import javax.swing.table.TableCellRenderer; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Insets; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class UpdateInfoTextAreaCellRender extends JTextArea implements TableCellRenderer { |
||||||
|
public UpdateInfoTextAreaCellRender() { |
||||||
|
setMargin(new Insets(2, 2, 2, 2)); |
||||||
|
setLineWrap(true); |
||||||
|
setWrapStyleWord(true); |
||||||
|
setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||||
|
// 计算当前行的最佳高度
|
||||||
|
int maxPreferredHeight = 0; |
||||||
|
for (int i = 0; i < table.getColumnCount(); i++) { |
||||||
|
setText("" + table.getValueAt(row, i)); |
||||||
|
setSize(table.getColumnModel().getColumn(column).getWidth(), 0); |
||||||
|
maxPreferredHeight = Math.max(maxPreferredHeight, getPreferredSize().height); |
||||||
|
} |
||||||
|
|
||||||
|
if (table.getRowHeight(row) != maxPreferredHeight) { |
||||||
|
table.setRowHeight(row, maxPreferredHeight); |
||||||
|
} |
||||||
|
|
||||||
|
setText(value == null ? "" : value.toString()); |
||||||
|
setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); |
||||||
|
if ((Boolean) table.getValueAt(row, 2)) { |
||||||
|
setBackground(new Color(0xdfecfd)); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,7 @@ |
|||||||
|
package com.fr.onlineupdate.actions; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class FileDownloader { |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package com.fr.onlineupdate.domain; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XINZAI on 2018/8/21. |
||||||
|
*/ |
||||||
|
public class DownloadItem { |
||||||
|
} |