我必须在HoltSoft的Ready to Program中使用Console类。我不应该使用挥杆,所以如果我不能挥杆,请不要这样做。
//imports
import java.awt.*;
import java.awt.event.*;
import hsa.*;
public class DrawLines extends Panel implements MouseListener, MouseMotionListener
{
Console c;
int startX, startY, prevX, prevY; //mouse coordinates
private boolean dragging; //whether or not the mouse is being dragged
MouseEvent e;
public DrawLines ()
{
c = new Console (); //creates console window
addMouseListener (this); //detects press/release
addMouseMotionListener (this);//detects dragging
}
public void mousePressed (MouseEvent e)
{
while (!dragging)
{
try
{
startX = e.getX ();//get the
startY = e.getY ();//original co-ordinates
dragging = true;
}
catch (NullPointerException q) //because I kept getting this error
{
}
}
}
public void mouseDragged (MouseEvent e)
{
while (dragging)
{
try
{
int x = e.getX (); //gets and
int y = e.getY (); //updates
prevX = x; //the mouse
prevY = y; //coordinates
}
catch (NullPointerException q)//because I kept getting this error
{
}
}
}
public void mouseReleased (MouseEvent e)
{
dragging = false; //stopped dragging
}
public void drawTheLine ()
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is
mouseReleased (e);
}
public void mouseMoved (MouseEvent e){}
public void mouseEntered (MouseEvent e){}
public void mouseExited (MouseEvent e){}
public void mouseClicked (MouseEvent e){}
public static void main (String[] args)
{
DrawLines a = new DrawLines ();
a.drawTheLine ();
}
}
我一直在尝试在Console中使用MouseListener和MouseMotionListener。起初,程序一直给我错误,所以我添加了try / catch结构。现在它没有崩溃,但屏幕上没有任何内容。为什么?帮助
如果我不应该使用try / catch来忽略它,我该怎么办?
我不允许在此程序中使用除Console()之外的任何内容。这是课程作业。
答案 0 :(得分:2)
看看这个:
public void drawTheLine ()
{
while (true)
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is
mouseReleased (e);
}
}
您传递的参数“e”为空。它在这里声明:
public class DrawLines extends Panel
implements MouseListener, MouseMotionListener
{
MouseEvent e; // IT IS NEVER SET TO ANYTHING! IT IS NULL!!!
在构造函数的某处,你应该这样做,因此它不再为null:
e = (something);
答案 1 :(得分:2)
Swing是一个事件驱动的系统,是一个单线程系统。
这意味着您的应用程序“等待”事件发生(事件调度线程会照顾您),并且任何阻止EDT的人,如循环,长时间运行的进程或阻塞IO,都会阻止您接收这些事件的通知后,申请无法运行。
所以,如果我们看看这个......
while (true)
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50);
mouseReleased (e);
}
}
它表明......一,你不明白在Swing中如何生成事件,以及两个,EDT实际上是如何工作的。
与某些UI框架不同,您不需要实现事件循环,Swing会对此进行处理。像这样阻止EDT会阻止它处理事件
相反,请删除drawLineMethod
,因为它对您来说绝对没有任何意义,并将您的主要方法替换为类似......
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawLines());
// I prefer pack, but you've not specified a preferred size for your panel...
//frame.pack();
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
现在。我不知道Console
类是什么或者做什么,但是在你的鼠标事件方法中,你需要更新它以便它可以更新它的输出......
更新了示例
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawPane extends JPanel {
private Point center;
private int radius;
public DrawPane() {
MouseAdapter handler = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
center = e.getPoint();
radius = 0;
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
radius = Math.max(width, height);
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (center != null) {
g.setColor(Color.RED);
g.fillOval(center.x - 2, center.y - 2, 4, 4);
g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);
}
}
}
}
我建议你花点时间阅读......
使用纯AWT版本进行更新
正如我所指出的那样OP是使用AWT而不是Swing,为什么,因为他们似乎能够...
public class DrawCircleAWT {
public static void main(String[] args) {
new DrawCircleAWT();
}
public DrawCircleAWT() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Frame frame = new Frame("Testing");
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
frame.add(new DrawPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawPane extends Panel {
private Point center;
private int radius;
public DrawPane() {
MouseAdapter handler = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
center = e.getPoint();
radius = 0;
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
radius = Math.max(width, height);
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (center != null) {
g.setColor(Color.RED);
g.fillOval(center.x - 2, center.y - 2, 4, 4);
g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);
}
}
}
}