Draw on one side of a JPanel

后端 未结 1 1876
一整个雨季
一整个雨季 2020-12-22 08:02

I want to program an application that lets you draw circles with a mouse click on the left side of a JFrame, and all the points are getting \"mirrored\" to the

相关标签:
1条回答
  • 2020-12-22 08:51

    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

    0 讨论(0)
提交回复
热议问题