📄 dragdrop.java
字号:
/* ---------------------------------------------------------------------- The SINUS Firewall -- a TCP/IP packet filter for Linux Written within the SINUS project at the University of Zurich, SWITCH, Telekurs Payserv AG, ETH Zurich. originally based on the sf Firewall Software (C) 1996 by Robert Muchsel and Roland Schmid. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. SINUS Firewall resources: SINUS Homepage: http://www.ifi.unizh.ch/ikm/SINUS/ Firewall Homepage: http://www.ifi.unizh.ch/ikm/SINUS/firewall.html Frequently asked questions: http://www.ifi.unizh.ch/ikm/SINUS/sf_faq.html Mailing list for comments, questions, bug reports: firewall@ifi.unizh.ch ---------------------------------------------------------------------- */package sfclasses;import java.awt.*;import java.awt.event.*;import java.util.*;/** * This class is used for graphically displaying and drag-and-drop editing * of graphs. Vertex objects must implement DragDropObj. <br> * The drag and drop panel consists of a canvas to display and edit the * topology, two scrollbars and a status line. Object dependent methods * are defined in DragDropObj. <br> * This is a GUI class. * @see DragDropObj * @see Graph * @version 1.0 29 Nov 1996 * @author Roland E. Schmid */public class DragDrop extends Panel implements AdjustmentListener, MouseListener, MouseMotionListener, KeyListener { /** * Create a canvas and two scrollbars and lay them out in the panel * @param g graph to store objects and edges * @param newObjectClass class for object creation * (must be public and implement DragDropObj) */ public DragDrop(Graph g, Class newObjectClass) { // implicit super() call here creates the panel createClass = newObjectClass; graph = g; canvas = new DragDropCanvas(); canvas.addMouseListener(this); canvas.addMouseMotionListener(this); canvas.addKeyListener(this); hbar = new Scrollbar(Scrollbar.HORIZONTAL); vbar = new Scrollbar(Scrollbar.VERTICAL); hbar.addAdjustmentListener(this); vbar.addAdjustmentListener(this); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; setLayout(gbl); sp = new Panel(); sp.setLayout(new BorderLayout(0,0)); sp.add("Center", canvas); sp.add("South", hbar); sp.add("East", vbar); Utils.add_component(this, sp, gbl, gbc, 0, 0, 1, 1, 100, 100); status = new Label(""); Utils.add_component(this, status, gbl, gbc, 0, 1, 1, 1, 100, 0); mt = new MediaTracker(canvas); } /** * Create a canvas and two scrollbars and lay them out in the panel * @param g graph to store objects and edges * @param newObjectClass class for object creation * (must be public and implement DragDropObj) * @param edit enable / disable editing functions on startup */ public DragDrop(Graph g, Class newObjectClass, boolean edit) { this(g, newObjectClass); editEnabled = edit; } /** * Event handler <br> * mouse click on background creates new object<br> * left mouse button to draw lines<br> * right mouse button (or button + META) to drag objects<br> * double click on object to call object's execute() method */ public void adjustmentValueChanged(AdjustmentEvent ae) { Object source = ae.getAdjustable(); int whatkind = ae.getAdjustmentType(); Graphics canvas_g = canvas.getGraphics(); if (canvas_g == null) return; canvas_g.setXORMode(canvas.getBackground()); if (source == hbar) { // horizontal scroll bar switch(whatkind) { case AdjustmentEvent.UNIT_INCREMENT: offset_x = ae.getValue(); break; case AdjustmentEvent.UNIT_DECREMENT: offset_x = ae.getValue(); break; case AdjustmentEvent.BLOCK_INCREMENT: case AdjustmentEvent.BLOCK_DECREMENT: case AdjustmentEvent.TRACK: offset_x = ae.getValue(); break; } canvas.repaint(); canvas_g.dispose(); return; } else if (source == vbar) { // vertical scroll bar switch(whatkind) { case AdjustmentEvent.UNIT_INCREMENT: offset_y = ae.getValue(); break; case AdjustmentEvent.UNIT_DECREMENT: offset_y = ae.getValue(); break; case AdjustmentEvent.BLOCK_INCREMENT: case AdjustmentEvent.BLOCK_DECREMENT: case AdjustmentEvent.TRACK: offset_y = ae.getValue(); break; } canvas.repaint(); canvas_g.dispose(); return; } } // adjustmentValueChanged public void mouseClicked(MouseEvent me) {} public void mouseExited(MouseEvent me) {} public void mousePressed(MouseEvent me) { Graphics canvas_g = canvas.getGraphics(); if (canvas_g == null) return; canvas_g.setXORMode(canvas.getBackground()); int x = me.getX() + offset_x; int y = me.getY() + offset_y; DragDropObj v = find(x, y, orig_v); if ((selected) && (v != last_v)) { // deselect last_v last_v.highlight(canvas_g, offset_x, offset_y, false); selected = false; status.setText(""); } if (v != null) { // user clicked on object if (!selected) { v.highlight(canvas_g, offset_x, offset_y, true); selected = true; status.setText(v.getObjectID()); } if (!editEnabled) { if (me.getClickCount() > 1) { // double click v.userAction(Utils.getParentFrame(this), canvas_g, offset_x, offset_y); checkConnection(v); } last_v = v; canvas_g.dispose(); return; } // assert(editEnabled) if (me.getClickCount() > 1) { // double click v.execute(this); checkConnection(v); } else { // single click if (me.isMetaDown()) { // right button state = STATE_DRAG; orig_v = v; } else { state = STATE_DRAW; orig_v = v; orig_x = v.getX(); orig_y = v.getY(); } } last_x = v.getX(); last_y = v.getY(); } else { // v == null if (!editEnabled) { canvas_g.dispose(); return; } // create new vertex try { v = (DragDropObj)createClass.newInstance(); v.initImage(canvas, mt); boolean interrupted = true; while (interrupted) { try { mt.waitForAll(); interrupted = false; } catch (Exception ex) { System.out.println("DragDrop.handleEvent: MediaTracker.waitForAll Exception "+ex); } } v.setCoordinates(x, y); v.draw(canvas_g, offset_x, offset_y); graph.insertVertex(v); } catch (IllegalAccessException e1) { System.out.println("Cannot create object, class not accessible: " +createClass); } catch (InstantiationException e2) { System.out.println("Cannot create object, class is interface or abstract: "+createClass); } catch (ClassCastException e3) {System.out.println("Cannot create object, class does not implement DragDropObj: "+createClass); } last_x = x; last_y = y; } last_v = v; canvas_g.dispose(); return; } // mousePressed public void mouseReleased(MouseEvent me) { Graphics canvas_g = canvas.getGraphics(); if (canvas_g == null) return; canvas_g.setXORMode(canvas.getBackground()); int x = me.getX() + offset_x; int y = me.getY() + offset_y; DragDropObj v = find(x, y, orig_v); if (!dragged) { state = STATE_NONE; orig_v = null; canvas_g.dispose(); return; } dragged = false; if (state == STATE_DRAG) { // user is dragging object if (v == null) { moveto(canvas_g, last_v, x, y); } else { // don't place object on top of other object moveto(canvas_g, last_v, last_x, last_y); } state = STATE_NONE; } if (state == STATE_DRAW) { // user is drawing line if ((last_x != orig_x) || (last_y != orig_y)) { // erase line canvas_g.drawLine(orig_x - offset_x, orig_y - offset_y, last_x - offset_x, last_y - offset_y); } if (orig_v.canConnectTo(v)) { // deselect last_v if ((last_v != orig_v) && (last_v != null)) last_v.highlight(canvas_g, offset_x, offset_y, false); if (v != null) { // insert or delete edge (toggle) // draw line (XOR-Mode -> erase or delete) if (graph.searchEdge(orig_v, v)) { // edge exists -> delete edge drawEdge(canvas_g,orig_v, v); graph.deleteEdge(orig_v, v); } else { // edge does not exist -> insert edge graph.insertEdge(orig_v, v, Color.black); drawEdge(canvas_g,orig_v, v); checkConnection(orig_v); } } } // can not connect origin to destination object else { orig_v.connectError(Utils.getParentFrame(this)); } last_v = orig_v; last_x = orig_x; last_y = orig_y; state = STATE_NONE; } orig_v = null; canvas_g.dispose(); return; } // mouseReleased public void mouseMoved(MouseEvent me) {} public void mouseDragged(MouseEvent me) { int X = me.getX(); int Y = me.getY(); Graphics canvas_g = canvas.getGraphics(); if (canvas_g == null) return; canvas_g.setXORMode(canvas.getBackground()); int x = X + offset_x; int y = Y + offset_y; DragDropObj v = find(x, y, orig_v); if (state == STATE_DRAG) { // user is dragging object if (X < 0 || X >= canvas_width || Y < 0 || Y >= canvas_height) updateVirtual(X, Y, true, false); moveto(canvas_g, last_v, x, y); dragged = true; } if (state == STATE_DRAW) { // user is drawing line dragged = true; if ((last_x != orig_x) || (last_y != orig_y)) { // erase line canvas_g.drawLine(orig_x - offset_x, orig_y - offset_y, last_x - offset_x, last_y - offset_y); } if (X < 0 || X >= canvas_width || Y < 0 || Y >= canvas_height) updateVirtual(X, Y, false, true); if (last_v != v) { // deselect last_v if ((last_v != orig_v) && (last_v != null)) last_v.highlight(canvas_g, offset_x, offset_y, false); // select v if (v != null) if (orig_v.canConnectTo(v)) v.highlight(canvas_g, offset_x, offset_y, true); } // draw new line canvas_g.drawLine(orig_x - offset_x, orig_y - offset_y, x - offset_x, y - offset_y); last_v = v; last_x = x; last_y = y; } canvas_g.dispose(); return; } // mouseDragged public void mouseEntered(MouseEvent me) { // update status line DragDropObj ddotmp = getSelected(); if (ddotmp != null) status.setText(ddotmp.getObjectID()); return; } // mouseEntered public void keyTyped(KeyEvent ke) {} public void keyReleased(KeyEvent ke) {} public void keyPressed(KeyEvent ke) { Graphics canvas_g = canvas.getGraphics(); if (canvas_g == null) return; canvas_g.setXORMode(canvas.getBackground()); if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) { // Esc pressed if (state == STATE_DRAG) { // user is dragging object moveto(canvas_g, last_v, last_x, last_y); orig_v = null; dragged = false; state = STATE_NONE; } if (state == STATE_DRAW) { // user is drawing line if ((last_x != orig_x) || (last_y != orig_y)) { // erase line canvas_g.drawLine(orig_x - offset_x, orig_y - offset_y, last_x - offset_x, last_y - offset_y); } // deselect last_v if ((last_v != orig_v) && (last_v != null)) last_v.highlight(canvas_g, offset_x, offset_y, false); state = STATE_NONE; last_v = orig_v; last_x = orig_x; last_y = orig_y; orig_v = null; dragged = false; } } // delete pressed -> delete highlighted vertex else if (ke.getKeyCode() == 127) { if (!editEnabled) { canvas_g.dispose(); return; } if ((state == STATE_NONE) && (last_v != null) && selected) { // let's first check if the user has changed his mind if (!last_v.confirmDelete()) { canvas_g.dispose(); return; } // deselect vertex last_v.highlight(canvas_g, offset_x, offset_y, false); selected = false; status.setText(""); // erase edges Enumeration neighbors = graph.findNeighbors(last_v); DragDropObj n; while (neighbors.hasMoreElements()) { n = (DragDropObj)neighbors.nextElement(); drawEdge(canvas_g,last_v, n); } // erase vertex last_v.erase(canvas_g, offset_x, offset_y); // delete vertex from graph graph.deleteVertex(last_v); } } // else if (e.key == 63) // `?' pressed // System.out.println("DragDrop: graph "+graph); canvas_g.dispose(); return; } // keyPressed /** * Called when panel size changes (e.g. on startup) */ public synchronized void setBounds(int x, int y, int width, int height) { // call setBounds() of superclass super.setBounds(x, y, width, height); // calculate virtual canvas size int hbar_size = hbar.getValue(); int vbar_size = vbar.getValue(); canvas_width = width - vbar_size; canvas_height = height - hbar_size; max_x = canvas_width; max_y = canvas_height; if (offset_x > max_x - canvas_width) offset_x = max_x - canvas_width; if (offset_y > max_y - canvas_height) offset_y = max_y - canvas_height; Enumeration vertices = graph.getAllVertices(); DragDropObj v; while (vertices.hasMoreElements()) { v = (DragDropObj)vertices.nextElement(); v.initImage(canvas, mt); int offset; int vx = v.getX()+10; if (vx > max_x) { offset = vx - max_x; if (canvas_width >= 2) { offset = (int)Math.ceil((double)offset / (double)(canvas_width / 2)); max_x += offset * (canvas_width / 2); } else max_x = vx; } int vy = v.getY()+10; if (vy > max_y) { offset = vy - max_y; if (canvas_height >= 2) { offset = (int)Math.ceil((double)offset / (double)(canvas_height / 2));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -