【问题标题】:paintComponent() and paint() - drawing JButton with decorator patternpaintComponent() 和 paint() - 使用装饰器模式绘制 JButton
【发布时间】:2023-04-04 11:45:01
【问题描述】:

我找到了一个带有 Swing 组件的装饰器模式示例。以下代码在JFrame 上绘制三个按钮。其中一个按钮上有斜线,并使用装饰器模式实现。原来的有paint()方法,但是我把paint()换成了paintComponent(Graphics g),然后按钮上画线失败。难道不能用paintComponent()代替paint()吗?如果可能的话怎么做?这次审判的问题是什么?我错过了什么?

原始代码链接是Decorator pattern in Java。

public class DecoWindow extends JFrame implements ActionListener {
    JButton Quit;

    public DecoWindow() {
        super("Deco Button");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jp = new JPanel();

        getContentPane().add(jp);
        jp.add(new CoolDDecorator(new JButton("Cbutton")));
        jp.add(new SlashDDecorator(new CoolDDecorator(new JButton("Dbutton"))));        
        jp.add(Quit = new JButton("Quit"));
        Quit.addActionListener(this);
        setSize(new Dimension(200, 100));
        setVisible(true);
        Quit.requestFocus();
    }

    public void actionPerformed(ActionEvent e) {
        System.exit(0);
    }

    public static void main(String argv[]) {
        new DecoWindow();
    }
}

class DDecorator extends JComponent {
    public DDecorator(JComponent c) {
        setLayout(new BorderLayout());
        add("Center", c);
    }
}

class SlashDDecorator extends DDecorator {
    int x1, y1, w1, h1;

    public SlashDDecorator(JComponent c) {
        super(c);
    }

    public void setBounds(int x, int y, int w, int h) {
          x1 = x; y1 = y;
          w1 = w; h1 = h;
          super.setBounds(x, y, w, h);
    }

    public void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2d = (Graphics2D) g;
          g2d.setColor(Color.red);
          g2d.drawLine(0, 0, w1, h1);
    }
}

class CoolDDecorator extends DDecorator {
    boolean mouse_over; //true when mose over button

    JComponent thisComp;

    public CoolDDecorator(JComponent c) {
        super(c);
        mouse_over = false;
        thisComp = this; //save this component
        //catch mouse movements in inner class
        c.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
                mouse_over = true; //set flag when mouse over
                thisComp.repaint();
            }

            public void mouseExited(MouseEvent e) {
                mouse_over = false; //clear flag when mouse not over
                thisComp.repaint();
            }
        });
    }

    //paint the button
    public void paintComponent(Graphics g) {
        super.paintComponent(g); //first draw the parent button
        Graphics2D g2d = (Graphics2D) g;

        //if the mouse is not over the button
        //erase the borders
        if (!mouse_over) {
            Dimension size = super.getSize();
            g2d.setColor(Color.lightGray);
            g2d.drawRect(0, 0, size.width - 1, size.height - 1);
            g2d.drawLine(size.width - 2, 0, size.width - 2, size.height - 1);
            g2d.drawLine(0, size.height - 2, size.width - 2, size.height - 2);
        }
    }
}

【问题讨论】:

    标签: java swing decorator paint paintcomponent


    【解决方案1】:

    paint() 调用paintComponent() 然后paintChildren()。您的组件正在绘制斜线并从paintComponent() 返回。然后默认的paint() 实现继续前进,最终绘制子项,也就是那些按钮,然后它们就直接绘制在你的斜杠上。

    您的 IDE 应该允许您在绘制代码中放置断点。您可以检查调用堆栈以了解发生了什么。如果您没有使用 IDE,则可以通过查看 JDK 中 src.zip 中的 JComponent.java 来了解 Swing 正在做什么。

    为什么还要使用paintComponent()?

    【讨论】:

    • (1+) 有关详细信息,请参阅:A Closer Look at the Paint Mechanism。
    • 谢谢。 Oracle 文档链接和 JComponent 子类的 UI 处理更精确。
    • 我在 SlashDDecorator 类和 DDecorator 类中添加了更多 public void paintBorder(Graphics g) { super.paintBorder(g); } and public void paintChildren(Graphics g) { super.paintChildren(g); }。但我看不到斜线按钮上的斜线。
    • 问题是paintChildren 会在你的斜线上绘画。您必须防止在您的paintComponent 之后执行绘制子项。调用 super.paintChildren 不会阻止孩子们绘画。一旦你阻止了孩子,你会看到斜线而不是按钮。我认为你将不得不重写paint,而不是paintComponent 来获得你想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 2011-07-18
    • 2013-07-01
    • 2014-10-29
    相关资源
    最近更新 更多