перекраска вызывает переполнение компонента - PullRequest
1 голос
/ 06 марта 2019

Я надеюсь, что на этот раз я правильно использовал функцию вопроса. Я был смущен вопросом со вчерашнего дня до настоящего времени. Я воспользовался поиском в Google, чтобы спросить своего учителя по Java, и не решил мою проблему.

Когда я использую repaint, дочерние компоненты в форме JPanel будут превышать свою область отображения. Как на следующих рисунках,

Это тот эффект, который я хочу This is the effect I want

Но когда я использую перекраску, кое-что меняется. But when I use repaint somethings changes.

На первый взгляд кнопка не выглядит правильной. The button doesn’t seem right at first.

Но иногда кнопка возвращается в нормальное состояние But sometimes the button will return to normal

это мой код. Я использую перекраску, потому что информация, которую я проверял, подсказывает мне, что я могу ее использовать. Перекрасьте для достижения анимационных эффектов.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;

class GPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.clip(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), getWidth(), getHeight()));
        g2d.setPaint(Color.BLUE);
        g2d.fillRect(0, 0, getWidth(), getHeight());
    }
}

public class MainComponentOverflow {

    public static void main(String[] args) {
        JFrame frame = new JFrame();

        // This is a panel with a shape
        GPanel panel = new GPanel();

        // This one is the effect I am looking for, the rectangle is displayed in the Panel.
        //panel.add(new Normal());
        // The following two will have problems, the rectangle will be displayed outside the Panel
        //panel.add(new Problem1());
        panel.add(new Problem2());

        //panel.add(new JButton("This will also cause problems, but it may also display properly when I resize the window."));

        frame.add(panel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

class Normal extends JPanel {

    public Normal() {
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

class Problem1 extends JPanel implements ActionListener {

    public Problem1() {
        Timer timer = new Timer(16, this);
        timer.start();
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

class Problem2 extends JPanel implements ActionListener {

    public Problem2() {
        Timer timer = new Timer(16, this);
        timer.start();
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setBackground(new Color((float) Math.random(), (float)Math.random(), (float)Math.random()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

1 Ответ

0 голосов
/ 06 марта 2019

Когда рамка сначала будет нарисована, клип будет установлен в GPanel, а затем дочерние элементы будут окрашены в Problem1 с тем же клипом, поэтому он будет работать.

Однако, когда вы перерисовываете Problem1, GPanel не будет перекрашиваться в первую очередь, поэтому клип не установлен, и отсутствует клип для ограничения Problem1.

Если вместо перекраски Problem1 вы перекрасите родителя, GPanel, это решит вашу проблему.

Другим решением было бы поместить клип в Problem1.

Обратите внимание, что вы можете заменить RoundRect2D на Ellipse2D, так как вы используете его для рисования эллипса.

...