登录界面
主界面
添加界面:
代码:
1、af-swing为自己定义的布局(封装了),下方提供下载链接.....
2、数据来源于place.txt,这个可以随意更改(一行代表一个数据)
3、用到的技术:JTree,背景图片的绘制,文件的读取以及自定义解析
4、功能,左上角当前用户的显示,左下角当前时间的显示及实时更新,添加功能,查询功能,城市信息的显示功能,数据来源文件的更换,以及菜单栏的小功能
由于是小作业,所以功能比较简单,后续如果需要,添加很方便
上核心代码:
package my;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class App
{
private static void createGUI()
{
JFrame frame = new LoginFrame();
frame.setVisible(true);
}
public static void main(String[] args)
{
// 设置界面样式 Look And Feel
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch(Exception ex)
{
ex.printStackTrace();
}
// 创建GUI线程
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run()
{
createGUI();
}
});
}
}
主面板
package my;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.SimpleDateFormat;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
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.JTextField;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import af.swing.AfEditText;
import af.swing.AfToaster;
public class MainFrame extends JFrame
{
//用户信息
public String user;
public String password;
public AfEditText textfield=new AfEditText();
public JLabel disPlay=new JLabel("**:**:** --:--:--");
public JPanel statusBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
public String fileName;
//注:import javax.swing.Timer;
public Timer timer;
public MainFrame(String title)
{
super(title);
JsFrame jPanel = new JsFrame("地质图");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(750, 780);
// 居中显示
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = ( screenSize.width - this.getWidth())/2;
int y = ( screenSize.height - this.getHeight())/2;
this.setLocation(x, y);
//内容面板
JPanel root=new JPanel();
this.setContentPane(root);
root.setLayout(new BorderLayout());
ImageIcon icon=new ImageIcon("hongqi.jpg"); //图片和项目同一路径,故不用图片的路径
this.setIconImage(icon.getImage());
//数据库
root.add(textfield, BorderLayout.BEFORE_FIRST_LINE);
textfield.setPlaceHolder("当前数据来源 : " + "place.txt");
disPlay.setFont(new Font("宋体",Font.PLAIN,15));
disPlay.setHorizontalAlignment(SwingConstants.CENTER);
disPlay.setOpaque(true);
//disPlay.setBackground(Color.DARK_GRAY);
//disPlay.setForeground(Color.DARK_GRAY);
//树状图
JPanel sPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(jPanel.tree);
scrollPane.setPreferredSize(new Dimension(180, 300));
sPanel.setLayout(new BorderLayout());
sPanel.add(scrollPane, BorderLayout.WEST); //树状图
sPanel.add(jPanel.testButton, BorderLayout.PAGE_START); //添加按钮
sPanel.add(jPanel.findText, BorderLayout.PAGE_END); //查询区域
sPanel.add(jPanel.panel, BorderLayout.CENTER); //显示区域
root.add(sPanel, BorderLayout.CENTER);
//状态栏
statusBar.setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY),
new EmptyBorder(4, 4, 4, 4)));
statusBar.add(new JLabel("当前时间 : "));
statusBar.add(disPlay);
root.add(statusBar, BorderLayout.SOUTH);
//添加菜单
JMenuBar menubar=new JMenuBar();
this.setJMenuBar(menubar);
//菜单01:文件
JMenu fileMenu=new JMenu("文件");
menubar.add(fileMenu);
//菜单项
JMenuItem fileOpenCmd=new JMenuItem("打开");
JMenuItem fileSaveCmd=new JMenuItem("保存");
JMenuItem fileSaveAsCmd=new JMenuItem("另存为...");
JMenuItem fileReLoginCmd=new JMenuItem("重新登录");
JMenuItem fileExitCmd=new JMenuItem("退出");
//添加至菜单01:文件
fileMenu.add(fileOpenCmd);
fileMenu.add(fileSaveCmd);
fileMenu.add(fileSaveAsCmd);
fileMenu.addSeparator();
fileMenu.add(fileReLoginCmd);
fileMenu.add(fileExitCmd);
//菜单02:帮助
JMenu helpMenu=new JMenu("帮助");
menubar.add(helpMenu);
//菜单项
JMenuItem helpAbout=new JMenuItem("关于");
JMenuItem helpOpen=new JMenuItem("打开帮助");
//添加至菜单02:帮助
helpMenu.add(helpAbout);
helpMenu.add(helpOpen);
//添加“退出”菜单项 事件
fileExitCmd.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
});
fileOpenCmd.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
test();
}
});
fileReLoginCmd.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
onLogin();
}
});
}
//选择打开文件
private void test()
{
//创建一个文件选择器
JFileChooser chooser=new JFileChooser();
//FileNameExtensionFilter:文件名后缀过滤器
FileNameExtensionFilter filter=new FileNameExtensionFilter("TXT文件", "txt");
chooser.setFileFilter(filter);
//显示对话框
int ret=chooser.showOpenDialog(this);
//获取用户选择的结果
if(ret==JFileChooser.APPROVE_OPTION)
{
//结果为:已经存在的一个文件
File file=chooser.getSelectedFile();
fileName = file.getName();
//数据库
textfield.setPlaceHolder("当前数据来源 : " + fileName);
}
}
//开始按钮
public void onStart()
{
if(timer!=null)return;
//创建定时器,每隔1000毫秒执行一次(更新一次)
ActionListener task=new UpdateTask();
timer=new Timer(1000,task);
timer.start();
}
// 点'重新登录'
private void onLogin()
{
MainFrame.this.setVisible(false);
// 打开主界面
LoginFrame loginFrame = new LoginFrame();
loginFrame.setVisible(true);
}
//事件处理
private class UpdateTask implements ActionListener
{
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//1、actionPerformed()在界面工作线程里运行,所以必须迅速返回
//2、在这里可以直接更新UI
SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-dd hh:mm:ss");
String text=sdf.format(System.currentTimeMillis());
disPlay.setText(text);
}
}
}
添加功能:
package jsUtil;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import af.swing.AfPanel;
import af.swing.layout.AfColumnLayout;
import af.swing.layout.AfRowLayout;
import af.swing.AfEditText;
public class AddActionDialog extends JDialog
{
public AfEditText shengField=new AfEditText();
public AfEditText shiField=new AfEditText();
public AfEditText xianField=new AfEditText();
public JButton button=new JButton("确定");
public AddActionDialog(JFrame owner)
{
super(owner,"添加",true);
this.setSize(300,250);
//设置一个容器
AfPanel root=new AfPanel();
this.setContentPane(root);
root.setLayout(new AfColumnLayout(10));
root.padding(10);
//中间面板
AfPanel mainPanel=new AfPanel();
root.add(mainPanel, "1w"); //占据中间区域
mainPanel.setLayout(new AfColumnLayout(10));
mainPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
mainPanel.padding(10);
mainPanel.add(new JLabel("请输入"),"20px");
mainPanel.add(shengField,"20px");
mainPanel.add(shiField,"20px");
mainPanel.add(xianField,"20px");
mainPanel.setBackground(new Color(200, 236, 204,100));
//提示
shengField.setPlaceHolder("省(可省略不写)");
shiField.setPlaceHolder("市(直辖市)");
xianField.setPlaceHolder("县/区(可省略不写)");
//底下
AfPanel buttonPanel=new AfPanel();
root.add(buttonPanel, "30px");//底部区域30px
buttonPanel.setLayout(new AfRowLayout(10));
buttonPanel.add(new JLabel(), "1w");//占位
buttonPanel.add(button, "auto");
//点击按钮时,关闭对话框
button.addActionListener((e)->{
setVisible(false);
});
}
//显示对话框,并且待对话框关闭,返回用户输入的结果
public String exec()
{
Rectangle frmRect=this.getOwner().getBounds();
int width=this.getWidth();
int height=this.getHeight();
int x=frmRect.x+(frmRect.width-width)/2;
int y = frmRect.y + (frmRect.height - height)/2;
this.setBounds(x,y, width, height);
this.setVisible(true);
//返回输入
if(xianField.getText().length() == 0 && shiField.getText().length() == 0 && shengField.getText().length() != 0)
return shengField.getText().trim();
else
if(xianField.getText().length() == 0 && shiField.getText().length() != 0 && shengField.getText().length() != 0)
return shengField.getText().trim() + "-" + shiField.getText().trim();
else
if(xianField.getText().length() != 0 && shiField.getText().length() != 0 && shengField.getText().length() != 0)
return shengField.getText().trim() + "-" + shiField.getText().trim() + "-" + xianField.getText().trim();
else
if(xianField.getText().length() != 0 && shiField.getText().length() != 0 && shengField.getText().length() == 0)
return shiField.getText().trim() + "-" + xianField.getText().trim();
return shiField.getText().trim();
}
}
自定义解析:
package jsUtil;
public class ParseStr
{
//解析'-'的数量
public static int sum(String lineTxt, int flag)
{
for(int i=0;i<lineTxt.length();i++)
{
char c = lineTxt.charAt(i);
if(c == '-')
flag ++;
}
return flag;
}
//解析字符串,解析出 : 省-市-县
public static String[] SubStr(String s, int f)
{
String[] strPlace = new String[f+1];
if(f == 0)
{
strPlace[0] = s;
}
else
if(f == 1)
{
String s1 = s.substring(0, s.indexOf("-") );
String s2 = s.substring(s.indexOf("-")+1, s.length());
strPlace[0] = s1;
strPlace[1] = s2;
}
else
if(f == 2)
{
int d1 = s.indexOf("-");
int d2 = s.lastIndexOf("-");
String s1 = s.substring(0, d1);
String s2 = s.substring(d1+1, d2);
String s3 = s.substring(d2+1, s.length());
strPlace[0] = s1;
strPlace[1] = s2;
strPlace[2] = s3;
}
for(int i=0;i<strPlace.length;i++)
{
//System.out.print(strPlace[i] +"****");
}
//System.out.println();
return strPlace;
}
//解析字符串,解析出 : [省, 市, 县] -> 省-市-县
public static String SubStr2(String s2)
{
String s = s2.substring(1, s2.length()-1).replace(", ", "-").trim();
return s;
}
}
主面板的中间面板:
package my;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import af.swing.AfEditText;
import jsUtil.AddActionDialog;
import jsUtil.BgPicture;
import jsUtil.FileUlits;
import jsUtil.ParseStr;
import jsUtil.Query;
public class JsFrame extends JFrame
{
public static JTree tree = null;
public AfEditText findText = new AfEditText();
public static JScrollPane scrollPane = new JScrollPane(tree);
public static JButton testButton=new JButton("添加");
BgPicture panel = new BgPicture();
JLabel label = new JLabel("中国", JLabel.CENTER);
// 创建树根节点
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("中国");
public JsFrame(String title)
{
super(title);
JPanel root = new JPanel();
this.setContentPane(root);
this.setSize(550, 400);
root.setLayout(new BorderLayout());
ImageIcon icon=new ImageIcon("hongqi.jpg"); //图片和项目同一路径,故不用图片的路径
this.setIconImage(icon.getImage());
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 居中显示
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = ( screenSize.width - this.getWidth())/2;
int y = ( screenSize.height - this.getHeight())/2;
this.setLocation(x, y);
//显示区域
panel.setLayout(new BorderLayout());
label.setFont(new Font("华文新魏", Font.BOLD, 30));
panel.add(label, BorderLayout.CENTER);
root.add(panel, BorderLayout.CENTER);
/* 读取数据 */
try
{
//从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
BufferedReader br = new BufferedReader(new InputStreamReader
(new FileInputStream(new File("place.txt")), "UTF-8"));
String lineTxt = null; //代表读取一行数据
lineTxt = br.readLine();
while ((lineTxt = br.readLine()) != null) //逐行读取
{
lineTxt = lineTxt.trim();
System.out.println(lineTxt); //读取的一行数据
int flag = ParseStr.sum(lineTxt, 0);
//if(flag == 0)continue;
String[] strPlace = new String[flag+1]; //存地址place
strPlace = ParseStr.SubStr(lineTxt, flag); //解析地址
CreateTree(strPlace, rootNode); //创建tree
}
br.close();
}
catch (Exception e)
{
System.err.println("read errors :" + e);
}
// 使用根节点创建树组件
tree = new JTree(rootNode);
tree.setRootVisible(false);
// 设置树显示根节点句柄
tree.setShowsRootHandles(true);
scrollPane.setPreferredSize(new Dimension(150, 300));
// 添加滚动面板到那内容面板
root.add(scrollPane, BorderLayout.WEST);
//向根面板添加一个按钮
findText.setPlaceHolder("输入查询城市(回车执行)");
root.add(testButton, BorderLayout.PAGE_START);
root.add(findText, BorderLayout.PAGE_END);
findText.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Query.findInTree(tree, findText.getText());
}
});
// 设置节点选中监听器
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
System.out.println("当前被选中的节点: " + e.getPath());
String s = e.getPath().toString();
String str = ParseStr.SubStr2(s);
label.setText(str);
}
});
//添加监听器
testButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
String str=getUserInput();
System.out.println(str);
int flag = ParseStr.sum(str, 0);
String[] strPlace = new String[flag+1]; //存地址place
strPlace = ParseStr.SubStr(str, flag); //解析地址
CreateTree(strPlace, rootNode); //创建tree
try
{
FileUlits.write2Txt(str);
} catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(str + "添加成功");
}
});
}
public String getUserInput()
{
AddActionDialog dialog=new AddActionDialog(this);
return dialog.exec();
}
//树状图的数据
private static void CreateTree(String[] strPlace, DefaultMutableTreeNode rootNode)
{
DefaultMutableTreeNode onNode; //1节点
DefaultMutableTreeNode twNode; //2节点
DefaultMutableTreeNode thNode; //3节点
if(strPlace.length == 1)
{
//二级节点
onNode = new DefaultMutableTreeNode(strPlace[0]);
DefaultMutableTreeNode node = Query.queryByTreeNode(rootNode, onNode.getUserObject());
//System.out.println(node + "88888");
if(node == null)
rootNode.add(onNode);
}
else
if(strPlace.length == 2)
{
//三级节点
onNode = new DefaultMutableTreeNode(strPlace[0]);
twNode = new DefaultMutableTreeNode(strPlace[1]);
DefaultMutableTreeNode node1 = Query.queryByTreeNode(rootNode, onNode.getUserObject());
if(node1 != null)
{
DefaultMutableTreeNode node2 = Query.queryByTreeNode(rootNode, twNode.getUserObject());
if(node2 == null)
node1.add(twNode);
}
else
{
rootNode.add(onNode);
onNode.add(twNode);
}
}
else
if(strPlace.length == 3) //河南省-南阳市-方城县||河南省-南阳市-唐河县
{
//四级节点
onNode = new DefaultMutableTreeNode(strPlace[0]);
twNode = new DefaultMutableTreeNode(strPlace[1]);
thNode = new DefaultMutableTreeNode(strPlace[2]);
DefaultMutableTreeNode node1 = Query.queryByTreeNode(rootNode, onNode.getUserObject());
if(node1 != null)
{
DefaultMutableTreeNode node2 = Query.queryByTreeNode(rootNode, twNode.getUserObject());
{
if(node2 != null)
{
DefaultMutableTreeNode node3 = Query.queryByTreeNode(rootNode, thNode.getUserObject());
if(node3 == null)
node2.add(thNode);
}
else
{
node1.add(twNode);
twNode.add(thNode);
}
}
}
else
{
rootNode.add(onNode);
onNode.add(twNode);
twNode.add(thNode);
}
}
}
}
需要的,下载链接在此: