gpt4 book ai didi

java - Repaint() 重新定位按钮

转载 作者:行者123 更新时间:2023-12-02 02:03:02 26 4
gpt4 key购买 nike

我正在编写一个 Java 程序,它将根据按下的按钮绘制圆形或矩形。虽然它确实绘制了给定的形状,但在绘制时它会在窗口的左上角(最有可能是(0,0))创建新按钮。我是否违反了paint()/repaint()的某些规则?

这是我的类(class):

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;
public class Components extends JPanel implements ActionListener
{
String em="Nothing";
public Components()
{
JButton c=new JButton("Rectangle");
JButton b=new JButton("Circle");
b.addActionListener(this);
c.addActionListener(this);
add(c, 0);
add(b, 1);
setBackground(Color.WHITE);
setVisible(true);
}

public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Rectangle"))
{
em="Rectangle";
repaint();
}
else
{
em="Circle";
repaint();
}
}

public void paint(Graphics g)
{
if(em.equals("Rectangle"))
{
g.drawRect(50, 50, 50, 50);
}
else if(em.equals("Circle"))
{
g.drawOval(50, 50, 50, 50);
}

}

}

以及不太重要的 JFrame 类:

import java.awt.Graphics;

import javax.swing.JFrame;
public class Wndw extends JFrame
{
public Wndw()
{
setTitle("Hello");
setSize(400, 400);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new Components());
}

public static void main (String [] args)
{
new Wndw();
}
}

最佳答案

这与重绘有(很少)关系,而与你违反绘画例程有关

首先查看 Performing Custom PaintingPainting in AWT and Swing了解绘画工作原理的更多细节。

paint 通过调用 paintComponentpaintBorderpaintChildren 委托(delegate)其职责。当您重写 paint 并未能调用它的 super 方法时,您就违反了这一责任,最终会遇到像现在这样的问题。

Graphics 上下文是 Swing 组件之间的共享资源。在绘制周期中绘制的每个组件都会获得相同的图形。这意味着,首先应该做的事情之一是准备好图形上下文,以便组件在其上进行绘制。这通常由 paintComponent 方法完成,您不再调用该方法

首先要做的是,停止重写paint,而是通常建议重写paintComponent,它限制了您的总体责任并降低了引入的风险进一步的问题。

接下来,在进行任何自定义绘画之前调用 super.paintComponent...

public class Components extends JPanel implements ActionListener
{
//....
@Overrride
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(em.equals("Rectangle"))
{
g.drawRect(50, 50, 50, 50);
}
else if(em.equals("Circle"))
{
g.drawOval(50, 50, 50, 50);
}
}

But when I do this, what was previously paint is erased

是的,绘画就是这样的。这是破坏性的。当执行绘制 channel 时,您需要重新绘制组件在该时间点的整个状态。

如果您想保留以前绘制的内容,您有两个基本选择。

  1. 将所有内容绘制到后备缓冲区(图像)并进行绘制
  2. 将重新绘制上下文所需的“命令”存储在某种列表

两者都有很多例子

关于java - Repaint() 重新定位按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51274272/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com