我正在尝试构建一个简单的绘图工具。 mouseDrag
个事件会创建一个新的椭圆并导致我的JPanel
转到repaint()
。
到目前为止,此工作正常。
但是,如果我在第一次触发mouseDrag
事件之前按下任何按钮(或任何其他UI组件),则该按钮将绘制在我面板的左上角。
我已将代码隔离到此测试应用程序中:
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test extends JFrame
{
public Test()
{
final JPanel paintPanel = new JPanel(){
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setPaintMode();
g2d.setStroke(new BasicStroke(1));
g2d.fillRect(100, 100, 10, 10);
}
};
paintPanel.setPreferredSize(new Dimension(300,300));
paintPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e)
{
paintPanel.repaint();
}
});
this.setLayout(new FlowLayout());
this.add(paintPanel);
this.add(new JButton("Dummy"));
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String... args)
{
new Test();
}
}
A Screenshot for "seeing" the problem in my Main application
答案 0 :(得分:8)
+1 @ MadProgrammer的答案。
super.paintComponent(..)
作为覆盖paintComponent()
JFrame
setPrefferedSize()
而是覆盖getPrefferedSize()
这是一个结合了我的建议和@MadProgrammer的例子:
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
JFrame frame;
public Test() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final PaintPanel paintPanel = new PaintPanel();
paintPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
paintPanel.addRect(e.getX(), e.getY());
}
});
frame.setLayout(new FlowLayout());
frame.add(paintPanel);
frame.add(new JButton("Dummy"));
frame.pack();
frame.setVisible(true);
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
}
class PaintPanel extends JPanel {
public PaintPanel() {
addRect(100, 100);
}
ArrayList<Rectangle> rects = new ArrayList<>();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaintMode();
for (Rectangle r : rects) {
g2d.setStroke(new BasicStroke(1));
g2d.fillRect(r.x, r.y, r.width, r.height);
}
}
public void addRect(int x, int y) {
rects.add(new Rectangle(x, y, 10, 10));
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
答案 1 :(得分:7)
您没有致电super.paintComponent
。
用于绘画循环的图形上下文在开始绘制的所有组件之间共享,这意味着如果你在绘画之前没有注意清除它,你将最终得到你之前绘制的内容。
paintComponent
的一项工作是为绘画准备图形