父面板未正确重绘
Parent Panel not repainting correctly
我有一个面板,其中包含已添加到其中的自定义组件。它正确地绘制,除非当组件(有自己的鼠标侦听器)被拖动时它开始奇怪地绘制。
有趣的是,如果我稍微调整父面板的大小,它现在将按预期进行绘制。我知道父面板正在通过
重新绘制
super.paintComponent(g);
和面板内的打印语句
paintComponent(Graphics g):
方法。我尝试在组件被拖动时重新验证(因为组件正在重新设置其边界)它变得无效。我仍然没有成功,想知道是否有人可以提供帮助。
是否有某些地方我没有正确重绘可能导致此行为?
另外作为一个附录,我在面板及其组件上都有一个鼠标侦听器,有没有一种方法可以在单击组件时面板鼠标侦听器也做出响应(除了返回到父级 class 来自组件)
这是我遇到的问题的一个工作示例
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;
public class testHome {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
testHome window = new testHome();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public testHome() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new myPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
}
class myPanel extends JPanel {
MyComponent comp;
public myPanel() {
super(null);
comp = new MyComponent(5, 5);
this.add(comp);
revalidate();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Line2D.Double line = new Line2D.Double(10, 10, comp.getX(), comp.getY());
System.out.println(comp.getX() + " " + comp.getY());
g2d.draw(line);
}
}
class MyComponent extends JComponent implements MouseListener, MouseMotionListener {
int x;
int y;
int mx;
int my;
public MyComponent(int x, int y) {
this.setVisible(true);
this.setBounds(x, y, 15, 15);
this.x = x;
this.y = y;
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fillRect(this.x, this.y, 15, 15);
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("dragging");
int dx = e.getX() - mx;
int dy = e.getY() - my;
this.setBounds(this.getX() + dx, this.getY() + dy, 15, 15);
}
@Override
public void mousePressed(MouseEvent e) {
mx = e.getX();
my = e.getY();
}
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
}
父面板实际上并没有完全自动重绘。 paintComponent()
被调用,但是如果您检查裁剪,例如通过:
System.out.println(g.getClipBounds());
您会看到只有较小组件下方的区域被绘制。 (组件不是不透明的,所以父组件需要绘制它下面的区域)。您需要为父面板显式调用 repaint()
:
getParent().repaint();
(或者使用指定区域的 repaint()
变体,如果父组件绘制成本高并且可以优化部分绘制)。
我有一个面板,其中包含已添加到其中的自定义组件。它正确地绘制,除非当组件(有自己的鼠标侦听器)被拖动时它开始奇怪地绘制。
有趣的是,如果我稍微调整父面板的大小,它现在将按预期进行绘制。我知道父面板正在通过
重新绘制 super.paintComponent(g);
和面板内的打印语句
paintComponent(Graphics g):
方法。我尝试在组件被拖动时重新验证(因为组件正在重新设置其边界)它变得无效。我仍然没有成功,想知道是否有人可以提供帮助。
是否有某些地方我没有正确重绘可能导致此行为?
另外作为一个附录,我在面板及其组件上都有一个鼠标侦听器,有没有一种方法可以在单击组件时面板鼠标侦听器也做出响应(除了返回到父级 class 来自组件)
这是我遇到的问题的一个工作示例
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;
public class testHome {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
testHome window = new testHome();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public testHome() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new myPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
}
class myPanel extends JPanel {
MyComponent comp;
public myPanel() {
super(null);
comp = new MyComponent(5, 5);
this.add(comp);
revalidate();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Line2D.Double line = new Line2D.Double(10, 10, comp.getX(), comp.getY());
System.out.println(comp.getX() + " " + comp.getY());
g2d.draw(line);
}
}
class MyComponent extends JComponent implements MouseListener, MouseMotionListener {
int x;
int y;
int mx;
int my;
public MyComponent(int x, int y) {
this.setVisible(true);
this.setBounds(x, y, 15, 15);
this.x = x;
this.y = y;
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fillRect(this.x, this.y, 15, 15);
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("dragging");
int dx = e.getX() - mx;
int dy = e.getY() - my;
this.setBounds(this.getX() + dx, this.getY() + dy, 15, 15);
}
@Override
public void mousePressed(MouseEvent e) {
mx = e.getX();
my = e.getY();
}
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
}
父面板实际上并没有完全自动重绘。 paintComponent()
被调用,但是如果您检查裁剪,例如通过:
System.out.println(g.getClipBounds());
您会看到只有较小组件下方的区域被绘制。 (组件不是不透明的,所以父组件需要绘制它下面的区域)。您需要为父面板显式调用 repaint()
:
getParent().repaint();
(或者使用指定区域的 repaint()
变体,如果父组件绘制成本高并且可以优化部分绘制)。