1

これは、数字を表示するためのスレッドです。

    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("Co-ords: ("+printX+","+printY+")",50,100); 常に が表示されます。つまり、変数がまったく変更されていないことを意味します...なぜですか? そして、どうすればこれを機能させることができますか...? [お願いします] paint() を使うべきではないことはわかっていますが、私は初級者から中級者なので... [編集]そして今、MadProgrammer が言及したので、EventDispatchThread エラーが発生します。[編集 2]を使用することは理解していますが、コード スニペットを使用して取得するにはどうすればよいですか? [編集 3]キーを入力すると、のインスタンスが開始されます。【UPDATE CLASS 2(実物)】(0,0)int printX = 0, printY = 0;


Timer@MadProgrammercow.xcow.y
pKeyListenerThread Sliderthread

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 が機能しない:
ここに画像の説明を入力

4

1 に答える 1

5

UI を更新することを Swing に伝える必要があります。イベントディスパッチスレッドとの契約に違反する可能性があるため、問題が発生する場合があります(イベントディスパッチスレッド以外のスレッドから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またはオーバーライドする理由はありませんpaintJPanela から拡張してをオーバーライドする方がよいでしょうpaintComponent。まず、これにより自動ダブル バッファリングが提供されます。次に、柔軟な展開オプションが提供されます (パネルをJFrameまたはに追加しますJApplet) 。
  • スレッド管理にはさらに作業が必要です。while ループで何もしない (whilegoが false) スレッドを実行すると、これらのスレッドの実行をスケジュールする必要があるため、CPU が浪費されます。Concurrency、特にSynchronizationと locksを読んでください
  • でキー バインディングAPI を使用しますKeyListener。より優れたフォーカス制御 (コンポーネントがアクションをトリガーするためにフォーカスを持っている必要はありません) を備えており、プラグ可能で再利用可能なコードを生成します。
  • イベント リスナーの内部クラスを利用します。本当にしたくないときに、メイン クラスを介してイベント ハンドラー メソッドを公開する必要がなくなります。
  • 実用的な場合は、空の例外ブロックを使用しないでください。 catch (Exception e) {}何か問題が発生した場合、何も教えてくれません。少なくとも、例外をログに記録する必要があります。

あなたの問題として..

、、およびvolatileCoOrdCounter#goを作成することから始めます。Counter#goSlider#goCow

私は逃げてCoOrdCounter#go、コンソールに正しく出力された結果を見ることができました(上記の理由により、私のマシンではグラフィックが機能しませんでした)

于 2012-11-26T03:07:23.287 に答える