Graphics2D 和 GUI:方法的 ArrayList、方法引用错误
Posted
技术标签:
【中文标题】Graphics2D 和 GUI:方法的 ArrayList、方法引用错误【英文标题】:Graphics2D and GUI: ArrayList of methods, method reference error 【发布时间】:2021-07-25 10:24:25 【问题描述】:假设我有一个包含三个 JButton 的 arrayList:b_line、b_rect、b_oval,它们的功能非常相似——它们在 JFrame 上绘制线条/矩形/椭圆形。
我没有手动为它们三个都编写 actionListener,而是考虑使用 ArrayList 来分配它们的 actionListener - 所以创建一个 Graphic2D 绘制方法的数组列表,如下所示:
drawLine, drawRect, drawOval
下面是我的代码:
ArrayList<Consumer<Void>> draws = new ArrayList<>();
draws.add(Graphics2D::drawLine);
出现错误,说 drawline 是静态方法,不应该在这种情况下使用。
如何修改方法引用以支持 drawLine 方法?感谢您的帮助!
【问题讨论】:
【参考方案1】:drawLine 不符合Consumer 中抽象方法的签名。
您创建了一个Consumer<Void>
对象列表,因此您必须传入Consumer<Void>
对象。 Consumer 类,和所有函数式接口一样,只有一个抽象方法:
public void accept(T argument)
你的方法引用必须匹配那个签名。一个方法的签名是它的返回类型和它的参数类型。因此,您的每个方法引用必须是以下之一:
具有完全相同的返回类型和相同参数的静态方法 一个非静态方法,具有相同的返回类型,属于与上述方法的第一个参数匹配的类型,其其余参数与上述方法的其余参数匹配。Consumer 的accept
方法只有一个参数,因此“剩余参数”为零。因此,您的方法引用必须是以下之一:
void
并接受Void
类型参数的静态方法(因为您的List 需要Consumer<Void>
对象)
属于 Void
类的非静态方法,它返回 void
并且需要零参数
很明显,Graphics.drawLine 不符合这些。 drawLine 确实返回 void,但它肯定不需要 Void
参数。事实上,它需要四个参数,因此它永远不能作为Consumer
。
您必须定义自己的功能接口。例如:
public interface RectangularShapeDrawer
void draw(Graphics g, int x1, int y1, int x2, int y2);
然后在您的列表中使用该类型:
List<RectangularShapeDrawer> drawers = new ArrayList<>();
drawers.add(Graphics::drawLine);
drawers.add(Graphics::drawRect);
drawers.add(Graphics::drawOval);
在我看来,由于每个 Graphics.draw* 方法只是一行代码,因此最好编写三个单独的 ActionListener。
【讨论】:
喜欢这个,尤其是最后一行1+【参考方案2】:这是一种可能性。我会使用枚举而不是 ArrayList。我必须为此设计一个新的功能界面。当然,您可以重命名任何内容。如果未设置活动枚举类型,则不会绘制任何内容。您也可以选择在每次按下按钮后在 process
中将其清空。
enum Draws OVAL(Graphics2D::drawOval),
LINE(Graphics2D::drawLine),
RECT(Graphics2D::drawRect);
private IntPentaFunction fnc;
private Draws(IntPentaFunction fnc)
this.fnc = fnc;
public IntPentaFunction getFnc()
return fnc;
public class ConsumerGraphics extends JPanel
IntPentaFunction active;
JFrame f = new JFrame();
interface IntPentaFunction
public void apply(Graphics2D g2d, int a, int b, int c,
int d);
@Override
public Dimension getPreferredSize()
return new Dimension(500,500);
public static void main(String[] args)
new ConsumerGraphics().start();
public void start()
JButton b_oval = new JButton("Oval");
b_oval.addActionListener((ae)->process(Draws.OVAL));
JButton b_line = new JButton("Line");
b_line.addActionListener((ae)->process(Draws.LINE));
JButton b_rect = new JButton("Rectangle");
b_rect.addActionListener((ae)->process(Draws.RECT));
add(b_oval);
add(b_line);
add(b_rect);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
public void process(Draws type)
// do other stuff in prep for draw
active = type.getFnc();
repaint();
// do any cleanup
@Override
public void paintComponent(Graphics g)
super.paintComponent(g);
if (active == null)
return;
Graphics2D g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.BLUE);
active.apply(g2d,100,100,200,200);
【讨论】:
以上是关于Graphics2D 和 GUI:方法的 ArrayList、方法引用错误的主要内容,如果未能解决你的问题,请参考以下文章
java Graphics2D drawString()内容换行问题