当前位置: 首页 > 知识库问答 >
问题:

Swing:paintComponenet不会绘制到JPanel

暴骏奇
2023-03-14
  1. 我在artPanel JPanel类中实现了MouseListener和MouseMotionListener。看来这解决了我的一些问题。但有几个问题:
  2. 您可以在这里下载我的java文件,以便更容易地识别问题。

我想不通的问题:

  1. “行”按钮无法正确创建行。我一直在玩mouseListener方法,但我无法使其工作。我希望它在单击和拖动鼠标的同时只画一条线。
  2. 其他按钮可以正确绘制形状。然而...当我制作新形状时,这些形状不会停留在面板上。例如,我做一个圆圈。然后我再转一圈,第一个就消失了。我想让他们所有人都时刻留在画布上。

除了这两个,它工作的很好。这里有一张它的样子的照片。

public class Shapes extends JFrame implements ActionListener, WindowListener{

    /**
     * Instance variables are created for the shape's sizes, window height and width.
     */
    int currentX, currentY;
    int previousX, previousY;
    int topLeftX, topLeftY;
    int bottomRightX, bottomRightY;
    int height, width;
    public final int WINDOW_WIDTH = 900;
    public final int WINDOW_HEIGHT = 700;

    /**
     * String shape is created for the type of shape.
     */
    public String shape = "Shape";

    /**
     * Color is set to null, because no color is pressed yet.
     */
    public Color color = null;

    /**
     * MouseReleased is false because no mouse has been released yet.
     */
    public boolean mouseReleased = false;

    private class artPanel extends JPanel implements MouseListener, MouseMotionListener{

        public artPanel(){
         /**
         * Listeners are added to the GUI (for the mouse clicks, and for the window exit).
         */
        addMouseListener(this);
        addMouseMotionListener(this);
        }

        /**
         * mouseDragged method is overridden.
         * Previous X and Y variables are set to the current X and Y values.
         * Then, the current X and Y values are set to the position where the mouse is dragged.
         * The width and height is then calculated, while using the absolute value.
         * Repaint method is invoked.
         */
        @Override
        public void mouseDragged(MouseEvent e) {

            previousX = currentX;
            previousY = currentY;

            currentX = bottomRightX = e.getX();
            currentY = bottomRightY = e.getY();

            width = Math.abs(topLeftX - bottomRightX);
            height = Math.abs(topLeftY - bottomRightY);

            repaint();
        }

        /**
         * mouseClicked method is overridden.
         */
        @Override
        public void mouseClicked(MouseEvent e) {

        }

        /**
         * mouseEntered method is overridden.
         */
        @Override
        public void mouseEntered(MouseEvent e) {

        }

        /**
         * mouseExited method is overridden.
         */
        @Override
        public void mouseExited(MouseEvent e) {

        }

        /**
         * mousePressed method is overridden, current X and Y variables are set to the position where the mouse is pressed.
         */
        @Override
        public void mousePressed(MouseEvent e) {
            topLeftX = currentX = e.getX();
            topLeftY = currentY = e.getY();

        }

        /**
         * mouseReleased method is overridden.
         * Bottom Right X and Y variables are set to the position where the mouse is pressed.
         * Width and height is set using the absolute value of the difference.
         * Repaint method is invoked.
         */
        @Override
        public void mouseReleased(MouseEvent e) {
            bottomRightX = e.getX();
            bottomRightY = e.getY();

            width = Math.abs(topLeftX - bottomRightX);
            height = Math.abs(topLeftY - bottomRightY);

            mouseReleased = true;

            repaint();
        }




        /**
         * mouseMoved method is overridden.
         */
        @Override
        public void mouseMoved(MouseEvent e) {

        }

        /**
         * Paint method is created with parameter g for implementing graphics.
         */
        public void paintComponent(Graphics g){
            super.paintComponent(g);

            /**
             * If the color is not null (has been changed), then the color is set to the user's c
             */
            if(color != null)
                g.setColor(color);

            /**
             * If the shape is a line (line button clicked), then the line is drawn.
             */
            if(shape.equals("Line")){
                g.drawLine(previousX, previousY, currentX, currentY);
            }

            /**
             * If the shape is a circle (circle button clicked), then the circle is drawn.
             * The mouseReleased is set to false so that it draws it when it is dragged.
             */
            else if(shape.equals("Circle") && mouseReleased){
                g.drawOval(topLeftX, topLeftY, width, height);
                mouseReleased = false;
            }

            /**
             * If the shape is a Rectangle (rectangle button clicked), then the rectangle is drawn.
             * The mouseReleased is set to false so that it draws it when it is dragged.
             */
            else if(shape.equals("Rectangle") && mouseReleased){
                g.drawRect(topLeftX, topLeftY, width, height);
                mouseReleased = false;
            }

            /**
             * If the shape is an Arc (arc button clicked), then the arc is drawn.
             * The mouseReleased is set to false so that it draws it when it is dragged.
             */
            else if(shape.equals("Arc") && mouseReleased){
                g.drawArc(topLeftX, topLeftY, width, height, 0, 90);
                mouseReleased = false;
            }
        }

    }


    /**
     * Constructor for creating the GUI
     */
    public Shapes(){
        /**
         * Super is invoked, title is set
         */
        super("Draw Geometric Shapes");
        /**
         * Size is set using the instance variables, does nothing on close as default.
         */
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        /**
         * Layout is set to borderlayout for the frame.
         */
        setLayout(new BorderLayout());

        /**
         * A panel for the buttons is created, uses a flowlayout.
         */
        JPanel buttons = new JPanel();
        buttons.setLayout(new FlowLayout());

        /**
         * Button for the color is created.
         */
        JButton colorChooser = new JButton("Color");
        colorChooser.addActionListener(this);
        buttons.add(colorChooser);

        /**
         * Button for making a line is created.
         */
        JButton line = new JButton("Line");
        line.addActionListener(this);
        buttons.add(line);

        /**
         * Button for making a circle is created.
         */
        JButton circle = new JButton("Circle");
        circle.addActionListener(this);
        buttons.add(circle);

        /**
         * Button for making a rectangle is created.
         */
        JButton rect = new JButton("Rectangle");
        rect.addActionListener(this);
        buttons.add(rect);

        /**
         * Button for making an arc is created
         */
        JButton arc = new JButton("Arc");
        arc.addActionListener(this);
        buttons.add(arc);

        /**
         * Buttons panel is added to the south part of the border layout (bottom of the frame).
         */
        add(buttons, BorderLayout.SOUTH);

        addWindowListener(this);

        artPanel p = new artPanel();
        p.setLayout(new FlowLayout());
        p.setBackground(Color.WHITE);

        add(p);
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        /**
         * New object of type Shapes is created and set to visible.
         */
        Shapes draw_shapes = new Shapes();
        draw_shapes.setVisible(true);
    }


    /**
     * actionPerformed is overridden and each button is set to a shape type
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        /**
         *  If the button "Color" is clicked, then the color chooser dialog appears.
         */
        if(e.getActionCommand().equals("Color")){
            color = JColorChooser.showDialog(this, "Color Chooser", color);
        }

        /**
         *  If the button "Line" is clicked, then the shape is set to Line.
         */
        else if(e.getActionCommand().equals("Line")){
            if(shape.equalsIgnoreCase("Line")){
                shape = "Line";
            }
            else shape = "Line";
        }

        /**
         *  If the button "Circle" is clicked, then the shape is set to circle.
         */
        else if(e.getActionCommand().equals("Circle")){
            if(shape.equalsIgnoreCase("Circle")){
                shape = "Circle";
            }
            else shape = "Circle";
        }

        /**
         *  If the button "Rectangle" is clicked, then the shape is set to rectangle.
         */
        else if(e.getActionCommand().equals("Rectangle")){
            if(shape.equalsIgnoreCase("Rectangle")){
                shape = "Rectangle";
            }
            else shape = "Rectangle";
        }

        /**
         *  If the button "Arc" is clicked, then the shape is set to Arc.
         */
        else if(e.getActionCommand().equals("Arc")){
            if(shape.equalsIgnoreCase("Arc")){
                shape = "Arc";
            }
            else shape = "Arc";
        }
    }

    }
}

我删除了其余的,因为它们是windowlistener方法。

共有1个答案

徐昕
2023-03-14
add(buttons, BorderLayout.SOUTH);

Panel p = new Panel();
add(p);

JPanel whitePanel = new JPanel();
whitePanel.setBackground(Color.WHITE);
add(whitePanel);

您的代码意味着您使用框架的内容面板的默认布局管理器,它是borderlayout

您尝试将“p”和“whitePanel”添加到BorderLayoutCenter(当您没有指定约束时,这是默认值)。只能将一个组件添加到BorderLayout的给定位置。只有最后一个添加的面板被绘制,这是你的白色面板,所以你永远不会看到你的面板的自定义绘制。

我不知道您确切的布局需求是什么,所以我不能建议一个解决方案,除了使用不同的布局管理器或使用不同布局管理器的嵌套面板。

你不应该覆盖画框上的油漆。您确实应该重写JPanel的paintComponent()。阅读Swing教程中关于自定义绘画的部分,了解更多信息和工作示例。

编辑:

然后我再转一圈,第一个就消失了。我想让他们一直都留在画布上。

 类似资料:
  • 我有一个扩展JComponent的自定义组件,它覆盖了方法paintComponent(Graphics g),但当我尝试将其添加到我的JPanel时,它就是不起作用,什么都没有绘制。这是我的代码:

  • 问题内容: 我尝试了一些用Java绘图的源代码,它们工作正常,但是当我尝试制作自己的源代码时,我无法使用该方法!我再次查看了自己拥有的代码,并查看了Oracle页面中的一些教程,但是我似乎无法得知为什么它不起作用。有人可以检查一下,告诉我这里有什么问题吗? 主要方法:公共类主要 板: car.java: 没有错误,它向我显示了正确的图像宽度,计时器也触发,也可以正常工作,但是图像无法绘制!该方法只

  • 将显示JFrame和JPanel,但paintComponent方法不在JPanel上绘制。我只看到我添加的JLabel、JTextField和JButton,而没有看到应该在JPanel上绘制的内容。

  • 我想重新绘制我的屏幕。到目前为止,它所做的只是在第一个屏幕上的头部应该在的地方显示一个点。这很好,但是我在代码中写了我想每秒将头部向下移动10个像素。我正在打印头部应该在的位置,在命令提示符中它显示y值确实在增加。但是在我的屏幕上,头部没有移动。 我尝试过使用revalidate方法,尝试扩展canvas类而不是jframe,我尝试过只为paint方法使用不同的类,我尝试过用paintCompon

  • 问题内容: 这是我的问题…: 在我的活动中,我有一个和一个。我希望Button仅在显示某个可绘制对象时才执行操作。是的,这意味着该代码正在各种可绘制对象之间进行动画处理,从而使其不会中断我想要完成的工作。 没用 并且我将其范围缩小到“ if(vari(drawabledrawable == acertaindrawable)”行的错误。尽管Eclipse并没有公然报告两个可绘制对象是否相同的And

  • 问题内容: 我正在做一项家庭作业,我应该制作一个程序,使您可以绘制自定义形状和线条,并在屏幕上移动它们。 最初,我使用公共空隙进行绘画,但是当我调用重绘时,形状会闪烁。 因此,我切换到。但是,当我尝试绘制形状时,没有任何显示。我相信这是因为它不在顶部绘画。 框架在3行中有3个面板。 我想绘制的面板自然是Draw Box面板。 这是我目前拥有的代码: 问题答案: 您的Main类扩展了JPanel,具