我的项目遇到了麻烦。 使用我从前一个问题收到的代码,我已经复制了我的问题。 我需要添加一个清除和撤消JButton。你可以看到我添加了按钮hpwever我无法执行所需的操作。 我已经尝试将ActionListeners添加到创建按钮的类,然后尝试执行 itemsDrawn = new ArrayList<&gt ;; (清楚) itemsDrawn.remove(itemsDrawn.size() - 1)(用于撤消) 作为结果的动作,但程序锁定。
基本上我正在做这个/我把ActionListeners放在哪里?
任何帮助将不胜感激
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class MyPaint {
static ArrayList<Drawable> itemsDrawn;
static JButton Clear,Undo;
public static void main(String[] args) {
new MyPaint();
}
public MyPaint() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Java 2D Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
DrawablePane dp = new DrawablePane();
ControlPane cp = new ControlPane(dp);
frame.add(dp);
frame.add(cp, BorderLayout.NORTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class State {
private final Color foreground;
private final Color background;
private final boolean gradient;
private final boolean filled;
private final boolean dashed;
private int LineWidth, DashLength;
public State(Color foreground, Color background, boolean gradient, boolean filled, boolean dashed,int LineWidth, int DashLength) {
this.foreground = foreground;
this.background = background;
this.gradient = gradient;
this.filled = filled;
this.dashed = dashed;
this.LineWidth = LineWidth;
this.DashLength = DashLength;
}
public Color getBackground() {
return background;
}
public Color getForeground() {
return foreground;
}
public boolean isGradient() {
return gradient;
}
public boolean isFilled() {
return filled;
}
public boolean isDashed(){
return dashed;
}
public int getLineWidth(){
return LineWidth;
}
public int getDashLength(){
return DashLength;
}
}
public class ControlPane extends JPanel {
private JComboBox shapes;
private JLabel foreground;
private JLabel background;
private JCheckBox gradient,Filled,dashed;
private JTextField Dashlength,Linewidth;
private JLabel Len,Wid;
private DrawablePane drawablePane;
public ControlPane(DrawablePane pane) {
shapes = new JComboBox<>(new String[]{"Rectangle", "Oval","Line"});
foreground = createColorLable(Color.BLACK);
foreground.setToolTipText("Foreground");
background = createColorLable(Color.WHITE);
background.setToolTipText("Background");
gradient = new JCheckBox("Gradient");
Filled = new JCheckBox("Filled");
dashed = new JCheckBox("Dashed");
Dashlength = new JTextField("1");
Linewidth = new JTextField("1");
Len = new JLabel("Dash Length:");
Wid = new JLabel("Line Width:");
Clear = new JButton("Clear");
Undo = new JButton("Undo");
JPanel panel = new JPanel();
panel.add(Clear);
panel.add(Undo);
panel.add(foreground);
panel.add(background);
panel.add(Filled);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
add(shapes, gbc);
add(panel, gbc);
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.NORTH;
add(gradient, gbc);
add(dashed, gbc);
add(Len);
add(Linewidth);
add(Wid);
add(Dashlength);
setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(12, 12, 12, 12)));
this.drawablePane = pane;
MouseHandler mouseHandler = new MouseHandler();
drawablePane.addMouseListener(mouseHandler);
drawablePane.addMouseMotionListener(mouseHandler);
}
public int getDash(){
String Length = Dashlength.getText();
int Dash = Integer.parseInt(Length);
return Dash;
}
public int getLine(){
String LWidth = Linewidth.getText();
int Line = Integer.parseInt(LWidth);
return Line;
}
protected Drawable createDrawable() {
Drawable drawable = null;
State state = new State(foreground.getBackground(), background.getBackground(), gradient.isSelected(), Filled.isSelected(), dashed.isSelected(),getLine(), getDash());
String selected = (String) shapes.getSelectedItem();
if ("rectangle".equalsIgnoreCase(selected)) {
drawable = new Square(state);
} else if ("oval".equalsIgnoreCase(selected)) {
drawable = new Circle(state);
}
else if ("Line".equalsIgnoreCase(selected)){
drawable = new Line(state);
}
return drawable;
}
protected JLabel createColorLable(Color base) {
final JLabel label = new JLabel();
label.setBackground(base);
label.setBorder(new LineBorder(Color.BLACK));
label.setPreferredSize(new Dimension(25, 25));
label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
label.setOpaque(true);
label.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Color color = JColorChooser.showDialog(label, "Color", label.getBackground());
if (color != null) {
label.setBackground(color);
}
}
});
return label;
}
public class MouseHandler extends MouseAdapter {
private Drawable drawable;
private Point clickPoint;
@Override
public void mousePressed(MouseEvent e) {
drawable = createDrawable();
drawable.setLocation(e.getPoint());
drawablePane.addDrawable(drawable);
clickPoint = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
Point drag = e.getPoint();
Point start = clickPoint;
int maxX = Math.max(drag.x, start.x);
int maxY = Math.max(drag.y, start.y);
int minX = Math.min(drag.x, start.x);
int minY = Math.min(drag.y, start.y);
int width = maxX - minX;
int height = maxY - minY;
drawable.setLocation(new Point(minX, minY));
drawable.setSize(new Dimension(width, height));
drawablePane.repaint();
}
}
}
public interface Drawable {
public void paint(JComponent parent, Graphics2D g2d);
public void setLocation(Point location);
public void setSize(Dimension size);
public State getState();
public Rectangle getBounds();
}
public abstract class AbstractDrawable implements Drawable {
private Rectangle bounds;
private State state;
public AbstractDrawable(State state) {
bounds = new Rectangle();
this.state = state;
}
@Override
public State getState() {
return state;
}
public abstract Shape getShape();
@Override
public void setLocation(Point location) {
bounds.setLocation(location);
}
@Override
public void setSize(Dimension size) {
bounds.setSize(size);
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public void paint(JComponent parent, Graphics2D g2d) {
Shape shape = getShape();
State state = getState();
Rectangle bounds = getBounds();
final float dash1[] = {state.LineWidth};
final BasicStroke dashed =
new BasicStroke(state.DashLength,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
10.0f, dash1, 0.0f);
if (bounds.width > 0 && bounds.height > 0) {
if (state.isGradient()){
if (state.isDashed()){
Point2D startPoint = new Point2D.Double(bounds.x, bounds.y);
Point2D endPoint = new Point2D.Double(bounds.x + bounds.width, bounds.y + bounds.height);
LinearGradientPaint gp = new LinearGradientPaint(
startPoint,
endPoint,
new float[]{0f, 1f},
new Color[]{state.getForeground(), state.getBackground()});
g2d.setPaint(gp);
g2d.setStroke(dashed);
g2d.draw(shape);
}
else{
Point2D startPoint = new Point2D.Double(bounds.x, bounds.y);
Point2D endPoint = new Point2D.Double(bounds.x + bounds.width, bounds.y + bounds.height);
LinearGradientPaint gp = new LinearGradientPaint(
startPoint,
endPoint,
new float[]{0f, 1f},
new Color[]{state.getForeground(), state.getBackground()});
g2d.setPaint(gp);
g2d.fill(shape);
}
}
else if (state.isFilled()){
if (bounds.width > 0 && bounds.height > 0) {
g2d.setPaint(state.getForeground());
g2d.fill(shape);
}
}
else if(state.isDashed()){
g2d.setStroke(dashed);
g2d.setPaint(state.getForeground());
g2d.draw(shape);
}
else{
BasicStroke stroke = new BasicStroke();
g2d.setStroke(stroke);
g2d.setPaint(state.getForeground());
g2d.draw(shape);
}
}
}
}
public class Square extends AbstractDrawable {
public Square(State state) {
super(state);
}
@Override
public Shape getShape() {
return getBounds();
}
}
public class Circle extends AbstractDrawable {
public Circle(State state) {
super(state);
}
@Override
public Shape getShape() {
Rectangle bounds = getBounds();
return new Ellipse2D.Float(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
public class Line extends AbstractDrawable {
public Line(State state){
super(state);
}
@Override
public Shape getShape() {
Rectangle bounds = getBounds();
return new Line2D.Float(bounds.x, bounds.y,bounds.width, bounds.height);
}
}
public class DrawablePane extends JPanel {
List<Drawable> itemsDrawn;
public DrawablePane() {
itemsDrawn = new ArrayList<>();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable d : itemsDrawn) {
d.paint(this, g2d);
}
g2d.dispose();
}
public void addDrawable(Drawable drawable) {
itemsDrawn.add(drawable);
repaint();
}
}
}
这是带有已实现的撤消和清除按钮的ControlPane类
public ControlPane(DrawablePane pane) {
shapes = new JComboBox<>(new String[]{"Rectangle", "Oval","Line"});
foreground = createColorLable(Color.BLACK);
foreground.setToolTipText("Foreground");
background = createColorLable(Color.WHITE);
background.setToolTipText("Background");
gradient = new JCheckBox("Gradient");
Filled = new JCheckBox("Filled");
dashed = new JCheckBox("Dashed");
Dashlength = new JTextField("1");
Linewidth = new JTextField("1");
Len = new JLabel("Dash Length:");
Wid = new JLabel("Line Width:");
Clear = new JButton("Clear");
Undo = new JButton("Undo");
JPanel panel = new JPanel();
panel.add(Clear);
panel.add(Undo);
panel.add(foreground);
panel.add(background);
panel.add(Filled);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
add(shapes, gbc);
add(panel, gbc);
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.NORTH;
add(gradient, gbc);
add(dashed, gbc);
add(Len);
add(Linewidth);
add(Wid);
add(Dashlength);
setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(12, 12, 12, 12)));
this.drawablePane = pane;
MouseHandler mouseHandler = new MouseHandler();
drawablePane.addMouseListener(mouseHandler);
drawablePane.addMouseMotionListener(mouseHandler);
Clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
itemsDrawn = new ArrayList<>();
(Not sure what to use here).repaint();
}
});
undo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (itemsDrawn.size() != 0) {
itemsDrawn.remove(itemsDrawn.size() - 1);
(Not sure what to put here).repaint();
}
}
});
}
这样的事情(DrawablePane中的clear和undo方法)
Clear.addActionListner(new ActionListener() {
@Override
public void actionPreformed(ActionEvent arg0){
Clear();
}
});
Undo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
Undo();
}
});
public class DrawablePane extends JPanel {
List<Drawable> itemsDrawn;
public DrawablePane() {
itemsDrawn = new ArrayList<>();
}
public void undo(){
if (itemsDrawn.size() != 0) {
itemsDrawn.remove(itemsDrawn.size() - 1);
repaint();
}
}
public void Clear(){
itemsDrawn = new ArrayList<>();
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable d : itemsDrawn) {
d.paint(this, g2d);
}
g2d.dispose();
}
public void addDrawable(Drawable drawable) {
itemsDrawn.add(drawable);
repaint();
}
}
}
我收到一条错误,说明在DrawablePane
中找不到清除和撤消答案 0 :(得分:4)
主要问题是itemsDrawn
使用DrawablePane
而非ControlPane
,因此尝试从ControlPane
更改DrawablePane
对DrawablePane
无效
相反,您应该向undo
调用clear
和ActionListener
添加两个方法,这些方法可以通过ControlPane
中的undo
来调用
更新了示例
首先,将clear
和DrawablePane
方法添加到public class DrawablePane extends JPanel {
List<Drawable> itemsDrawn;
public DrawablePane() {
itemsDrawn = new ArrayList<>();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable d : itemsDrawn) {
d.paint(this, g2d);
}
g2d.dispose();
}
public void addDrawable(Drawable drawable) {
itemsDrawn.add(drawable);
repaint();
}
public void undo() {
if (!itemsDrawn.isEmpty()) {
int size = itemsDrawn.size() - 1;
itemsDrawn.remove(size);
repaint();
}
}
public void clear() {
itemsDrawn.clear();
repaint();
}
}
...
ActionListener
其次,从适当的clear.addActionListner(new ActionListener() {
@Override
public void actionPreformed(ActionEvent arg0) {
drawablePane.clear();
}
});
undo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
drawablePane.undo();
}
});
...
ControlPane
显然,这些会在您的{{1}}
中创建答案 1 :(得分:0)
在BufferedImage上绘制图形并将其显示在DrawPane的paintComponent方法中。如果要清除它,只需用背景颜色覆盖BufferedImage或创建一个新的BufferedImage并将其填充到图像变量中。
public class DrawablePane extends JPanel {
private BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);
List<Drawable> itemsDrawn;
public DrawablePane() {
itemsDrawn = new ArrayList<>();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
public void addDrawable(Drawable drawable) {
itemsDrawn.add(drawable);
repaint();
}
public void clear() {
img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);
repaint();
}
}
在您为此课程提供的公共方法中,您的所有绘图 上的BufferedImage。