4

注: 私のコードの問題は、四角形とすべてをクリアするメソッドを作成したことですが、唯一間違っていたのは、go() メソッド内で DrawPanel クラスの myDraw オブジェクトをインスタンス化することでした。そのため、Stop を使用して DrawPanel を再度インスタンス化し、まったく新しいオブジェクトを作成する必要がありました。そのため、四角形が追加されていたものとは異なる DrawPanel オブジェクトで clearRects メソッドを呼び出すことになりました。とにかく、MadProgrammer によるコードの提案に従うことにしました。彼のコードはまさに Java: A Beginner's Guide が教えているとおりであり、はるかに簡潔だったからです。

さて、私は今朝から StackOverflow を実行しており、コードの多くの問題を修正することができましたが、ArrayLists に関するこの問題にはまだ悩まされています。

私が意図したことをしていないように見える次のコードがあります。今、私はどこかで間違いを犯していることに気づきましたが、それを修正する方法が本当にわかりません.

設定方法は、停止ボタンを押すと ArrayList がクリアされ、いわば空白の JPanel になるようにすることです。ここにコード スニペットを示します。必要に応じてプログラム全体を投稿できますが、ここにスニペットのみを貼り付けているのは、私が非常に単純でばかげた間違いを犯していると想定しているためです。

class DrawPanel extends JPanel {
    ArrayList<MyRectangle> rects = new ArrayList<>();
    Random rand = new Random();

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        addRect();

        for(MyRectangle r : rects) {
        g.setColor(r.getColor());
        g.fillRect(r.x, r.y, r.width, r.height);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500,500);
    }

    public ArrayList<MyRectangle> addRect() {
        int ht = rand.nextInt(getHeight());
    int wd = rand.nextInt(getWidth());

    int x = rand.nextInt(getWidth() - wd);
    int y = rand.nextInt(getHeight() - ht);

    int r = rand.nextInt(256);
    int g = rand.nextInt(256);
    int b = rand.nextInt(256);

    rects.add(new MyRectangle(x, y, wd, ht, new Color(r, b, g)));
    System.out.println(rects.size());
    return rects;
}

    public void clearEvent(ActionEvent e) {
        System.out.println(rects.size());
        rects.clear();
        frame.repaint();
        System.out.println("I was called");
    }
}

ボタンが actionPerformed メソッドでそれを呼び出す部分は次のとおりです。

class StopListener implements ActionListener {
    DrawPanel draw = new DrawPanel();
    public void actionPerformed(ActionEvent e) {
        timer.stop();
        draw.clearEvent(e);
    }
    }

編集:私のclearEventメソッドが参照するarraylistオブジェクトは、addRect()が追加するものと同じではないことを理解しています。私が求めているのは、JButton を使用してクリーンアップできるように「接続」する方法だと思います。

編集:完全なプログラムは次のとおりです。

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

public class TwoButtonsRandomRec {

    JFrame frame;
    Timer timer;

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            TwoButtonsRandomRec test = new TwoButtonsRandomRec();
            test.go();
        }
        });
    }

    public void go() {
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton startButton = new JButton("Start");
    startButton.addActionListener(new StartListener());
    JButton stopButton = new JButton("Stop");
    stopButton.addActionListener(new StopListener());

    final DrawPanel myDraw = new DrawPanel();

    timer = new Timer(50, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            myDraw.repaint();
        }
        });

    frame.add(startButton, BorderLayout.NORTH);
    frame.add(stopButton, BorderLayout.SOUTH);
    frame.add(myDraw, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
    }

    class StartListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        timer.start();
    }
    }

    class StopListener implements ActionListener {
    DrawPanel draw = new DrawPanel();
    public void actionPerformed(ActionEvent e) {
        timer.stop();
        draw.clearEvent(e);
    }
    }

    class DrawPanel extends JPanel {
    ArrayList<MyRectangle> rects = new ArrayList<>();
    Random rand = new Random();

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        addRect();

        for(MyRectangle r : rects) {
        g.setColor(r.getColor());
        g.fillRect(r.x, r.y, r.width, r.height);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500,500);
    }

    public ArrayList<MyRectangle> addRect() {
        int ht = rand.nextInt(getHeight());
        int wd = rand.nextInt(getWidth());

        int x = rand.nextInt(getWidth() - wd);
        int y = rand.nextInt(getHeight() - ht);

        int r = rand.nextInt(256);
        int g = rand.nextInt(256);
        int b = rand.nextInt(256);

        rects.add(new MyRectangle(x, y, wd, ht, new Color(r, b, g)));
        System.out.println(rects.size());
        return rects;
    }

    public void clearEvent(ActionEvent e) {
        System.out.println(rects.size());
        rects.clear();
        repaint();
        System.out.println("I was called");
    }
    }
}

class MyRectangle extends Rectangle {
    Color color;
    public MyRectangle(int x, int y, int w, int h, Color c) {
    super(x, y, w, h);
    this.color = c;
    }

    public Color getColor() {
    return color;
    }
}

誰かが興味を持っている場合に備えて、ここで尋ねた以前の関連する質問を次に示します。

JFrame の奇妙な動作

4

1 に答える 1

3

差し迫った問題が 2 つあります。

addRect1 つ目は、メソッド内で呼び出すことです。paintComponentつまり、 をクリアした後でもList、次の再描画時に新しい四角形が追加されます。

第二に、フレーム全体ではなく描画パネルのみを更新したいので、を使用repaintするDrawPanel代わりに を呼び出します。frame.repaint()

public class BadPaint05 {

    public static void main(String[] args) {
        new BadPaint05();
    }

    public BadPaint05() {
        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 MasterPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MasterPane extends JPanel {

        private DrawPanel drawPane;
        private Timer timer;

        public MasterPane() {
            setLayout(new BorderLayout());
            drawPane = new DrawPanel();

            add(drawPane);

            JButton stop = new JButton("Stop");
            stop.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    drawPane.clearEvent(e);
                    timer.stop();
                }
            });

            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    drawPane.addRect();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();

            add(stop, BorderLayout.SOUTH);

        }

    }

    class DrawPanel extends JPanel {

        ArrayList<MyRectangle> rects = new ArrayList<>();
        Random rand = new Random();

        @Override
        public void paintComponent(Graphics g) {

            super.paintComponent(g);

//            addRect();

            for (MyRectangle r : rects) {
                g.setColor(r.getColor());
                g.fillRect(r.x, r.y, r.width, r.height);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

        public ArrayList<MyRectangle> addRect() {
            int ht = rand.nextInt(getHeight());
            int wd = rand.nextInt(getWidth());

            int x = rand.nextInt(getWidth() - wd);
            int y = rand.nextInt(getHeight() - ht);

            int r = rand.nextInt(256);
            int g = rand.nextInt(256);
            int b = rand.nextInt(256);

            rects.add(new MyRectangle(x, y, wd, ht, new Color(r, b, g)));
            System.out.println(rects.size());
            repaint();
            return rects;
        }

        public void clearEvent(ActionEvent e) {
            System.out.println(rects.size());
            rects.clear();
//            frame.repaint();
            repaint();
            System.out.println("I was called");
        }
    }

    public class MyRectangle {

        private int x, y, width, height;
        private Color color;

        private MyRectangle(int x, int y, int wd, int ht, Color color) {
            this.x = x;
            this.y = y;
            this.width = wd;
            this.height = ht;
            this.color = color;
        }

        public Color getColor() {
            return color;
        }

    }
}
于 2012-12-12T00:10:16.590 に答える