Draw on one side of a JPanel

你。 提交于 2019-11-29 18:00:42
Frakcool

Let's go through your problems:

The first problem I encountered was that when I try to implement this draw-mechanic in my frame, no circles appear.

This is because you forgot to call JPanel#revalidate() and JPanel#repaint() whenever you click somewhere in the DrawCircle class.

So, you could change your mousePressed() method to:

@Override
public void mousePressed(MouseEvent e) {
    p.add(new Point(e.getX(), e.getY()));
    revalidate();
    repaint();
}

Note that I also changed the e.getX() and e.getY() calls, because they were on the wrong places (unless you want them that way).

That will make your circles to appear, but, your DrawCircle is really thin (I changed the height of your JFrame to 200 for this image, otherwise it would be really tall):

The red part is your DrawCircle panel.

To fix this you need to override its getPreferredSize() method:

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

That will make your JPanel to return half the size, width and height were passed as parameters to the constructor, and your class DrawCircle should now look like this:

class DrawCircle extends JPanel implements MouseListener {
    ArrayList<Point> p = new ArrayList<Point>();

    int width = 0;
    int height = 0;

    public DrawCircle(int width, int height) {
        this.width = width;
        this.height = height;
        addMouseListener(this);
    }

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

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Point point : p) {
            g.fillOval(point.x, point.y, 30, 30);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mousePressed(MouseEvent e) {
        p.add(new Point(e.getX(), e.getY()));
        revalidate();
        repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }
}

And the output would be something like this:

It works (on the whole frame) when I use container.add(new DrawCircle)

That's because by default BorderLayout places by default the elements on the CENTER region, and if you have nothing else in the rest of orientations (NORTH, SOUTH, etc) it will take the whole space.

Now let's continue with how to solve your problem:

I also made some changes to the Application class (which in my case I renamed to CustomPaintingInHalfFrame):

These changes were:

  • Create final constants for the WIDTH and HEIGHT attributes.
  • Removal of unnecessary JPanel with BorderLayout layout, as JFrame already has this layout by default, I simply added our DrawClass to it.
  • Drawing of a border for the DrawCircle panel (as you don't want a division between both (left and right) parts of your JFrame as stated in your previous question you can simply remove it (I recommend you to leave it there while you're testing so you know where left panel ends and right panel starts.
  • Passing WIDTH / 2 and HEIGHT as parameters for DrawCircle constructor, so it can return the correct Dimension.

So, our class should now look like this:

public class CustomPaintingInHalfFrame {
    int x, y;
    public static final int WIDTH = 500;
    public static final int HEIGHT = 200;

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

    @SuppressWarnings("serial")
    public void gui() {
        JFrame jframe = new JFrame("Title");

        DrawCircle dc = new DrawCircle(WIDTH / 2, HEIGHT);

        dc.setBorder(BorderFactory.createLineBorder(Color.RED));

        jframe.add(dc, BorderLayout.WEST);

        jframe.setSize(WIDTH, HEIGHT);
        jframe.setVisible(true);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setResizable(false);

    }
}

Additional Tips

  1. I recommend you to rename your DrawCircle to Circle or something like that. As a convention, Classes names should be nouns

  2. Rename gui() method to createGui() for example because, as Classes names, method names should be verbs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!