0

これは私が理解に近づいたものですが、実際には理解できませんでした。

以下にリストされているコードは、最初のクリックを確認するとすぐに緑色の円を描画することになっています。そうではありません。その後クリックすると、現在クリックされているポイントと前のポイントを結ぶ線が赤で描画されます。コードは最初のクリックで失敗し、その後のすべてのクリックで機能します。最初のクリックが表示されないのはなぜですか? 走る!

私は何を間違っていますか?

コードは、現在の JDE でコンパイルする必要があります。

ティア

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

class Demo extends JFrame
            implements  ActionListener, ListSelectionListener, MouseListener {

  int clkCt = 0, // Count of the number of clicks we've done.
      oldX,      // Penultimate X value
      oldY,      // Penultimate X value
      scrH,      // Height of the drawing canvas.
      scrW;      // Width of the drawing canvas.

  JFrame f;      // Holder for the drawing canvas.

  JLabel ctL;    // Displays the number of clicks we've done.

  JPanel canvas; // The drawing canvas.

  public void demoLines() {

    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    scrH = (int) ((double) d.height * 0.75);
    scrW = (int) ((double) d.width * 0.75);

    oldX = scrH / 2;
    oldY = oldX;

    // Create and set up the window.
    f = new JFrame("Multi Click Demo");
    f.getContentPane().setLayout(null);
    int h = scrH / 5;
    f.setBounds(h, h, scrW, scrH);

    // Create a panel
    canvas = new JPanel();
    canvas.setBackground(Color.black);
    canvas.setForeground(Color.red);
    canvas.setLayout(null);
    canvas.setBounds(0, 0, scrW, scrH);
    canvas.setPreferredSize(new Dimension(scrW, scrH));
    canvas.addMouseListener(this);
    f.getContentPane().add(canvas);

    // Create the exit button.
    JButton exit = new JButton("Exit");
    exit.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        goAway();
      }
    });
    exit.setBackground(Color.black);
    exit.setForeground(Color.red);
    exit.setBounds(0, 0, (scrW / 15), (scrH / 15));
    canvas.add(exit); //*/

    // Create the label for the click count.
    ctL = new JLabel("None Yet");
    ctL.setBackground(Color.black);
    ctL.setForeground(Color.red);
    ctL.setBounds((scrH / 15), (scrH * 13 / 15), (scrW / 15), (scrH / 15));
    canvas.add(ctL);

    f.getContentPane().add(canvas);
    f.setVisible(true);

    Graphics g = canvas.getGraphics();
    if (g == null) {
      System.out.println("No graphics for canvas!");
    } else {
      canvas.revalidate(); // This didn't help.
      paintComponent(g, (oldX + oldX / 2), (oldY + oldY / 2));
    }
  }

  void goAway() {
    f.setVisible(false);
    f.dispose();
  }

  public void mouseClicked(MouseEvent m) {
    // Where was the mouse clicked?
    int clkdBtn = m.getButton(),
        x = m.getX(),
        y = m.getY();
    Graphics g = canvas.getGraphics();
    paintComponent(g, x, y);
  }

  public void paintComponent(Graphics g,
                             int x,
                             int y) {

    // This always runs.
    ctL.setText(clkCt + "");

    if (clkCt == 0) {
      // This never displays!
      g.setColor(Color.green);
      int r = scrH * 4 / 5;
      g.drawOval((scrH / 10), (scrH / 10), r, r);
    }

   g.setColor(Color.red);
   g.drawLine(oldX, oldY, x, y);
   oldX = x;
    oldY = y;
    clkCt++;
  }


  public void actionPerformed(ActionEvent event) { }
  public void valueChanged(ListSelectionEvent event) { }

  public void mouseEntered(MouseEvent e) { }
  public void mouseExited(MouseEvent e) { }
  public void mousePressed(MouseEvent e) { }
  public void mouseReleased(MouseEvent e) { }

  public static void main(String[] s) {

    Demo m = new Demo();
    m.demoLines();
  }
}
4

4 に答える 4

2

そのコードには多くの問題がありました。私はそれらを修正しましたが、すべての変更を文書化することを怠りました。このコードをよく見て、なぜ私が変更を加えたのか (関連するドキュメント/チュートリアルを読んでも) わからない場合は、質問してください。

ここに画像の説明を入力

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;

public class Demo extends JPanel
        implements ListSelectionListener, MouseListener {

    int clkCt = 0, // Count of the number of clicks we've done.
            oldX, // Penultimate X value
            oldY, // Penultimate X value
            scrH = 100, // Height of the drawing canvas.
            scrW = 400;      // Width of the drawing canvas.
    JLabel ctL;    // Displays the number of clicks we've done.
    int x, y;

    public void demoLines() {
        oldX = scrH / 2;
        oldY = oldX;

        // Create a panel
        setBackground(Color.black);
        setForeground(Color.red);
        setPreferredSize(new Dimension(scrW, scrH));

        // Create the label for the click count.
        ctL = new JLabel("None Yet");
        ctL.setBackground(Color.black);
        ctL.setForeground(Color.red);
        ctL.setBounds((scrH / 15), (scrH * 13 / 15), (scrW / 15), (scrH / 15));
        add(ctL);
        addMouseListener(this);
    }

    public void mouseClicked(MouseEvent m) {
        // Where was the mouse clicked?
        x = m.getX();
        y = m.getY();
        repaint();
    }

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    public void paintComponent(Graphics g) {

        // This always runs.
        ctL.setText(clkCt + "");

        if (clkCt == 0) {
            // This never displays!
            g.setColor(Color.green);
            int r = scrH * 4 / 5;
            g.drawOval((scrH / 10), (scrH / 10), r, r);
        }

        g.setColor(Color.red);
        g.drawLine(oldX, oldY, x, y);
        oldX = x;
        oldY = y;
        clkCt++;
    }

    public void valueChanged(ListSelectionEvent event) {
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                Demo m = new Demo();
                m.demoLines();
                JFrame f = new JFrame("Demo");
                f.add(m);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

ノート

  1. フレームまたは他の最上位のコンテナーを拡張しないでください。代わりに、1 つのインスタンスを作成して使用します。
  2. Java GUI は、さまざまな画面解像度やさまざまな PLAF を使用するさまざまなプラットフォームで動作する必要がある場合があります。そのため、コンポーネントを正確に配置するのに役立ちません。堅牢な GUI のコンポーネントを整理するには、代わりに、レイアウト マネージャー、またはそれらの組み合わせを使用し、空白のレイアウト パディングと境界線を使用します。
  3. のような最上位のコンテナでペイントする代わりに、メソッドに & do カスタム ペイントをJFrame追加します。また、レイアウト マネージャーを支援するために、カスタム コンポーネントの適切な優先サイズを返します。JPanelpaintComponent(Graphics)
  4. のカスタム ペイントの場合は、 の代わりにJComponentオーバーライドします。paintComponent(Graphics)paint(Graphics)
于 2013-06-17T06:48:52.640 に答える