我有听众输入此代码:
someBoolean = true;
case FILL_POLYGON:
{
if (greenLightForFilling == true)
{
while (someBoolean)
{
fillPressed = true;
fillPolygon(polyFiller);
}
}
break;
} // end FILL_POLYGON
当我点击f
时。
是否可以在while
循环中添加另一个侦听器,所以何时
用户再次点击f
,someBoolean
会获得false
?
请注意,我已经有一个用于输入交换机案例的密钥监听器。
此致
编辑 - 相关代码:
public class DrawPolygons
{
public static void main (String[] args) throws FileNotFoundException
{
// attaching the menu to the frame
final JFrame frame = new JFrame("Draw polygons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new DrawingPanel());
frame.pack();
frame.setVisible(true);
}
}
/**
* Main class
* @author X2
*
*/
class DrawingPanel extends JPanel implements MouseListener, MouseMotionListener ,KeyListener
{
/**
* private variables
*/
// dimensions of the window
private static final long serialVersionUID = 1L;
private static final Dimension MIN_DIM = new Dimension(300, 300);
private static final Dimension PREF_DIM = new Dimension(500, 500);
// Hot-keys hit by the user - used for keyboard listening
private static final char FILL_POLYGON = 'F';
private static final char SAVE_POLYGONS = 'S';
private static final char LOAD_POLYGONS = 'L';
private static final char FILL_POLYGON_LOWERCASE = 'f';
private static final char SAVE_POLYGONS_LOWERCASE = 's';
private static final char LOAD_POLYGONS_LOWERCASE = 'l';
private static final String SPACE = " ";
// boolean flags
private boolean greenLightForFilling = false;
private boolean polygonDone = false;
private boolean loading = false;
private boolean loading2 = false;
private boolean fillPressed = false;
// data structures
// The dummy point tracking the mouse
private final Point trackPoint = new Point();
// The list of points making up a polygon
private ArrayList<Point> points = new ArrayList<Point>();
// holds edges of current polygon
private ArrayList<Edge> edges = new ArrayList<Edge>();
// array-list of vertices
private ArrayList<Point> vertices = new ArrayList<Point>();
// all the polygons
private ArrayList<Polygon> polygons = new ArrayList<Polygon>();
// count the vertices
private int verticesCounter = 0;
// hold polygon vertices for the polygon-filling
private Vector<Point> polygon = new Vector<Point>();
private ArrayList<Point> bigVerticesList= new ArrayList<Point>();
static int counter = 0;
/**
* Setting the dimensions of the window
*/
public Dimension getMinimumSize() { return MIN_DIM; }
public Dimension getPreferredSize() { return PREF_DIM; }
/**
* The constructor
*/
DrawingPanel()
{
super();
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
/**
* The drawing itself
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// draw previous polygons
if (this.polygons.size() > 0)
drawPreviousPolygons(g);
int numPoints = points.size();
if (numPoints == 0)
return; // nothing to draw
Point prevPoint = points.get(0);
// draw polygon
Iterator<Point> it = points.iterator();
while (it.hasNext())
{
Point curPoint = it.next();
draw(g, prevPoint, curPoint);
prevPoint = curPoint;
}
// now draw tracking line or complete the polygon
if (polygonDone == true)
{
Point point0 = points.get(0); // grab the starting point (x,y)
// draw the last edge between the starting point & the last point
draw(g, prevPoint, point0);
}
else // polygonDone == false
draw(g, prevPoint, trackPoint);
}
/**
* MouseListener interface
*/
public void mouseClicked(MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
if (polygonDone == false)
{
Point p = new Point(x,y); // new point
vertices.add(p); // add to vertices list
this.verticesCounter++;
}
if (verticesCounter > 1) // create a new edge
{
int verSize = vertices.size(); // grab number of vertices
Point p1 = vertices.get(verSize - 1); // grab the last vertex
Point p2 = vertices.get(verSize - 2); // grab the one before last vertex
// create the current edge between the two points P1 and P2
Edge currentEdge = new Edge(p1,p2);
// add the edge to the edges list
if (polygonDone == false)
this.edges.add(currentEdge);
}
switch (evt.getClickCount())
{
case 1: // single-click
if (polygonDone == true)
{
/**
* remove all the entries from the edges list - preparing for the next polygon
*/
// first add the last edge between the final vertex and the first vertex
Point p1 = null ,p2 = null;
if (!loading)
{
p1 = this.vertices.get(0); // grab 1st vertex
int verSize = vertices.size();
p2 = vertices.get(verSize - 1); // grab last vertex
// create the last edge between the final point & the first point
Edge currentEdge = new Edge(p1,p2);
// add the last edge to the edges list
this.edges.add(currentEdge);
}
if (loading)
loading = false;
// create the new polygon structure with the edges
Polygon poly = new Polygon(this.edges , this.vertices);
// add the polygon to the polygons array
this.polygons.add(poly);
// reset edges ,reset points , reset vertices-counter , reset vertices
greenLightForFilling = true;
verticesCounter = 0;
edges.clear();
points.clear();
vertices.clear();
polygonDone = false;
repaint();
break;
}
points.add(new Point(x, y));
repaint();
break;
case 2: // double-click
polygonDone = true;
points.add(new Point(x, y));
repaint();
break;
default: // ignore anything else
break;
}
}
/**
* MouseMotionListener interface
*/
public void mouseMoved(MouseEvent evt)
{
trackPoint.x = evt.getX();
trackPoint.y = evt.getY();
repaint();
}
/**
* draw points and lines
* @param g
* @param p1
* @param p2
*/
private void draw(Graphics g, Point p1, Point p2)
{
int x1 = p1.x;
int y1 = p1.y;
int x2 = p2.x;
int y2 = p2.y;
// draw the line
g.setColor(Color.green.darker());
g.drawLine(x1 + 3, y1 + 3, x2 + 3, y2 + 3);
// now just paint the edge between those two points
g.setColor(Color.green);
g.fillOval(x1, y1, 8, 8);
g.setColor(Color.black);
g.fillOval(x2, y2, 8, 8);
greenLightForFilling = false;
}
/**
* Run on the arrayList of the Polygons , and draw the previous polygons
* that we already made
* @param g
*/
private void drawPreviousPolygons(Graphics g)
{
int i = 0;
while (i < this.polygons.size())
{
Polygon currentPoly = polygons.get(i); // grab current polygon
int j = 0;
ArrayList<Edge> edges = currentPoly.getPolygonEdges();
// draw the edges of the polygon
while (j < edges.size()) // run on all the edges of the polygon
{
Edge edgeCurrent = edges.get(j); // grab current edge
// drawing the edge
// now draw it - grab the two points that create the edge
int x1 = edgeCurrent.getX1();
int y1 = edgeCurrent.getY1();
int x2 = edgeCurrent.getX2();
int y2 = edgeCurrent.getY2();
// draw the line first so that the points appear on top of the line ends, not below
g.setColor(Color.green.darker());
g.drawLine(x1 + 3, y1 + 3, x2 + 3, y2 + 3);
// now just paint the edge between those two points
g.setColor(Color.green);
g.fillOval(x1, y1, 8, 8);
g.setColor(Color.black);
g.fillOval(x2, y2, 8, 8);
// proceed to next edge
j++;
}
i++; // next polygon
}
}
@Override
public void keyTyped(KeyEvent keyEvent)
{
PolygonFiller polyFiller = new PolygonFiller();
char key = keyEvent.getKeyChar();
switch(key)
{
/**
* Fill the polygons
*/
case FILL_POLYGON:
{
if (greenLightForFilling == true)
{
while (true)
{
fillPolygon(polyFiller);
}
}
break;
} // end FILL_POLYGON
case FILL_POLYGON_LOWERCASE:
{
if (greenLightForFilling == true)
{
fillPolygon(polyFiller);
}
break;
}
/**
* save all polygons in a .scn file
*/
case SAVE_POLYGONS :
{
if (greenLightForFilling == true)
{
saveWorkspace();
}
break;
} // end SAVE_POLYGONS
case SAVE_POLYGONS_LOWERCASE:
{
if (greenLightForFilling == true)
{
saveWorkspace();
}
break;
}
/**
* Delete everything & load all polygons from .scn file
*/
case LOAD_POLYGONS:
{
loadWorkspace();
break;
}
case LOAD_POLYGONS_LOWERCASE:
{
loadWorkspace();
break;
}
default: break;
} // end switch
}
答案 0 :(得分:2)
我不明白为什么不。有几件事需要考虑。
密钥监听器本身在事件分派线程上运行;你不希望在那个线程上有这个循环,因为第二个按键的代码也在那个线程中运行。所以第一个按键需要启动SwingWorker或其他一些线程来运行填充。
我建议多边形填充物要么运行缓慢(做一点填充然后以某种方式暂停,除非填充需要相当长的时间),否则它必须在第二次按键之前完成填充。它可能还需要“冲洗”填充输出,以便缓冲不会消除可见效果。
--- addendeum
我不会创建一个额外的keylistener,我会使用我的那个。我会在那个监听器中有一个布尔开关指示我是否处于“绘图模式”;如果没有,启动绘图循环并更改开关,如果是,则终止绘图循环并更改开关。
我会编写一个类来执行填充循环,并使其可运行。当是时候开始循环时,我会实例化它并在SwingWorker线程中运行它。循环会填充一点,睡一会儿,然后再填充一点直到完成。我对你的填充循环一无所知,所以你必须在这里填写。
你的keylistener可以保持对循环填充对象的引用,并在其上调用一个方法来设置你提到的“end loop”布尔值。该类中的循环将检查填充之间的布尔值。
网上有很多关于如何启动在事件派发线程之外运行的SwingWorker线程的例子;我可以创建一个,但你似乎没有任何具体问题,所以一般案例文档和例子应该服务。如果您尝试并遇到特定问题,请将该问题发回SO。
答案 1 :(得分:0)
您可以通过以下示例:
Component.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
}
});
只需将ActionListener
更改为您需要的听众。但是,因为你已经拥有了一个用于击键的监听器,你可以使用那个......