Java swing窗体程序设计,关于系统托盘的问题。在系统托盘上右键会中断窗体上持续运行的绘图线程。

lunatic19981529 2018-10-12 10:12:15
题目设计要求为:一个小车在斜向下移动的窗体程序。要求窗体最小化,绘图停止,但小车x,y会随时间持续变化,使得窗体显示时,实现了不停止的效果。
目前能实现,不停止的效果,但是一旦在系统托盘图标上右键, 窗体上的小车就不运动了,十分不解。

上面就是运行时的效果

然后在系统托盘那右键,绘图线程就停止了。

下面是代码:

绘图线程的代码:
public class Thread_JPanel extends Container implements Runnable {

public void launchframe() {
setSize(700, 700);
setLayout(null);
setLocation((int) x, (int) y);
setVisible(true);
}

public void paint(Graphics g) {
g.drawImage(car, getx(), gety(), 90, 90, null);
//System.out.println(getx()+" "+gety());
}

public void run() {
while (true) {
repaint();
}
}
}


修改图片x,y的代码:
public class Change_x_y implements Runnable{

public void run() {
while (true) {
System.out.println(x + " " + y);
if (x >= 610 || y >= 610) {
x = y = 0;
} else {
x += (double) speed / 1000 * fresh_time;
y += (double) speed / 1000 * fresh_time;
}
try {
sleep(fresh_time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}


这两个线程,我都设为一个Form类的内部类,在Form类的构造函数中调用:
public Form() {

// 设置主窗体
Setform();

// 检查是否能创建系统托盘。否,则退出程序
Check_SystemTray();

// 如果可以,则创建弹出菜单以及系统托盘的对象,并设定相应的事件
try {
SetTray();
} catch (AWTException e1) {
e1.printStackTrace();
}

// 向窗口添加其他组件,并设置事件
SetOther();

b.launchframe();
thread.start();
form.add(b);
thread1.start();

form.setVisible(true);
}


系统托盘是用settray()方法设置:
public void SetTray() throws AWTException {
PopupMenu pop = new PopupMenu();
MenuItem open = new MenuItem("Show");
MenuItem close = new MenuItem("Exit");
// 创建一个位置跟随控件的弹出菜单,并添加两个菜单选项(“打开”,“退出”)
// jpopupmenu的弹出窗口位置,在JFrame中固定,不能被添加到托盘图标上,所以使用组件popupmenu

pop.add(open);
pop.add(close);
// 给pop菜单添加两个菜单选项

// 创建托盘图标
TrayIcon trayicon = new TrayIcon(car, "Java系统托盘", pop);
// TrayIcon 类的构造方法,分别是图片地址,提示信息,菜单
trayicon.setImageAutoSize(true);

SystemTray systemTray = SystemTray.getSystemTray();
systemTray.add(trayicon);

// 菜单双击选项
trayicon.addMouseListener(new MouseAdapter() {
// 鼠标事件
public void mouseClicked(MouseEvent e) {
// 判断是否双击了鼠标
if (e.getClickCount() == 2) {
form.setVisible(true);
}
}
});

// 菜单选项open 的事件监听器,并执行的操作
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
form.setVisible(true);
}
});

// 菜单选项close 的事件监听器,并执行的操作
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});

}



用过eclipse的debug模式,但是不知道怎么看线程被如何停止。
跪求大佬解决,如果嫌麻烦,也可以教教我怎么用eclipse的调试功能查看线程。
...全文
408 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39936465 2019-07-31
  • 打赏
  • 举报
回复
引用 楼主 lunatic19981529 的回复:
题目设计要求为:一个小车在斜向下移动的窗体程序。要求窗体最小化,绘图停止,但小车x,y会随时间持续变化,使得窗体显示时,实现了不停止的效果。 目前能实现,不停止的效果,但是一旦在系统托盘图标上右键, 窗体上的小车就不运动了,十分不解。 用过eclipse的debug模式,但是不知道怎么看线程被如何停止。 跪求大佬解决,如果嫌麻烦,也可以教教我怎么用eclipse的调试功能查看线程。
为啥要用线程,修改参数,repaint不就好了?
qq_39936465 2019-07-31
  • 打赏
  • 举报
回复

public class Car extends JFrame {
	panel p = new panel();
	static JFrame jf=new JFrame();
	static Image car = Toolkit.getDefaultToolkit().getImage("src/images/car.jpg");
	

	Car() {
		initialize();
	}

