-1

私は学生で、プロジェクトの 1 つを作成するのに苦労しています。これは、最終的なプロジェクトが実際にどのようなものになるかのほんの一部ですが、可能な限り区分化しようとしています。

私が抱えている特定の問題は、ユーザーが画面上に複数のボールを作成できるようにするボタン付きのフレームを表示し、それらをクリックしてそれぞれを選択できる Java アプリケーションの作成に関連しています。

私は小さな変更を加えようとしましたが、それらのどれも機能していないので、解決策を見つけるときの自由度を高めるために削除しました。

Simulationクラスのコードは次のとおりです。

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

public class Simulation {

   int noOfBallClicks = 0;

   Simulation() {
      buildTheGUI();
   }
   JFrame frame = new JFrame();
   JFrame frame2 = new JFrame();
   JPanel panal = new JPanel();
   JButton add = new JButton("add a new object");

   public void buildTheGUI() {
      frame.setVisible(true);
      frame.setSize(500, 500);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(panal);
      panal.add(add);
      add.addActionListener(new ButtonClickHandler());
   }

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

   class ButtonClickHandler implements ActionListener {

      public void actionPerformed(ActionEvent e) {
         noOfBallClicks = noOfBallClicks++;
         frame.add(new Ball());
         frame.validate();
      }
   }
}

Ballクラスのコードは次のとおりです。

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

public class Ball extends JPanel {

   private int x;
   private int y;
   private int w;
   private int h;

   Ball() {
      this.x = 200;
      this.y = 200;
      this.w = 100;
      this.h = 100;
   }

   Ball(int a) {
      Random rand = new Random();
      this.w = 100;
      this.h = 100;
      this.x = rand.nextInt(300);
      this.y = rand.nextInt(300);
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.RED);
      g.fillOval(x, y, h, w);
   }
}
4

1 に答える 1

2

私が抱えている特定の問題は、ユーザーが画面上に複数のボールを作成できるようにするボタン付きのフレームを表示し、それらをクリックしてそれぞれを選択できる Java アプリケーションの作成に関連しています。

私は小さな変更を加えようとしましたが、それらのどれも機能していないので、解決策を見つけるときにより多くの自由を与えるようにそれを削除しました.

何が間違っているか、何を達成したいかについては決して言及しません...上記とタイトルに加えて、再描画されたオブジェクトの選択

ただし、指定されたコードにはいくつかの問題があります。

1)JFrameすべてのコンポーネントが追加されるまで表示を設定しないでください(そうしないと、コンテンツが表示されないなどの問題が発生します)

2)オブジェクトの図面に適合する、および/または適切な を使用する をオーバーライドsetSizeして返すを呼び出さないでください。onの代わりに呼び出すことができます。JFramegetPreferredSize()JPanelDimensionGraphicsLayoutManagerpack()setSize(...)JFrame

3) Swing コンポーネントは、ブロックを介してイベント ディスパッチ スレッドで作成および操作する必要があります。詳細については、Swing の同時実行を参照してください。SwingUtilities.invokeLater(Runnable r)

4) 使用するときは、行った変更を反映するために をvalidate()呼び出す必要があります。repaint()

5) また、パネルを追加するデフォルトJFrameのレイアウトを使用しています。デフォルトでBorderLayoutは、(ボタン リスナーを使用して) ボールBorderLayoutが追加さBorderLayout.CENTERれ、呼び出しのたびに古いボール/が別のボールJFrame#add(Component c)に置き換えられます。JPanel

6) そのままの状態でJPanel2Ballが重なり合って上部BallJPanel覆われ、下部が覆われるBall場合... 透明なパネルが必要ですJComponent#setOpaque(false)

7)カスタム ペイントJComponentを行うとき、またはその拡張機能はほとんど使用しません。私はむしろ、描画/表示する必要があるものの仮想表現Objectとして機能する を作成します (個人的な好みかもしれません)。これらのオブジェクトは myで視覚化され、メソッドが呼び出されて、フィールド データに従って自分自身を描画する eachのオブジェクトが渡されます。JPanel paintComponent(..)draw(..)GraphicsJPanelBall

