编辑!未调用的getter函数会导致JPanel在错误的位置重新打印

问题描述 投票:0回答:3

这很奇怪,我有一个gui程序,允许用户通过检测鼠标单击来更新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添加到南北和西borderlayout位置进行了另一项测试,发现中心borderlayout位置(一个画布位于其中)未对齐并且与其他Jpanels重叠,并且在重新绘制后已固定。这似乎是导致Canvas位置发生变化的原因。

Edit3:上述实验的照片enter image description here

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

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

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

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

这很奇怪,我有一个gui程序,它允许用户通过在每次检测到鼠标单击时检测到鼠标单击来更新J面板,JPanel会重新绘制自身。由于某种原因,重新粉刷...

java swing jframe jpanel repaint
3个回答
0
投票

您正在覆盖JComponentJPanel的超类)getX()getX()


0
投票

您能否提供MyFrame类?我尝试使用此代码,并且效果很好:


0
投票

替换

© www.soinside.com 2019 - 2024. All rights reserved.