Java JFrame上没有显示数字
这是使数字显示的线程:Java JFrame上没有显示数字,java,multithreading,swing,jframe,paint,Java,Multithreading,Swing,Jframe,Paint,这是使数字显示的线程: class CoOrdCounter extends Thread{ public void run(){ try{ while(true){ Thread.sleep(500); printX = cow.x; printY = cow.y; } }catc
class CoOrdCounter extends Thread{
public void run(){
try{
while(true){
Thread.sleep(500);
printX = cow.x;
printY = cow.y;
}
}catch(Exception e){}
}
}
//Of course I also have CoOrdCounter co = new CoOrdCounter; co.start();
然后。。。
g、 drawStringCo ords:+printX+,+printY+,50100;
它总是显示0,0,可能是因为int printX=0,printY=0;。这意味着变量根本没有改变。。。为什么?我应该如何使这项工作。。。?
我知道我不应该用油漆,但我是初学者,所以。。。
[EDIT]现在MadProgrammer提到了它,我确实得到了一个EventDispatchThread错误。
[编辑2]我理解使用计时器,但@MadProgrammer如何使用您的代码片段获得cow.x和cow.y?
[编辑3]如果键入键p,KeyListener将启动线程滑块thread的实例。
[更新第2类真实内容]
[编辑4]@MadProgrammer不工作:
您需要告诉Swing您想要更新UI。在您的情况下,这将出现问题,因为可能会违反与事件调度线程的约定,即您不应该从事件调度线程之外的任何线程更新UI 下面的示例使用了一个简单的javax.swing.Timer,它克服了这个问题
public class PrintNumbers {
public static void main(String[] args) {
new PrintNumbers();
}
public PrintNumbers() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PrintPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PrintPane extends JPanel {
private int printX;
private int printY;
public PrintPane() {
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
printX = (int) Math.round(Math.random() * 1000);
printY = (int) Math.round(Math.random() * 1000);
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth() - 1;
int height = getHeight() - 1;
FontMetrics fm = g.getFontMetrics();
String text = printX + "x" + printY;
int x = (width - fm.stringWidth(text)) / 2;
int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
g.drawString(text, x, y);
}
}
}
更新
来自示例代码
首先,列出您的示例代码错误的地方
没有理由从JFrame扩展或重写绘制方法。您最好从JPanel扩展并覆盖paintComponent。首先,这将为您提供自动双缓冲,其次,它将为您提供灵活的部署选项,将面板添加到JFrame或JApplet
你的线程管理需要更多的工作。在while循环中运行那些在go为false时不执行任何操作的线程是在浪费CPU,因为这些线程仍然需要调度才能运行。具有通读性,尤其是和锁
通过KeyListener使用API。它有更好的焦点控制——组件不必有焦点来触发操作并生成可插入和可重用的代码。
为您使用事件侦听器。当您确实不想公开事件处理程序方法时,它将使您不再需要通过主类公开事件处理程序方法
在实际情况下,应避免使用空异常块。捕获异常e{}不会告诉您任何事情,如果出现问题。至少您应该记录异常。
至于你的问题
首先制作CoOrdCountergo、Countergo、Slidergo和Cow
我没有使用CoOrdCountergo,并且能够正确地看到打印到控制台的结果您的图形在我的机器上无法工作,原因如上所述您需要告诉Swing您想要更新UI。在您的情况下,这将出现问题,因为可能会违反与事件调度线程的约定,即您不应该从事件调度线程之外的任何线程更新UI 下面的示例使用了一个简单的javax.swing.Timer,它克服了这个问题
public class PrintNumbers {
public static void main(String[] args) {
new PrintNumbers();
}
public PrintNumbers() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PrintPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PrintPane extends JPanel {
private int printX;
private int printY;
public PrintPane() {
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
printX = (int) Math.round(Math.random() * 1000);
printY = (int) Math.round(Math.random() * 1000);
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth() - 1;
int height = getHeight() - 1;
FontMetrics fm = g.getFontMetrics();
String text = printX + "x" + printY;
int x = (width - fm.stringWidth(text)) / 2;
int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
g.drawString(text, x, y);
}
}
}
更新
来自示例代码
首先,列出您的示例代码错误的地方
没有理由从JFrame扩展或重写绘制方法。您最好从JPanel扩展并覆盖paintComponent。首先,这将为您提供自动双缓冲,其次,它将为您提供灵活的部署选项,将面板添加到JFrame或JApplet
你的线程管理需要更多的工作。在while循环中运行那些在go为false时不执行任何操作的线程是在浪费CPU,因为这些线程仍然需要调度才能运行。具有通读性,尤其是和锁
通过KeyListener使用API。它有更好的焦点控制——组件不必有焦点来触发操作并生成可插入和可重用的代码。
为您使用事件侦听器。当您确实不想公开事件处理程序方法时,它将使您不再需要通过主类公开事件处理程序方法
在实际情况下,应避免使用空异常块。捕获异常e{}不会告诉您任何事情,如果出现问题。至少您应该记录异常。
至于你的问题
首先制作CoOrdCountergo、Countergo、Slidergo和Cow
我使用CoOrdCountergo侥幸逃脱,并且能够正确地看到打印到控制台上的结果。由于上述原因,图形无法在我的机器上工作。请使用javax.swing.Timer,例如。@trashgood但是我如何使数字显示出来?正如trashgood所述-使用swing计时器。在计时器的ActionListener中,您可以更改printX和printY并调用repaint。不管你做什么,不要叫线程。睡觉。。。在事件线程上。无论你的能力水平如何,都不要在画图或JFrame中绘制。这不是做错事的借口。@hoverfullofeels我不明白。。。如果你不在JFrame中画画,你如何在它上面获得图像呢?对不起,使用javax.swing.Timer,例如。@trashgood,但是我如何让数字显示出来呢
垃圾神状态-使用摆动计时器。在计时器的ActionListener中,您可以更改printX和printY并调用repaint。不管你做什么,不要叫线程。睡觉。。。在事件线程上。无论你的能力水平如何,都不要在画图或JFrame中绘制。这不是做错事的借口。@hoverfullofeels我不明白。。。如果你不在JFrame中画画,那么你如何在上面获得图像呢?很抱歉,既然你提到了它,我确实得到了一个EventDispatchThread错误。javax.swing.Timer为+1。什么是EventDispatchThread错误?@trashgood我再也不明白了?好吧;不允许get更新您的问题以显示您当前的代码。@MADCOOW=null引发错误?我的代码不是调用initGuy来设置cow的位置吗?既然您提到了它,我确实得到了一个EventDispatchThread错误。javax.swing.Timer为+1。什么是EventDispatchThread错误?@trashgood我再也不明白了?好吧;不允许get更新您的问题以显示您当前的代码。@MADCOOW=null引发错误?我的代码不是调用initGuy来设置cow的位置吗?