首页 > 解决方案 > 已编辑!!未调用的 getter 函数导致 JPanel 在错误的位置重新打印

问题描述

这很奇怪,我有一个 gui 程序,它允许用户通过检测 mouseclick 来更新 J 面板,每次检测到鼠标单击时,JPanel 都会重新绘制自己。由于某种原因,即使通过测试,重绘也会减少 30-40 像素,这表明它们是在完全相同的坐标处进行绘制的。但是,在我最小化然后重新最大化窗口后,这个问题就解决了。

在以相同的方法检测到鼠标点击后调用重绘

编辑:下面是该错误的最小再现

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class CenterPanel extends JPanel{
    private  int sideLength = 50;
    private  int x = 10;
    private  int y = 10;

    public CenterPanel() {
        setPreferredSize(new Dimension(x*sideLength,y*sideLength));
        addMouseListener(new Mouse());
    }

    public void paintComponent (Graphics g) {
        super.paintComponent(g);
        this.setBackground(Color.WHITE);
        this.setBorder(new LineBorder(Color.BLACK,3));
        try {
            createCanvas(x,y,g,sideLength);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void createCanvas(int x, int y, Graphics g, int sideLength) throws InterruptedException {
        int coordX=0;
        int coordY=0;
        for(int i=0; i<x;i++) {
            for(int j=0; j<x;j++) {
                paintRectangle(g,Color.LIGHT_GRAY,coordX,coordY,sideLength-1,sideLength-1);
                coordX=coordX+sideLength;
            }
            coordX=0;
            coordY=coordY+sideLength;
        }
    }

    private static void paintRectangle(Graphics g,Color color,int x, int y,int width,int height) throws InterruptedException {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }   

    class Mouse extends MouseAdapter{
        public void mouseClicked (MouseEvent e) {
            repaint();
        }
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

import javax.swing.*;
import javax.swing.border.LineBorder;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class TestFrame extends JFrame implements MouseMotionListener, ActionListener{

    private static Color currentColor = Color.lightGray;

    private static Color defaultColor = Color.lightGray;

    private CenterPanel centerPanel;
    JButton red, yellow, white, pink, orange, magenta, light_gray, green, gray, dark_gray, cyan, blue, black; 

    public TestFrame() {
        centerPanel=new CenterPanel();
        gui();
    }

    private void gui() {
        JPanel topPanel = new JPanel ();
        topPanel.setBackground(Color.GREEN);
        topPanel.setPreferredSize(new Dimension(50,50));

        JPanel bottomPanel = new JPanel ();
        bottomPanel.setBackground(Color.YELLOW);
        bottomPanel.setPreferredSize(new Dimension(50,50));

        JPanel leftPanel = new JPanel ();
        leftPanel.setBackground(Color.RED);
        leftPanel.setPreferredSize(new Dimension(50,50));

        JPanel rightPanel = new JPanel ();
        rightPanel.setBackground(Color.PINK);
        rightPanel.setPreferredSize(new Dimension(50,50));

        Container c = this.getContentPane();
        c.setLayout(new BorderLayout());

        c.add(centerPanel, BorderLayout.CENTER);
        c.add(topPanel, BorderLayout.NORTH);
        c.add(bottomPanel, BorderLayout.SOUTH);
        c.add(leftPanel, BorderLayout.WEST);
        c.add(rightPanel, BorderLayout.EAST);       

        this.setVisible(true);

        pack();
    }

    public void actionPerformed(ActionEvent e) {

    }

    public static void main(String[] args) {
        TestFrame t=new TestFrame();

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        // TODO Auto-generated method stub

    }
}

Edit2:我通过将 Jpanels 添加到南北和西边界布局位置进行了另一项测试,发现中心边界布局位置(一个画布在其中)未对齐并且与其他 Jpanels 重叠并且在重新绘制后被修复。这似乎是导致 Canvas 位置变化的原因。

Edit3:所述实验的照片 在此处输入图像描述

更新:我将 CenterPanel Jpanel 的 setSize() 更改为 setPreferredSize()。现在重叠显示而无需调用重绘(鼠标单击)。

**更新!!!我已将问题缩小到 CenterPanel 中的 getter 函数**

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

这两个。如果我删除它们,问题就会消失。问题是我仍然不明白为什么这两个 getter 函数甚至没有被调用时会导致这个问题???

标签: javaswingjframejpanelrepaint

解决方案


你能提供一个 MyFrame 课程吗?我尝试使用此代码并且效果很好:

import javax.swing.JFrame;
import java.awt.Color;

public class App extends JFrame {
    public static void main(String[] args) {
        App app = new App();
        app.start();
    }

    public static Color getCurrentColor() {
        return Color.GREEN.darker();
    }

    public void start() {
        setSize(400, 400);
        setVisible(true);
        add(new Canvas());
    }

    public static Color getDefaultColor() {
        return Color.BLUE;
    }
}

推荐阅读