登錄界面
主界面
添加界面:
代碼:
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);
}
}
}
}
需要的,下載鏈接在此: