gpt4 book ai didi

java - 保留绘制图形 - 删除 super.paintComponent

转载 作者:行者123 更新时间:2023-12-03 23:05:04 25 4
gpt4 key购买 nike

我有一个名为 Foo 的类,它扩展了一个名为 Bar 的类,该类扩展了 JPanel 并实现了 ActionListener。当我选择 Circle 并单击绘制按钮时,我绘制了一个圆,当我按下矩形并单击绘制时,它会删除​​之前的形状并绘制一个矩形。

但是,我想保留 JPanel 上的所有形状,直到我选择单击删除按钮。所以我删除了 super.paintComponent(g) 并且它可以工作,但它也会导致类 Bar 的按钮以故障方式重新出现。我怎样才能阻止按钮再次绘画?我在考虑不扩展 Bar 而让 Foo 扩展 JPanel。

  public class Bar extends JPanel implements ActionListener
{
public void actionPerformed(ActionEvent e)
{

if (e.getActionCommand() == "Draw")
{
this.requestDraw = true;
repaint();
}
if (e.getActionCommand() == "Circle")
{
requestRectangle = false;
requestTriangle = false;
requestCircle = true;
}
if (e.getActionCommand() == "Rectangle")
{
requestCircle = false;
requestTriangle = false;
requestRectangle = true;
}
if (e.getActionCommand() == "Right Triangle")
{
requestCircle = false;
requestRectangle = false;
requestTriangle = true;
}
}


public class Foo extends Bar
{
@Override
public void paintComponent(Graphics g)
{
//super.paintComponent(g);
if(RequestDraw())
{

if(RequestCircle())
circle.draw(g);
if(RequestRectangle())
rectangle.draw(g);
if(RequestTriangle())
rightTriangle.draw(g);



}

if(!RequestDraw())
{


g.setColor(getBackground());
g.fillRect(0,0,getWidth(), getHeight());
}
}
}
}

enter image description here

最佳答案

在 Hovercraft 的所有评论旁边

图形上下文在组件之间共享。 super.paintComponent 的任务之一是在绘制之前“清理”图形上下文。

这就是为什么您会看到两个版本的按钮...

我也会做一些不同的事情。随着时间的推移,这应该有助于扩展性和重用性,同时也会稍微减少逻辑。

我会...

  • 将形状抽象为具有最低要求的基本“形状”类,例如填充和描边颜色、位置、大小、描边等,并知道如何自行绘制。
  • 我会创建某种模型,允许您分离和定义责任边界。 “管理”形状不是组件的责任,它只关心在其表面上绘制它们。同样,组件不关心“形状”是什么,它只想知道如何绘制它们...
  • 我会使用 Action 来简单地创建这些形状并将它们添加到模型中...

enter image description here

我只创建了一个三角形(除了位置和大小之外,它没有其他属性),但我相信您会明白大概的意思...(请注意,您需要提供自己的三角形图标为了行动 ;))

public class DrawMe {

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

public DrawMe() {

EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());

DrawModel model = new DefaultDrawModel();
model.addElement(new Triangle(new Rectangle(10, 10, 100, 100)));
DrawPane drawPane = new DrawPane(model);

JToolBar toolBar = new JToolBar();
toolBar.add(new AddTriangleAction(model));
frame.add(toolBar, BorderLayout.NORTH);

frame.add(drawPane);
frame.setSize(400, 400);
frame.setVisible(true);
}
});

}

/**
* Simple action used to add triangles to the model...the model acts
* as a bridge between the action and the UI.
*/
protected class AddTriangleAction extends AbstractAction {

private DrawModel model;

public AddTriangleAction(DrawModel model) {
// Supply your own icon
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("/shape_triangle.png")));
this.model = model;
}

public DrawModel getModel() {
return model;
}

@Override
public void actionPerformed(ActionEvent e) {
// Randomly add the triangles...
int x = (int)(Math.random() * 400);
int y = (int)(Math.random() * 400);
model.addElement(new Triangle(new Rectangle(x, y, 100, 100)));
}

}

/**
* This is the background pane, from which the draw pane extends...
*/
protected class BackgroundPane extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

int x = getWidth() / 2;
int y = getHeight() / 2;

Graphics2D g2d = (Graphics2D) g.create();
RadialGradientPaint rgp = new RadialGradientPaint(
new Point(x, y),
Math.max(getWidth(), getHeight()),
new float[]{0f, 1f},
new Color[]{Color.GRAY, Color.WHITE}
);

g2d.setPaint(rgp);
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));

g2d.setBackground(Color.BLACK);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);

g2d.dispose();
}
}

/**
* This is a simple model, I stole the list model because it was quicker
* and easier to demonstrate (don't need to write all the listeners)
*/
public interface DrawModel extends ListModel<DrawMeShape> {
public void addElement(DrawMeShape shape);
public void removeElement(DrawMeShape shape);
}

/**
* A default implementation of the DrawModel...
*/
public class DefaultDrawModel extends DefaultListModel<DrawMeShape> implements DrawModel {
@Override
public void removeElement(DrawMeShape shape) {
removeElement((Object)shape);
}
}

/**
* The actually "canvas" that shapes are rendered to
*/
protected class DrawPane extends BackgroundPane {

// Should provide ability to setModel...
private DrawModel model;

public DrawPane(DrawModel model) {
this.model = model;
model.addListDataListener(new ListDataListener() {

@Override
public void intervalAdded(ListDataEvent e) {
repaint();
}

@Override
public void intervalRemoved(ListDataEvent e) {
repaint();
}

@Override
public void contentsChanged(ListDataEvent e) {
repaint();
}
});
}

public DrawModel getModel() {
return model;
}

@Override
protected void paintComponent(Graphics g) {

super.paintComponent(g);

// Draw the shapes from the model...
Graphics2D g2d = (Graphics2D) g.create();
DrawModel model = getModel();
for (int index = 0; index < model.getSize(); index++) {
DrawMeShape shape = model.getElementAt(index);
shape.paint(g2d, this);
}

g2d.dispose();

}

}

/**
* A abstract concept of a shape. Personally, if I was doing it, I would
* generate an interface first, but this is just a proof of concept...
*/
public abstract class DrawMeShape {

private Rectangle bounds;

public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}

public Rectangle getBounds() {
return bounds;
}

protected abstract Shape getShape();

/**
* The shape knows how to paint, but it needs to know what to paint...
* @param g2d
* @param parent
*/
public void paint(Graphics2D g2d, JComponent parent) {
g2d = (Graphics2D) g2d.create();
Rectangle bounds = getBounds();
Shape shape = getShape();
g2d.translate(bounds.x, bounds.y);
g2d.setColor(Color.DARK_GRAY);
g2d.fill(shape);
g2d.setColor(Color.BLACK);
g2d.draw(shape);
g2d.dispose();
}

}

/**
* An implementation of a Triangle shape...
*/
public class Triangle extends DrawMeShape {

public Triangle(Rectangle bounds) {
setBounds(bounds);
}

@Override
protected Shape getShape() {
// This should be cached ;)
Path2D path = new Path2D.Float();
Rectangle bounds = getBounds();

path.moveTo(bounds.width / 2, 0);
path.lineTo(bounds.width, bounds.height);
path.lineTo(0, bounds.height);
path.lineTo(bounds.width / 2, 0);
path.closePath();

return path;
}
}
}

快乐的画...

关于java - 保留绘制图形 - 删除 super.paintComponent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12810057/

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