java - Repaint() 和 PaintComponent() 未正确更新

标签 java swing paintcomponent repaint

我有一个带有两个按钮的 Jframe:“A”和“B”。单击按钮“A”应在 JPanel 中显示大写字母 A。这里的问题是,重复单击鼠标时,以前绘制的字母不会显示。我想确保所绘制的内容都保留在绘图中。以下是我的程序的代码。

JFrame 代码:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class DrawFrame extends JFrame{
    private final int WIDTH = 500;
    private final int HEIGHT = 300;

    private GUIModel model;

    private JButton number1;
    private JButton number2;

    private JPanel numberPanel;
    private DrawPanel graphicsPanel;

    public DrawFrame()
    {
        this.model = new GUIModel(" ");

        createSelectionPanel();
        createGraphicsPanel();

        this.setSize(WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    private void createSelectionPanel()
    {
        numberPanel = new JPanel();

        ButtonListener listener = new ButtonListener();

        number1 = new JButton("A");
        number1.addActionListener(listener);

        number2 = new JButton("B");
        number2.addActionListener(listener);  

        numberPanel.setLayout(new GridLayout(2,2));
        numberPanel.add(number1);
        numberPanel.add(number2);

        this.add(numberPanel, BorderLayout.WEST);
    }

    private void createGraphicsPanel()
    {
        //instantiate drawing panel
        graphicsPanel = new DrawPanel(WIDTH, HEIGHT, model);
        //add drawing panel to right
        add(graphicsPanel);
    }

    private class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            model.setDisplayString(event.getActionCommand());
        }
    }

    //creates a drawing frame
    public static void main(String[] args)
    {
        DrawFrame draw = new DrawFrame();
    }   
}

JPanel 代码:

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;

public class DrawPanel extends JPanel{
    private static final long serialVersionUID = 3443814601865936618L;

    private Font font = new Font("Default", Font.BOLD, 30);

    private static final Color DEFAULT_TEXT_COLOR = Color.BLACK;
    private static final Color HOVER_TEXT_COLOR = Color.RED;
    private Color color = DEFAULT_TEXT_COLOR;

    private List<GUIModel> numberList = new ArrayList<GUIModel>();
    private GUIModel model;
    boolean mouseHover = false;

    public DrawPanel(int width, int height, GUIModel model){
        this.setPreferredSize(new Dimension(width, height));
        this.model = model;

        //set white background for drawing panel
        setBackground(Color.WHITE);

        //add mouse listeners
        MouseHandler mouseHandler = new MouseHandler();
        this.addMouseListener(mouseHandler);
        this.addMouseMotionListener(mouseHandler);
    }

//    void checkForHover(MouseEvent event) {
//        FontMetrics metrics = getFontMetrics(font);
//
//        Graphics g = getGraphics();
//        Rectangle textBounds = metrics.getStringBounds("C", g).getBounds();
//        g.dispose();
//
//        int index = 0;
//        while (index < numberList.size()) {
//            Double x = numberList.get(index).getCoordinate().getX();
//            Double y = numberList.get(index).getCoordinate().getY();
//            
//            textBounds.translate(x.intValue(), y.intValue());
//            
//            if (textBounds.contains(event.getPoint())) {
//                color = HOVER_TEXT_COLOR;
//            }
//            else {
//                color = DEFAULT_TEXT_COLOR;
//            }
//            index++;
//        }
//    }

this is my PaintComponent method where I'm going through the list of letters I've drawn at different coordinates and drawing them on the canvas

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setFont(font);
        g.setColor(color);

        int index = 0;
        while (index < numberList.size()) {
            Double x = numberList.get(index).getCoordinate().getX();
            Double y = numberList.get(index).getCoordinate().getY();
            String display = numberList.get(index).getDisplayString();
            g.drawString(display, x.intValue(), y.intValue());
            index++;
        }

        if (model.getCoordinate() != null) {
            Point p = model.getCoordinate();            
            g.drawString(model.getDisplayString(), p.x, p.y);
            numberList.add(model);
        }
    }

    //class to handle all mouse events
    private class MouseHandler extends MouseAdapter implements MouseMotionListener
    {
        @Override
        public void mousePressed(MouseEvent event)
        {
           model.setCoordinate(event.getPoint());
        }

        @Override
        public void mouseReleased(MouseEvent event)
        {
            DrawPanel.this.repaint();
        }

//        @Override
//        public void mouseEntered(MouseEvent event) {
//            checkForHover(event);
//        }
//        
//        @Override
//        public void mouseMoved(MouseEvent event) {
//            checkForHover(event);
//        }
    }
}

GUIModel 代码:

import java.awt.Point;

public class GUIModel {
    private String displayString;
    private Point coordinate;

    public GUIModel(String displayString) {
        this.displayString = displayString;
    }
    public void setDisplayString(String displayString) {
        this.displayString = displayString;
    }

    public String getDisplayString() {
        return displayString;
    }

    public Point getCoordinate() {
        return coordinate;
    }

    public void setCoordinate(int x, int y) {
        this.coordinate = new Point(x, y);
    }

    public void setCoordinate(Point coordinate) {
        this.coordinate = coordinate;
    }   
}

任何帮助或建议将不胜感激。谢谢。

最佳答案

@MadProgrammer 你的评论帮助我修复了我的代码。就像你说的,我需要创建一个新的 GUIModel 并将其添加到我的 numberList 中。

我修改了 PaintComponent 方法来反射(reflect)这一点,现在它可以工作了。所以,谢谢!

public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setFont(font);
    g.setColor(color);

    int index = 0;
    while (index < numberList.size()) {
        Double x = numberList.get(index).getCoordinate().getX();
        Double y = numberList.get(index).getCoordinate().getY();
        String display = numberList.get(index).getDisplayString();
        g.drawString(display, x.intValue(), y.intValue());
        index++;
    }

    if (model.getCoordinate() != null) {
        Point p = model.getCoordinate();            
        g.drawString(model.getDisplayString(), p.x, p.y);
        GUIModel number = new GUIModel();
        number.setCoordinate(p);
        number.setDisplayString(model.getDisplayString());
        numberList.add(number);
    }
}

关于java - Repaint() 和 PaintComponent() 未正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33768648/

相关文章:

java - Leiningen 2.2 -> 2.5 的重大变化

java - 在 JtextPane 中突出显示单词时性能非常慢

java - 使整个 jinternalframe 透明

java - 将 Shape 的中心与 JPanel 的中心对齐

java - 使用 Spring 和 JsonTypeInfo 注释将 JSON 反序列化为多态对象模型

java - 为什么在 IRC 聊天中使用 PircBot 的 getPrefix 方法不返回任何内容?

java - 在 listView android 中设置 alpha 透明度

java - 如何在按下窗口关闭按钮时最小化 jFrame?

java - 只绘制一次图像,无需重新绘制

java - 在 JComponent 顶部绘制