?? mstvisual.java
字號:
implements KeyListener {
public void keyPressed(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
paintResult = false;
repaint();
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
//當delete鍵按下時
if (lineBrighter) {
//如果當前有線高亮顯示,則刪除該線
startNode.remove(currentLineIndex);
endNode.remove(currentLineIndex);
weight.remove(currentLineIndex);
weightBack.remove(currentLineIndex);
lineBrighter = false;
repaint();
}
if (brighter) {
//如果當前有結點高亮顯示,則刪除該結點以及相應的邊
for (int i = 0; i < startNode.size(); i++) {
int index = ( (Integer) startNode.get(i)).intValue();
if (index == currentNodeIndex) {
startNode.remove(i);
endNode.remove(i);
weight.remove(i);
weightBack.remove(i);
i--;
}
if (index > currentNodeIndex) {
startNode.set(i, new Integer(index - 1));
}
}
for (int i = 0; i < endNode.size(); i++) {
int index = ( (Integer) endNode.get(i)).intValue();
if (index == currentNodeIndex) {
startNode.remove(i);
endNode.remove(i);
weight.remove(i);
weightBack.remove(i);
i--;
}
if (index > currentNodeIndex) {
endNode.set(i, new Integer(index - 1));
}
}
node.remove(currentNodeIndex);
nodeName.remove(currentNodeIndex);
brighter = false;
repaint();
}
}
};
}
//鼠標事件監聽類
class MouseL
implements MouseListener {
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
paintResult = false;
if (e.getClickCount() == 2 && brighter) {
String str = JOptionPane.showInputDialog(null, "請輸入新的結點名:",
"更改結點名",
JOptionPane.
INFORMATION_MESSAGE);
if (str == null) {
return;
}
else if (str.length() > 0) {
nodeName.set(currentNodeIndex, str);
}
else {
nodeName.set(currentNodeIndex, String.valueOf(name++));
}
repaint();
}
if (e.getClickCount() == 2 && lineBrighter) {
//鼠標經過一條邊且雙擊時,更改權重
System.out.println("Change weight");
String str = JOptionPane.showInputDialog(null, "請輸入該邊的新權重",
"更改權重",
JOptionPane.
INFORMATION_MESSAGE);
if (str != null && str.length() > 0) {
weight.set(currentLineIndex, Integer.valueOf(str));
weightBack.set(currentLineIndex, Integer.valueOf(str));
}
else {
weight.set(currentLineIndex, new Integer(0));
weightBack.set(currentLineIndex, new Integer(0));
}
return;
}
if (e.getClickCount() == 2 && !hasPre) {
//鼠標雙擊且沒有一條邊的開始結點時,新建一個結點
String str = JOptionPane.showInputDialog(null, "請輸入結點名:",
"新建結點",
JOptionPane.
INFORMATION_MESSAGE);
if (str == null) {
return;
}
else if (str.length() > 0) {
nodeName.add(str);
}
else {
nodeName.add(String.valueOf(name++));
}
node.add(new Point(e.getX(), e.getY()));
drawNode = true;
repaint();
}
if (e.getClickCount() == 2 && hasPre) {
//鼠標雙擊且已經有了一條邊的開始結點時,取消該邊的創建,并將開始結點鏈表中的最后一個元素刪除
hasPre = false;
repaint();
if (startNode.size() > 0) {
startNode.removeLast();
}
}
}
public void mouseReleased(MouseEvent e) {
paintResult = false;
for (int i = 0; i < node.size(); i++) {
if (e.getX() >= ( (Point) node.get(i)).x
&& e.getX() <= ( ( (Point) node.get(i)).x + 30)
&& e.getY() >= ( (Point) node.get(i)).y
&& e.getY() <= ( ( (Point) node.get(i)).y + 30)) {
if (!hasPre) {
//點擊鼠標,而且還不存在一條邊的開始結點時,將當前結點加入到開始結點鏈表中
if (!move) {
preNode.x = ( (Point) node.get(i)).x;
preNode.y = ( (Point) node.get(i)).y;
startNode.add(new Integer(i));
hasPre = true;
drawEdge = true;
}
else {
move = false;
}
}
else {
//點擊鼠標,而且已經存在一條邊的開始結點時,將當前結點加入到結束結點鏈表中
//創建一條邊并輸入該邊的權重
currentNode.x = ( (Point) node.get(i)).x;
currentNode.y = ( (Point) node.get(i)).y;
if (i == ( (Integer) startNode.getLast()).intValue()) {
return;
}
endNode.add(new Integer(i));
findEdge = true;
hasPre = false;
repaint();
String str = JOptionPane.showInputDialog(null, "請輸入該邊的權重",
"新建邊", JOptionPane.INFORMATION_MESSAGE);
if (str != null && str.length() > 0) {
weight.add(Integer.valueOf(str));
weightBack.add(Integer.valueOf(str));
}
else {
weight.add(new Integer(0));
weightBack.add(new Integer(0));
}
drawWeight = true;
repaint();
}
}
}
}
}
boolean move = false;
//鼠標運動監聽類
class MouseM
implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
if (brighter) {
move = true;
node.set(currentNodeIndex, new Point(e.getX(), e.getY()));
repaint();
}
}
public void mouseMoved(MouseEvent e) {
if (hasPre) {
//如果已經存在一條邊的開始結點,則得到當前鼠標位置,并畫出開始結點與鼠標位置之間的直線
currentMousePoint.x = e.getX();
currentMousePoint.y = e.getY();
repaint();
}
for (int i = 0; i < startNode.size() && i < endNode.size(); i++) {
int[] p = getPaintPosition( ( (Point) node.get( ( (Integer) startNode.
get(i)).intValue())).x,
( (Point) node.get( ( (Integer) startNode.
get(i)).intValue())).y,
( (Point) node.get( ( (Integer) endNode.
get(i)).intValue())).x,
( (Point) node.get( ( (Integer) endNode.
get(i)).intValue())).y);
float k;
if ( (p[2] - p[0]) != 0) {
k = ( (float) (p[3] - p[1])) / ( (float) (p[2] - p[0]));
}
else {
k = Integer.MAX_VALUE;
}
float b = p[3] - k * p[2];
int small;
int large;
if (p[2] > p[0]) {
small = p[0];
large = p[2];
}
else {
small = p[2];
large = p[0];
}
//如果鼠標經過圖中的某一條邊,則高亮顯示該邊及相應權重
if (k == Integer.MAX_VALUE) {
if ( (e.getX() >= p[0] - 15) && (e.getX() <= p[0] + 15) &&
e.getX() >= small && e.getX() <= large) {
lineBrighter = true;
paintResult = false;
currentLineIndex = i;
repaint();
break;
}
}
if (e.getY() <= (k * e.getX() + b + 20) &&
e.getY() >= (k * e.getX() + b - 20) &&
e.getX() >= small && e.getX() <= large) {
lineBrighter = true;
paintResult = false;
currentLineIndex = i;
repaint();
break;
}
else {
lineBrighter = false;
repaint();
}
}
//如果鼠標經過圖中某一個結點,則高亮顯示該結點及相應結點名
for (int i = 0; i < node.size(); i++) {
if (e.getX() >= ( (Point) node.get(i)).x
&& e.getX() <= ( ( (Point) node.get(i)).x + 30)
&& e.getY() >= ( (Point) node.get(i)).y
&& e.getY() <= ( ( (Point) node.get(i)).y + 30)) {
currentNodeIndex = i;
brighter = true;
paintResult = false;
repaint();
break;
}
else {
brighter = false;
repaint();
}
}
}
}
public static void main(String[] args) {
JFrame fram = new JFrame();
MSTVisual pan = new MSTVisual();
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("文件");
JMenu helpMenu = new JMenu("幫助");
JMenuItem exit = new JMenuItem("退出");
JMenuItem topic = new JMenuItem("主題");
JMenuItem about = new JMenuItem("關于");
exit.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(1);
}
}
);
topic.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
Process process = Runtime.getRuntime().exec(
"notepad help.txt");
}
catch (IOException e) {
System.out.println("Open file error!");
}
}
}
);
about.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(null,
" 最小生成樹算法過程演示\n winpro ",
"關于", JOptionPane.INFORMATION_MESSAGE);
}
}
);
fileMenu.add(exit);
helpMenu.add(topic);
helpMenu.add(about);
menuBar.add(fileMenu);
menuBar.add(helpMenu);
fram.setJMenuBar(menuBar);
Container c = fram.getContentPane();
c.add(pan);
fram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fram.setSize(800, 600);
fram.setTitle("最上生成樹算法演示");
fram.setVisible(true);
}
private boolean drawEdge = false;
private boolean drawNode = false;
private boolean brighter = false;
private boolean drawWeight = false;
private boolean hasPre = false;
private boolean findEdge = false;
private boolean findMSTEdge = false;
private boolean paintResult = false;
private boolean lineBrighter = false;
private int currentNodeIndex = 0;
private int currentLineIndex = 0;
private int sMSTEdge = 0;
private int eMSTEdge = 0;
private int iD = -1;
private int name = 0;
private Thread main_thread;
private LinkedList startNode = new LinkedList();
private LinkedList endNode = new LinkedList();
private LinkedList weight = new LinkedList();
private LinkedList weightBack = new LinkedList();
private LinkedList nodeName = new LinkedList();
private LinkedList node = new LinkedList();
private Vector MST = new Vector();
private Vector sMSTEdgeV = new Vector();
private Vector eMSTEdgeV = new Vector();
private Vector isSelect = new Vector();
private Vector edge = new Vector();
private Point preNode = new Point();
private Point currentNode = new Point();
private Point currentMousePoint = new Point();
private JButton process = new JButton("演示算法");
private MouseL mouse = new MouseL();
private MouseM mouseM = new MouseM();
private KeyDown key = new KeyDown();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -