【问题标题】:repaint() not invoking paintComponent()?repaint() 没有调用paintComponent()?
【发布时间】:2013-11-25 23:22:52
【问题描述】:

您好,我正在尝试解决以下问题:编写一个程序,提示用户使用文本字段输入中心点和半径的 x 和 y 位置。当用户单击“绘制”按钮时,在组件中绘制一个具有该中心和半径的圆。我看不出我的代码有什么问题,但有些原因是因为 repaint() 似乎没有调用paintComponent(),因为消息将更改为 TESTING 1 但不是 TESTING 2 并且不进行绘图。 我的代码:

import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.applet.*;
import java.awt.geom.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class q3{

    public static class cgPanel extends JPanel{
        private static double x;
        private static double y;
        private static double r;
        private static JTextField xField;
        private static JTextField yField;
        private static JTextField rField;
        private static JButton draw;
        private static JLabel message;
//This is all just Layout work.
        public cgPanel(){
            setLayout(new BorderLayout());
            JPanel drawPanel = new JPanel();
            drawPanel.setBackground(Color.WHITE);
            add(drawPanel, BorderLayout.CENTER);
            message = new JLabel("");
            JPanel sub1ForSub1 = new JPanel();
            sub1ForSub1.add(message);
            JLabel coordinates = new JLabel("Coordinates:");
            JPanel sub2ForSub1 = new JPanel();
            sub2ForSub1.add(coordinates);
            JPanel subPanel1 = new JPanel();
            subPanel1.setLayout(new GridLayout(2, 1));
            subPanel1.add(sub1ForSub1);
            subPanel1.add(sub2ForSub1);
            JLabel xLabel = new JLabel("x:");
            xField = new JTextField(4);
            JLabel yLabel = new JLabel(" y:");
            yField = new JTextField(4);
            JLabel rLabel = new JLabel(" Radius:");
            rField = new JTextField(4);
            JPanel subPanel2 = new JPanel();
            subPanel2.add(xLabel);
            subPanel2.add(xField);
            subPanel2.add(yLabel);
            subPanel2.add(yField);
            subPanel2.add(rLabel);
            subPanel2.add(rField);
            draw = new JButton("Draw");
            ActionListener bL = new ButtonListener();
            draw.addActionListener(bL);
            JPanel subPanel3 = new JPanel();
            subPanel3.add(draw);
            JPanel Panel = new JPanel();
            Panel.setLayout(new BorderLayout());
            Panel.add(subPanel1, BorderLayout.NORTH);
            Panel.add(subPanel2, BorderLayout.CENTER);
            Panel.add(subPanel3, BorderLayout.SOUTH);
            add(Panel, BorderLayout.SOUTH);
            setVisible(true);
        }
        static class ButtonListener extends JComponent implements ActionListener{
            public void actionPerformed(ActionEvent e){
                try{
                    String xString = xField.getText();
                    String yString = yField.getText();
                    String rString = rField.getText();
                    message.setText("TESTING 1");
                    x = Double.parseDouble(xString);
                    y = Double.parseDouble(yString);
                    r = Double.parseDouble(rString);
                    repaint();
                }
                catch (NumberFormatException exception){
                    message.setText("Please enter a number.");
                }
            }
//This is where I cant seem to get the code in paintComponent to run when the Draw button is pressed.
            public void paintComponent(Graphics g){
                Graphics2D g2 = (Graphics2D) g;
                Ellipse2D.Double circle = new Ellipse2D.Double(x - r, y - r, r*2, r*2);
                g2.draw(circle);
                message.setText("TESTING 2");
            }
        }
    }
    public static void main(String[] args){
        JFrame frame = new JFrame();
        frame.setSize(800, 800);
        frame.setTitle("Circle Generator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cgPanel panel = new cgPanel();
        frame.add(panel);
        frame.setVisible(true);
    }
}

【问题讨论】:

    标签: swing graphics paintcomponent repaint actionevent


    【解决方案1】:

    所以,有几件事。

    您的问题源于您的 ButtonListener 正在扩展 JComponent,因此 repaint() 方法正在为 ButtonListener(实际上不是 JComponent)调用该方法。

    paintComponent 方法也适用于 ButtonListener。

    相反,您希望您的按钮侦听器能够访问您的 cgPanel,以便它可以告诉 IT 重新绘制。而且您的paintComponent 需要移动到cgPanel,但即使那样您也可能不希望它在那里,因为cgPanel 上有一堆其他组件。

    从您的代码中并不清楚您真正希望在哪里绘制圆圈。

    您可能应该创建一个扩展 JPanel 的 CirclePanel,并覆盖 paintComponent 来绘制您的圆圈,然后将其添加到您的 cgPanel。然后让您的 ButtonListener 告诉 CirclPanel 实例重新绘制。

    【讨论】:

    • 当我尝试这样的事情时,尝试在静态上下文中使用非静态方法 repaint() 时出现错误。
    猜你喜欢
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多