	private void initialize() {
		jf.setSize(700, 700);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置窗体关闭模式
		jf.setContentPane(p);
		jf.setVisible(true);// 设置窗体的可见性
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Car c=new Car();
		try {
			c.SetTray();
		} catch (AWTException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		while (true) {
			c.p.Change_x_y();d
                       try {
				new Thread().sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			c.p.repaint();
		}

	}

	public static void SetTray() throws AWTException {
		PopupMenu pop = new PopupMenu();
		MenuItem open = new MenuItem("Show");
		MenuItem close = new MenuItem("Exit");

		pop.add(open);
		pop.add(close);

		TrayIcon trayicon = new TrayIcon(car, "Java系统托盘", pop);
		trayicon.setImageAutoSize(true);

		SystemTray systemTray = SystemTray.getSystemTray();
		systemTray.add(trayicon);

		// 菜单双击选项
		trayicon.addMouseListener(new MouseAdapter() {
			// 鼠标事件
			public void mouseClicked(MouseEvent e) {
				// 判断是否双击了鼠标
				if (e.getClickCount() == 2) {
					jf.setVisible(true);
				}
			}
		});

		// 菜单选项open 的事件监听器,并执行的操作
		open.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jf.setVisible(true);
			}
		});

		// 菜单选项close 的事件监听器,并执行的操作
		close.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

	}

}

class panel extends JPanel {

	Image car = Toolkit.getDefaultToolkit().getImage("src/images/car.jpg");
	private int x, y;

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		super.paint(g);
		Graphics2D gp = (Graphics2D) g;
		gp.drawImage(car, getX(), getY(), 90, 90, this);
	}

	public void Change_x_y() {

		System.out.println(x + " " + y);
		if (x >= 610 || y >= 610) {
			x = y = 0;
		} else {
			x += 5;
			y += 5;
		}

	}
}

qybao 2019-07-30
  • 打赏
  • 举报
回复
确定是线程停止吗?线程停止有什么异常抛出吗?
我怀疑是发生最大最小化后窗体没有刷新
我觉得你这应该用个timer来做,timer刷新panel,最小化时关闭timer,最大化后恢复timer
十八道胡同 2018-10-16
  • 打赏
  • 举报
回复
引用 5 楼 lunatic19981529 的回复:
[quote=引用 4 楼 LCL_data 的回复:]
[quote=引用 3 楼 lunatic19981529 的回复:]
[quote=引用 1 楼 LCL_data 的回复:]
是否可以把 绘图的线程 加日志,然后试下 点击托盘时,观察下这个线程发生了啥

emm不知道怎么操作[/quote]

给你的程序加日志https://blog.csdn.net/rrz634171/article/details/50896369

然后在程序中,输出日志[/quote]
用了一下,让人头大,空缺知识太多了,研究ing……
[/quote]

慢慢来
lunatic19981529 2018-10-15
  • 打赏
  • 举报
回复
引用 4 楼 LCL_data 的回复:
[quote=引用 3 楼 lunatic19981529 的回复:] [quote=引用 1 楼 LCL_data 的回复:] 是否可以把 绘图的线程 加日志,然后试下 点击托盘时,观察下这个线程发生了啥
emm不知道怎么操作[/quote] 给你的程序加日志https://blog.csdn.net/rrz634171/article/details/50896369 然后在程序中,输出日志[/quote] 用了一下,让人头大,空缺知识太多了,研究ing……
十八道胡同 2018-10-14
  • 打赏
  • 举报
回复
引用 3 楼 lunatic19981529 的回复:
[quote=引用 1 楼 LCL_data 的回复:]
是否可以把 绘图的线程 加日志,然后试下 点击托盘时,观察下这个线程发生了啥

emm不知道怎么操作[/quote]

给你的程序加日志https://blog.csdn.net/rrz634171/article/details/50896369

然后在程序中,输出日志
Surrin1999 2018-10-13
  • 打赏
  • 举报
回复
双击调试栏里某个线程 你就切换到某个线程的调试了
十八道胡同 2018-10-13
  • 打赏
  • 举报
回复
是否可以把 绘图的线程 加日志,然后试下 点击托盘时,观察下这个线程发生了啥
lunatic19981529 2018-10-13
  • 打赏
  • 举报
回复
引用 1 楼 LCL_data 的回复:
是否可以把 绘图的线程 加日志,然后试下 点击托盘时,观察下这个线程发生了啥
emm不知道怎么操作

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