これが私が作った短い例です(上記を念頭に置いて):

ballsはすべて選択されています。つまり、クリックされていますが、赤は選択されていません。

ここに画像の説明を入力

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final DrawPanel drawPanel = new DrawPanel();

        drawPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                super.mouseClicked(me);
                for (Ball b : drawPanel.getBalls()) {//iterate through each ball
                    if (b.getBounds().contains(me.getPoint())) {//get the ball bounds and check if mouse click was within its bounds
                        if (!b.isSelected()) {//check if ball has been clicked on
                            b.setSelected(true);
                        } else {
                            b.setSelected(false);
                        }
                        drawPanel.repaint();//so ball color change will be shown
                    }
                }

            }
        });

        JPanel controlPanel = new JPanel();

        JButton createBallButton = new JButton("Add ball");
        createBallButton.addActionListener(new ActionListener() {
            Random rand = new Random();
            private int counter = 1;

            public void actionPerformed(ActionEvent e) {

                int ballRadius = 10;
                int x = rand.nextInt(drawPanel.getWidth());
                int y = rand.nextInt(drawPanel.getHeight());

                //check that we dont go offscreen by subtarcting its radius unless its x and y are not bigger than radius
                if (y > ballRadius) {
                    y -= ballRadius;
                }
                if (x > ballRadius) {
                    x -= ballRadius;
                }

                drawPanel.addBall(new Ball(x, y, ballRadius, counter));//add ball to panel to be drawn
                counter++;//increase the ball number
            }
        });

        final JTextArea jtf = new JTextArea(5, 10);
        jtf.setEditable(false);
        JButton printSelectedBallButton = new JButton("Print selected balls");
        printSelectedBallButton.addActionListener(new ActionListener() {
            Random rand = new Random();
            private int counter = 1;

            public void actionPerformed(ActionEvent e) {
                jtf.setText("");
                for (Ball b : drawPanel.getBalls()) {
                    if (b.isSelected()) {
                        jtf.append("Selected: " + b.getNumber() + "\n");
                    }
                }

            }
        });

        controlPanel.add(createBallButton);
        controlPanel.add(printSelectedBallButton);
        JScrollPane jsp = new JScrollPane(jtf);
        controlPanel.add(jsp);

        frame.add(drawPanel);
        frame.add(controlPanel, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);

    }

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

class DrawPanel extends JPanel {

    ArrayList<Ball> balls = new ArrayList<>();

    public void addBall(Ball b) {
        balls.add(b);
        repaint();
    }

    public ArrayList<Ball> getBalls() {
        return balls;
    }

    @Override
    protected void paintComponent(Graphics grphcs) {
        super.paintComponent(grphcs);
        Graphics2D g2d = (Graphics2D) grphcs;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for (Ball ball : balls) {
            ball.draw(g2d);
        }
    }

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

class Ball {

    private Color color;
    private int x, y;
    private int radius;
    private final int number;
    private boolean selected;

    Ball(int x, int y, int radius, int counter) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.number = counter;
        selected = false;
        this.color = Color.RED;//default color of unselected ball
    }

    public void draw(Graphics2D g2d) {
        Color prevColor = g2d.getColor();
        g2d.drawString(number + "", x + radius, y + radius);//draw the number of ball
        g2d.setColor(color);
        g2d.fillOval(x, y, radius, radius);
        g2d.setColor(prevColor);
    }

    public Rectangle2D getBounds() {
        return new Rectangle2D.Double(x, y, radius, radius);
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
        if (selected) {
            color = Color.GREEN;
        } else {
            color = Color.RED;
        }
    }

    boolean isSelected() {
        return selected;
    }

    int getNumber() {
        return number;
    }
}
于 2013-02-16T17:25:24.863 に答える