package bs.util.tool.commongui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import bs.util.io.PropertiesUtils;
/**
* GUI主界面.
*/
public class GuiMain extends JFrame {
private static final long serialVersionUID = 1L;
/**
* 软件名称.
*/
private String softName = "Common GUI Tools";
/**
* GUI配置属性Map.
*/
private static Map<String, String> propsMap;
/**
* GUI配置属性Map(更多工具).
*/
private static Map<String, String> more_propsMap;
/**
* GUI配置属性Map(网络工具).
*/
private static Map<String, String> network_propsMap;
/**
* 常用插件ID.
*/
private static String commonUsePlugins;
/**
* 宽度, 满足宽高比例1024:768.
*/
private static int gui_width;
/**
* 高度.
*/
private int gui_height = gui_width * 768 / 1024;
/**
* 入口程序.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
propsMap = PropertiesUtils.getPropertiesMap(GuiUtils
.getActualPath("conf/common_gui_tools.properties"));
more_propsMap = PropertiesUtils.getPropertiesMap(GuiUtils
.getActualPath("conf/more_tools.properties"));
network_propsMap = PropertiesUtils.getPropertiesMap(GuiUtils
.getActualPath("conf/network_tools.properties"));
propsMap.putAll(more_propsMap);
propsMap.putAll(network_propsMap);
commonUsePlugins = propsMap.get("CommonUseTools");
gui_width = Integer.parseInt(propsMap.get("GUIWidth"));
// 设置皮肤外观
String guiSkinStr = propsMap.get("GUISkin").trim();
if (guiSkinStr.length() > 0) {
String[] guiSkins = guiSkinStr.split(",");
for (String skin : guiSkins) {
if (setLookAndFeel(skin)) {
break;
}
}
}
// 设置显示字体
// 中文字体
GuiUtils.fontStyles_cn = new String(propsMap.get("fontStyles_cn").getBytes("ISO-8859-1"), "UTF-8")
.split(",");
GuiUtils.fontStyle_cn = GuiUtils.getAvailableFont(GuiUtils.fontStyles_cn);
// 英文字体
GuiUtils.fontStyles = (new String(propsMap.get("fontStyles").getBytes("ISO-8859-1"), "UTF-8") + "," + GuiUtils.fontStyle_cn)
.split(",");
GuiUtils.fontStyle = GuiUtils.getAvailableFont(GuiUtils.fontStyles);
// 支持Unicode的字体
GuiUtils.fontStyles_un = (new String(propsMap.get("fontStyles_un").getBytes("ISO-8859-1"), "UTF-8")
+ "," + GuiUtils.fontStyle_cn).split(",");
GuiUtils.fontStyle_un = GuiUtils.getAvailableFont(GuiUtils.fontStyles_un);
// 初始化字体
GuiUtils.initFont();
GuiMain frame = new GuiMain();
frame.setVisible(true);
} catch (Exception e) {
GuiUtils.log(e);
}
}
/**
* 设置皮肤外观.
*/
private boolean setLookAndFeel(String lookAndFeel) {
try {
UIManager.setLookAndFeel(lookAndFeel);
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
return true;
} catch (Exception e) {
return false;
}
}
});
}
/**
* Swing面板.
*/
private JPanel contextPanel;
/**
* 警告、错误消息输出表单.
*/
public static JTextArea msgTextArea = new JTextArea();
/**
* Tab Panel.
*/
private JTabbedPane tabbedPane = new JTabbedPane();
/**
* 插件属性,key:插件ID_插件名称,value:{插件ID, 插件名称, 插件类名全称, 插件图标}.
*/
private Map<Integer, List<String>> pluginsProperties = new LinkedHashMap<Integer, List<String>>();
/**
* 插件title面板,key:插件ID,value:title面板.
*/
private Map<Integer, JPanel> titlesPanel = new HashMap<Integer, JPanel>();
/**
* 插件面板,key:插件ID,value:JPanel面板.
*/
private Map<Integer, JPanel> pluginsPanel = new HashMap<Integer, JPanel>();
/**
* 记录插件在当前TabPanel的位置,key:插件ID,value:Index索引位置.
*/
private Map<Integer, Integer> pluginsTabIndex = new HashMap<Integer, Integer>();
/**
* 记录当前TabPanel位置的插件,key:Index索引位置,value:插件ID.
*/
private Map<Integer, Integer> tabPluginsId = new HashMap<Integer, Integer>();
/**
* 设定显示位置及大小.
*/
private void setLocatinAndSize() {
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension dimension = kit.getScreenSize();
int screen_width = (int) dimension.getWidth();
int screen_height = (int) dimension.getHeight();
// 如果显示屏幕分辨率没有已设定的面板大, 则按显示屏幕分辨率显示
gui_width = screen_width < gui_width ? screen_width : gui_width;
gui_height = screen_height < gui_height ? screen_height : gui_height;
setLocation((screen_width - gui_width) / 2, (screen_height - gui_height) / 2); // 默认距屏幕左上角(0, 0), 此处设为居中显示屏幕
setSize(gui_width, gui_height); // JFrame大小
}
public GuiMain() {
contextPanel = (JPanel) getContentPane();
setTitle(softName); // 标题
// setResizable(false); // 默认不设置时是true
setLocatinAndSize();
// setLayout(new FlowLayout(FlowLayout.RIGHT)); // 流布局管理器(默认居中对齐)
setLayout(new BorderLayout()); // 边界布局管理器
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Toolkit kit = Toolkit.getDefaultToolkit();
setIconImage(GuiUtils.getImage("img/icon/cgt_Icon.png", kit));
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar); // 菜单工具条
add(tabbedPane, BorderLayout.CENTER);
// 警告、错误消息输出域
JPanel msgPanel = new JPanel(new BorderLayout());
msgPanel.setBorder(BorderFactory.createTitledBorder("Console:"));
msgTextArea.setFont(GuiUtils.font13);
msgTextArea.setRows(5);
msgTextArea.setEditable(false);
msgTextArea.setLineWrap(true); // 自动换行
msgPanel.add(new JScrollPane(msgTextArea), BorderLayout.CENTER);
// paste复制按钮、clear清楚按钮
JPanel msgButtonPanel = new JPanel(new GridLayout(2, 1));
JButton pasteButton = new JButton("paste");
pasteButton.setFont(GuiUtils.font13_cn);
pasteButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
StringSelection selection = new StringSelection(msgTextArea.getText());
// 获取系统剪切板,复制输出消息
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
}
});
msgButtonPanel.add(pasteButton);
JButton clearButton = new JButton("clear");
clearButton.setFont(GuiUtils.font13_cn);
clearButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
msgTextArea.setText("");
}
});
msgButtonPanel.add(clearButton);
msgPanel.add(msgButtonPanel, BorderLayout.EAST);
add(msgPanel, BorderLayout.SOUTH);
JMenu fileMenu = new JMenu(" File ");
menuBar.add(fileMenu); // File菜单
JMenuItem exitItem = new JMenuItem("Exit"); // 二级菜单
exitItem.setIcon(GuiUtils.getIcon("img/icon/cgt_Exit.png", kit));
fileMenu.add(exitItem);
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
JMenu toolsMenu = new JMenu(" Tools ");
menuBar.add(toolsMenu); // 工具菜单
JMenu more_toolsMenu = new JMenu(" More Tools ");
menuBar.add(more_toolsMenu); // 更多工具菜单
JMenu network_toolsMenu = new JMenu(" NetWork Tools ");
menuBar.add(network_toolsMenu); // 网络工具菜单
JMenu helpMenu = new JMenu(" Help ");
menuBar.add(helpMenu); // Help菜单
JMenuItem fontItem = new JMenuItem("Font"); // 二级菜单
fontItem.setIcon(GuiUtils.getIcon("img/icon/cgt_Font.png", kit));
helpMenu.add(fontItem);
fontItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(contextPanel, softName + " 使用的字体\n\n中文字体: " + GuiUtils.fontStyle_cn
+ "\n英文字体: " + GuiUtils.fontStyle + "\nUnicode字体: " + GuiUtils.fontStyle_un + "\n", "Font",
JOptionPane.INFORMATION_MESSAGE);
}
});
helpMenu.addSeparator(); // 分隔符
JMenuItem aboutItem = new JMenuItem("About"); // 二级菜单
aboutItem.setIcon(GuiUtils.getIcon("img/icon/cgt_About.png", kit));
helpMenu.add(aboutItem);
aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(contextPanel, "Version: " + propsMap.get("Version")
+ "\nAuthor: bs2004@163.com\nDevelop Date: " + propsMap.get("Develop_Date"), "About",
JOptionPane.INFORMATION_MESSAGE);
}
});
// 关闭图标
final Icon closeIcon = GuiUtils.getIcon("img/icon/cgt_Close.png", kit);
// 关闭Label事件
final MouseListener closeLabelListener = new MouseListener() {
public void mouseReleased(MouseEvent e) {
// 当前点击Label的父Panel
int closeIndex = tabbedPane.indexOfTabComponent(((JPanel) ((JLabel) e.getSource()).getParent()));
tabbedPane.remove(closeIndex);
// 移除插件在当前TabPanel的位置的记录
pluginsTabIndex.remove(tabPluginsId.get(closeIndex));
// 清空原TabPanel位置的插件记录,重新记录
tabPluginsId.clear();
// remove插件面板后调整索引位置
for (Integer i : pluginsTabIndex.keySet()) {
Integer index = pluginsTabIndex.get(i);
if (index > closeIndex) {
pluginsTabIndex.put(i, index - 1);
}
tabPluginsId.put(pluginsTabIndex.get(i), i);
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
};
tabbedPane.setFont(GuiUtils.font14b_cn);
String toolPrefix = "Tool_";
try {
List<String> pluginSortAndNames = new ArrayList<String>();
for (String key : propsMap.keySet()) {
if (key.startsWith(toolPrefix)) {
pluginSortAndNames.add(key.substring(toolPrefix.length()));
}
}
Collections.sort(pluginSortAndNames); // 排序
// 插件属性,按ID升序排列
int moreTools_cnt = more_propsMap.size();
int networkTools_cnt = network_propsMap.size();
for (int i = 0; i < pluginSortAndNames.size(); i++) {
String key = pluginSortAndNames.get(i);
List<String> pluginProps = new ArrayList<String>();
String[] sortAndName = key.split("_");
String pluginName = sortAndName[1];
pluginProps.add(sortAndName[0]);
pluginProps.add(pluginName);
String classAndIcon = propsMap.get(toolPrefix + key);
String className = classAndIcon.split("_")[0];
pluginProps.add(className);
pluginProps.add(classAndIcon.indexOf("_") > 0 ? classAndIcon.substring(className.length() + 1) : "");
Integer pluginId = Integer.parseInt(sortAndName[0]);
try {
Class.forName(className);
pluginsProperties.put(pluginId, pluginProps);
// 插件图标
String iconPath = pluginProps.get(3).trim();
Icon toolIcon = null;
if (iconPath.length() > 0) {
toolIcon = GuiUtils.getIcon(iconPath, kit);
}
if (("," + commonUsePlugins + ",").contains("," + pluginId + ",")) {
// 初始只加载常用插件
JPanel pluginPanel = (JPanel) (Class.forName(className)).newInstance();
pluginsPanel.put(pluginId, pluginPanel);
// 设置title栏左侧图标,中间插件名称,右侧关闭图标
JPanel titlePanel = new JPanel();
titlePanel.setOpaque(false);
titlePanel.add(new JLabel(toolIcon), BorderLayout.WEST);
titlePanel.add(new JLabel(pluginName + " "), BorderLayout.CENTER);
JLabel closeLabel = new JLabel(closeIcon);
closeLabel.addMouseListener(closeLabelListener);
titlePanel.add(closeLabel, BorderLayout.EAST);
titlesPanel.put(pluginId, titlePanel);
tabbedPane.addTab(null, pluginPanel);
tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, titlePanel);
pluginsTabIndex.put(pluginId, tabbedPane.getTabCount() - 1);
tabPluginsId.put(tabbedPane.getTabCount() - 1, pluginId);
// 设置图标,图标在右侧
// tabbedPane.addTab(pluginName + " ", (JPanel) (Class.forName(className)).newInstance());
// tabbedPane.setIconAt(tabbedPane.getTabCount() - 1, toolIcon);
}
// 设置菜单
JMenuItem toolItem = new JMenuItem(pluginName); // 二级菜单
toolItem.setName(Integer.toString(pluginId));
if (pluginId > 50 && pluginId < 71) {
more_toolsMenu.add(toolItem);
moreTools_cnt--;
if (moreTools_cnt > 0) {
more_toolsMenu.addSeparator(); // 分隔符
}
} else if (pluginId > 70 && pluginId < 99) {
network_toolsMenu.add(toolItem);
networkTools_cnt--;
if (networkTools_cnt > 0) {
network_toolsMenu.addSeparator(); // 分隔符
}
} else {
toolsMenu.add(toolItem);
if (pluginId != 99) {
toolsMenu.addSeparator(); // 分隔符
}
}
toolItem.setIcon(toolIcon);
toolItem.addActionListener(new ActionListener() {
// 菜单事件
public void actionPerformed(ActionEvent event) {
JMenuItem item = (JMenuItem) event.getSource();
Integer pluginId = Integer.parseInt(item.getName());
// 如果面板没有add到tablePanel上,则add
if (pluginsTabIndex.get(pluginId) == null) {
List<String> pluginProps = pluginsProperties.get(pluginId);
// 懒加载未加载的插件
JPanel pluginPanel = pluginsPanel.get(pluginId);
if (pluginPanel == null) {
try {
pluginPanel = (JPanel) (Class.forName(pluginProps.get(2))).newInstance();
pluginsPanel.put(pluginId, pluginPanel);
} catch (Exception e) {
GuiUtils.log(e);
}
}
// 设置title栏左侧图标,中间插件名称,右侧关闭图标
JPanel titlePanel = titlesPanel.get(pluginId);
if (titlePanel == null) {
titlePanel = new JPanel();
titlePanel.setOpaque(false);
String iconPath = pluginProps.get(3).trim();
if (iconPath.length() > 0) {
titlePanel.add(
new JLabel(GuiUtils.getIcon(iconPath, Toolkit.getDefaultToolkit())),
BorderLayout.WEST);
}
titlePanel.add(new JLabel(pluginProps.get(1) + " "), BorderLayout.CENTER);
JLabel closeLabel = new JLabel(closeIcon);
closeLabel.addMouseListener(closeLabelListener);
titlePanel.add(closeLabel, BorderLayout.EAST);
titlesPanel.put(pluginId, titlePanel);
}
tabbedPane.addTab(null, pluginPanel);
tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, titlePanel);
pluginsTabIndex.put(pluginId, tabbedPane.getTabCount() - 1);
tabPluginsId.put(tabbedPane.getTabCount() - 1, pluginId);
// 选中当前新add的插件面板
tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
} else {
// 如果面板已经add到tablePanel上,则选中
tabbedPane.setSelectedIndex(pluginsTabIndex.get(pluginId));
}
}
});
} catch (ClassNotFoundException e) {
GuiUtils.log("Warn: Ignore plugin \"" + sortAndName[1]
+ "\", because can not find it's Class \"" + className + "\".");
}
}
} catch (Exception e) {
GuiUtils.log(e);
}
}
}