这是显示数字的线程:
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.drawString("坐标:("+printX+","+printY+")",50,100);
它总是显示(0,0)
,可能是因为int printX = 0, printY = 0;
。所以这意味着变量根本没有改变......为什么?我应该如何使这项工作...?
[请]我知道我不应该使用 paint() 但我是初级中级所以...
[编辑] 现在 MadProgrammer 提到了它,我确实收到了 EventDispatchThread 错误。
[EDIT 2] 我了解使用 Timer
但是 @MadProgrammer
我如何获得 cow.x
和 cow.y
使用您的代码片段?
[EDIT 3] 如果您键入键 p
KeyListener
将启动 Thread
的实例 slider
,线程
。
[UPDATE CLASS 2(真实的东西)]
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.io.*;
import java.net.*;
@SuppressWarnings({"serial","rawtypes","unchecked"})
public class CowbenderI extends JFrame implements MouseListener, KeyListener{
CoOrdCounter co;
Counter cnt;
Icon icon = new ImageIcon("resources/img/cow.png");
int focusX = 0, focusY = 0, counter = 0;
ArrayList lines = new ArrayList();
Point2D.Double start;
final Color BROWN = new Color(156,93,82);
Slider thread;
Rectangle cow = null;
boolean drawGuy = false, useFinal = false, checkedForWin = false, alive = true;
int finalTime = 0;
int printX = 0, printY = 0;
public CowbenderI(){
super("Cowbender I - \"Slope Run\"");
setSize(700,700);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseListener(this);
addKeyListener(this);
cnt = new Counter();
cnt.go = false;
cnt.start();
co = new CoOrdCounter();
co.go = false;
co.start();
}
public void paint(Graphics g){
super.paint(g);
try{
g.setColor(Color.WHITE);
g.fillRect(-2000, -2000, 5000, 5000);
URL url = this.getClass().getResource("resources/img/world/slope.png");
Image bckgrnd = Toolkit.getDefaultToolkit().getImage(url);
g.drawImage(bckgrnd,0,0,this);
}catch(Exception e){}
g.setColor(BROWN);
for(int i = 0; i < lines.size(); i++){
Line2D.Double temp = (Line2D.Double) lines.get(i);
int x1 = Integer.parseInt(""+Math.round(temp.getX1()));
int x2 = Integer.parseInt(""+Math.round(temp.getX2()));
int y1 = Integer.parseInt(""+Math.round(temp.getY1()));
int y2 = Integer.parseInt(""+Math.round(temp.getY2()));
g.drawLine(x1-focusX,y1-focusY,x2-focusX,y2-focusY);
}
if(drawGuy){
try{
g.setFont(new Font("Arial",Font.BOLD,16));
if(useFinal == false) g.drawString("Current Time: "+counter,50,50);
else g.drawString("Current Time: "+finalTime,50,50);
g.drawString("Co-ords: ("+printX+","+printY+")",50,100);
if(alive == true){
URL url = this.getClass().getResource("resources/img/world/char.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
g.drawImage(image, cow.x-focusX, cow.y-focusY, this);
}
else{
URL url = this.getClass().getResource("resources/img/world/deadchar.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
g.drawImage(image, cow.x-focusX, cow.y-focusY, this);
if(checkedForWin == false){
finalTime = counter;
useFinal = true;
checkWin();
}
}
} catch(Exception exc){}
focusX = cow.x-100;
focusY = cow.y-100;
}
}
public void checkWin(){
if(finalTime >= 45){
JOptionPane.showMessageDialog(null,"You won!\nThe farmer got tired and ran back!","Cowbender I - The Slope",JOptionPane.INFORMATION_MESSAGE,icon);
System.exit(0);
}
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){
start = new Point2D.Double(e.getX()+focusX,e.getY()+focusY);
}
public void mouseReleased(MouseEvent e){
Point2D.Double end = new Point2D.Double(e.getX()+focusX,e.getY()+focusY);
lines.add(new Line2D.Double(start,end));
repaint();
}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){
if(e.getKeyChar()=='w'||e.getKeyChar()=='W'){
focusY-=100;
repaint();
}
if(e.getKeyChar()=='a'||e.getKeyChar()=='A'){
focusX-=100;
repaint();
}
if(e.getKeyChar()=='s'||e.getKeyChar()=='S'){
focusY+=100;
repaint();
}
if(e.getKeyChar()=='d'||e.getKeyChar()=='D'){
focusX+=100;
repaint();
}
if(e.getKeyChar()=='p'||e.getKeyChar()=='P'){
alive = true;
counter = 0;
cnt.go = true;
co.go = true;
useFinal = false;
thread = new Slider();
thread.start();
thread.action(true);
}
if(e.getKeyChar()=='z'||e.getKeyChar()=='Z'){
lines.remove(lines.size()-1);
repaint();
}
if(e.getKeyChar()=='x'||e.getKeyChar()=='X'){
int response = milkSwing.confirmBox(null, "Do you really want to remove all of your summoned earth?", "Cowbender - The Slope", JOptionPane.YES_NO_OPTION);
if(response == JOptionPane.YES_OPTION) lines.clear();
repaint();
}
if(e.getKeyChar()=='q'||e.getKeyChar()=='Q'){
System.exit(0);
}
}
class CoOrdCounter extends Thread{
public boolean go = true;
public void run(){
try{
while(true){
if(go){
Thread.sleep(500);
printX = cow.x;
printY = cow.y;
repaint();
}
}
}catch(Exception e){}
}
}
class Counter extends Thread{
public boolean go = true;
public void run(){
try{
while(true){
if(go){
Thread.sleep(1000);
counter++;
}
}
} catch(Exception e){}
}
}
private class Slider extends Thread{
double velocity, gravity;
boolean go = false;
public void run(){
if(go){
initGuy();
velocity = 0;
gravity = 1;
}
while(go){
try{
Line2D.Double lineTaken = null;
boolean onLine = false;
int firstOnLine = -1;
for(int i = lines.size()-1; i>=0; i--){
Line2D.Double temp = (Line2D.Double) lines.get(i);
if(temp.intersects(cow.x,cow.y,50,50)){
lineTaken = temp;
onLine = true;
if(firstOnLine!=i){
firstOnLine = i;
gravity = 0;
}
break;
}
}
if(onLine){
double grav = (lineTaken.y2-lineTaken.y1)/50;
double vlct = (lineTaken.x2-lineTaken.x1)/100;
if(velocity<5)velocity+=vlct;
if(gravity<2.5)gravity+=grav;
}
else{
gravity+=.2;
}
cow.x+=velocity;
cow.y+=gravity;
if(cow.x > 10000) alive = false;
Thread.sleep(75);
repaint();
}catch(Exception e){break;}
}
}
public void action(boolean b){
go = b;
}
public void initGuy(){
Line2D.Double firstLine = (Line2D.Double) lines.get(0);
int x = Integer.parseInt(""+Math.round(firstLine.x1));
int y = Integer.parseInt(""+Math.round(firstLine.y1));
cow = new Rectangle(x+90,y-60,50,50);
drawGuy = true;
}
}
/**
* @param args
*/
public static void main(String[] args) {
CowbenderI g = new CowbenderI();
}
}<br />
[编辑 4] @MadProgrammer 不工作:
最佳答案
您需要告诉 Swing 您想要更新 UI。在你的情况下,这会出现问题,因为它可能违反与事件调度线程的契约(Contract)(你永远不应该从事件调度线程以外的任何线程更新 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
扩展或覆盖paint
方法。您最好从JPanel
扩展并覆盖paintComponent
。首先,这将为您提供自动双缓冲,其次,它将为您提供灵活的部署选项(将面板添加到JFrame
或JApplet
) - 您的线程管理需要更多工作。在 while 循环中运行什么都不做的线程(当
go
为 false 时)正在浪费 CPU,因为这些线程仍然需要安排运行。通读Concurrency , 特别是 Synchronization和锁 - 使用key bindings API 通过
KeyListener
。它具有更好的焦点控制(组件不必拥有焦点即可触发操作)并生成可插入和可重用的代码。 - 利用inner classes为你的事件听众。当您确实不想这样做时,它将使您无需通过主类公开事件处理程序方法
- 您应该尽可能避免使用空异常 block 。如果出现问题,
catch (Exception e) {}
不会告诉您任何信息。至少您应该记录异常。
关于你的问题..
开始制作 CoOrdCounter#go
、Counter#go
、Slider#go
和 Cow
volatile .
我逃脱了 CoOrdCounter#go
并能够看到正确打印到控制台的结果(由于上述原因,您的图形无法在我的机器上运行)
关于java - 数字未显示在 JFrame 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13558034/