我正在尝试使用Swing和Graphics2D制作Digital Doily应用程序。我以前从未使用Swing或任何2D图形。当你拿着鼠标时,你应该能够绘制东西,但由于某种原因它不起作用,我无法弄清楚原因。我没有发布GalleryPanel.java类,因为它不会以任何方式影响绘图。这是我的代码:
Main.java
public class Main {
public static final int WINDOW_WIDTH = 1600;
public static final int WINDOW_HEIGHT = 800;
public static final int SIDE_MENU_WIDTH = WINDOW_WIDTH / 4;
public static final String TITLE = "Digital Doily";
public static final Font PANEL_TITLE_FONT = new Font("Arial", Font.BOLD, 16);
/**
* Just a main method used to run the JFrame window
* @param args
*/
public static void main(String[] args) {
WindowFrame frame = new WindowFrame(WINDOW_WIDTH, WINDOW_HEIGHT, TITLE);
}
}
WindowFrame.java
public class WindowFrame extends JFrame {
/**
* The width of the window
*/
private int width;
/**
* The height of the window
*/
private int height;
/**
* The main constructor of the window
* @param width - width of the window
* @param height - height of the window
* @param title - title of the window
*/
public WindowFrame(int width, int height, String title) {
super(title);
this.setSize(new Dimension(width, height));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setFont(new Font("Times New Roman", Font.PLAIN, 12));
// Initializing the main GUI elements
initializeGUI();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
/**
* The main GUI of the window frame
*/
private void initializeGUI() {
JPanel window = new JPanel(new BorderLayout());
this.setContentPane(window);
//Doily panel
DoilyPanel doilyPanel = new DoilyPanel();
doilyPanel.setBackground(Color.BLACK);
window.add(doilyPanel, BorderLayout.CENTER);
// Gallery panel
GalleryPanel galleryPanel = new GalleryPanel(doilyPanel);
galleryPanel.setBackground(Color.getColor("DDDDDD"));
window.add(galleryPanel, BorderLayout.EAST);
// Options panel
OptionsPanel optionPanel = new OptionsPanel(this, doilyPanel, galleryPanel);
optionPanel.setBackground(Color.getColor("DDDDDD"));
window.add(optionPanel, BorderLayout.WEST);
window.setVisible(true);
}
}
OptionsPanel.java
public class OptionsPanel extends JPanel {
/**
* An instance of the DoilyPanel class
*/
private DoilyPanel doilyPanel;
/**
* An instance of JFrame
*/
private JFrame frame;
private GalleryPanel galleryPanel;
public OptionsPanel(JFrame frame, DoilyPanel doilyPanel, GalleryPanel galleryPanel) {
this.doilyPanel = doilyPanel;
this.frame = frame;
this.galleryPanel = galleryPanel;
/**
* Start of GUI
*/
this.setPreferredSize(new Dimension(Main.SIDE_MENU_WIDTH, Main.WINDOW_HEIGHT));
setLayout(new BorderLayout());
//Initializing the panel GUI elements
initializeGUI();
setVisible(true);
/**
* End of GUI
*/
}
/**
* The main GUI of the panel
*/
private void initializeGUI() {
// Title panel
JPanel titlePanel = new JPanel();
titlePanel.setBackground(Color.WHITE);
this.add(titlePanel, BorderLayout.NORTH);
// Options title label
JLabel optionsTitle = new JLabel("Options");
optionsTitle.setFont(Main.PANEL_TITLE_FONT);
titlePanel.add(optionsTitle);
titlePanel.setVisible(true);
// Main panel
JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,10));
mainPanel.setPreferredSize(new Dimension(Main.SIDE_MENU_WIDTH, Main.WINDOW_WIDTH - titlePanel.getHeight()));
this.add(mainPanel, BorderLayout.CENTER);
// Doily sector
JLabel sectorTitle = new JLabel("Sectors: ");
mainPanel.add(sectorTitle);
SpinnerModel sectorSpinnerModel = new SpinnerNumberModel(doilyPanel.getSectors(), 1,100,1);
JSpinner sectorSpinner = new JSpinner(sectorSpinnerModel);
mainPanel.add(sectorSpinner);
// Pen size
JLabel penSizeTitle = new JLabel("Pen size: ");
mainPanel.add(penSizeTitle);
SpinnerModel penSizeSpinnerModel = new SpinnerNumberModel(doilyPanel.getPenSize(), 1,100,1);
JSpinner penSizeSpinner = new JSpinner(penSizeSpinnerModel);
mainPanel.add(penSizeSpinner);
// Clear
JButton clearButton = new JButton("Clear");
mainPanel.add(clearButton);
// Undo
JButton undoButton = new JButton("Undo");
mainPanel.add(undoButton);
// Redo
JButton redoButton = new JButton("Redo");
mainPanel.add(redoButton);
// Delete
JButton deleteButton = new JButton("Delete");
mainPanel.add(deleteButton);
// Change pen color
JButton changePenColorButton = new JButton("Change pen color");
mainPanel.add(changePenColorButton);
// Save
JButton saveButton = new JButton("Save");
mainPanel.add(saveButton);
// Toggle sector lines
JButton toggleSectorLinesButton = new JButton("Sector lines: " + doilyPanel.getSectorLinesStatus());
mainPanel.add(toggleSectorLinesButton);
// Toggle reflections
JButton toggleReflectionButton = new JButton("Reflections: " + doilyPanel.getReflectedDrawingStatus());
mainPanel.add(toggleReflectionButton);
// Toggle eraser
JButton toggleEraserButton = new JButton("Eraser: ");
mainPanel.add(toggleEraserButton);
// Creating a new OptionsPanelListener
OptionsPanelListener optionsPanelListener = new OptionsPanelListener(
frame, doilyPanel, galleryPanel, penSizeSpinner, sectorSpinner, clearButton, undoButton, redoButton, deleteButton,
changePenColorButton, saveButton, toggleSectorLinesButton, toggleReflectionButton, toggleEraserButton
);
// Adding all listeners to the components
sectorSpinner.addChangeListener(optionsPanelListener);
mainPanel.setVisible(true);
}
}
OptionsPanelListener.java
public class OptionsPanelListener implements ActionListener, ChangeListener {
private JFrame frame;
private DoilyPanel doilyPanel;
private GalleryPanel galleryPanel;
private JSpinner sectorSpinner;
private JSpinner penSizeSpinner;
private JButton clearButton;
private JButton undoButton;
private JButton redoButton;
private JButton deleteButton;
private JButton changePenColorButton;
private JButton saveButton;
private JButton toggleSectorLinesButton;
private JButton toggleReflectionButton;
private JButton toggleEraserButton;
public OptionsPanelListener(
JFrame frame, DoilyPanel doilyPanel, GalleryPanel galleryPanel, JSpinner penSizeSpinner, JSpinner sectorSpinner, JButton clearButton, JButton undoButton, JButton redoButton,
JButton deleteButton, JButton changePenColorButton, JButton saveButton, JButton toggleSectorLinesButton, JButton toggleReflectionButton, JButton toggleEraserButton
) {
this.frame = frame;
this.doilyPanel = doilyPanel;
this.galleryPanel = galleryPanel;
this.penSizeSpinner = penSizeSpinner;
this.sectorSpinner = sectorSpinner;
this.clearButton = clearButton;
this.undoButton = undoButton;
this.redoButton = redoButton;
this.deleteButton = deleteButton;
this.changePenColorButton = changePenColorButton;
this.saveButton = saveButton;
this.toggleSectorLinesButton = toggleSectorLinesButton;
this.toggleReflectionButton = toggleReflectionButton;
this.toggleEraserButton = toggleEraserButton;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == clearButton) {
doilyPanel.removeStrokes();
doilyPanel.repaint();
} else if(e.getSource() == undoButton) {
if (!doilyPanel.getStrokes().isEmpty()) {
doilyPanel.removeStrokes(doilyPanel.getStrokesSize());
doilyPanel.repaint();
}
// TO DO:
} else if (e.getSource() == redoButton) {
if (!doilyPanel.getStrokes().isEmpty()) {
doilyPanel.repaint();
}
} else if (e.getSource() == changePenColorButton) {
Color color = JColorChooser.showDialog(frame, "Change pen color", frame.getBackground());
if (color != null) {
doilyPanel.setStrokeColor(color);
doilyPanel.setColor(color);
}
doilyPanel.repaint();
} else if(e.getSource() == saveButton) {
if (galleryPanel.getDoilies().size() < 12) {
BufferedImage doily = DoilyPanel.resizeDoily(doilyPanel.saveDoily(doilyPanel), 100, 100);
galleryPanel.addDoily(new JLabel(new ImageIcon(doily)));
galleryPanel.revalidate();
} else {
JOptionPane.showMessageDialog(null, "The maximum number of doilies you can save is 12.");
}
} else if (e.getSource() == toggleSectorLinesButton) {
doilyPanel.toggleSectorLines();
doilyPanel.setSectorLinesStatus(doilyPanel.updateSectorLinesStatus());
doilyPanel.repaint();
} else if(e.getSource() == toggleReflectionButton) {
doilyPanel.toggleReflectDrawing();
doilyPanel.setReflectedDrawingStatus(doilyPanel.updateReflectDrawingStatus());
doilyPanel.repaint();
} else if (e.getSource() == toggleEraserButton) {
}
}
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == penSizeSpinner) {
doilyPanel.setPenSize((int)penSizeSpinner.getValue());
doilyPanel.setStrokePenSize((int) penSizeSpinner.getValue());
doilyPanel.repaint();
//doilyPanel.repaint();
} else if (e.getSource() == sectorSpinner) {
doilyPanel.setSectors((int) sectorSpinner.getValue());
doilyPanel.setSectorsAngle(360.0 / doilyPanel.getSectors());
doilyPanel.repaint();
}
}
}
DoilyPanel.java
public class DoilyPanel extends JPanel {
/**
* How many sectors the doily has
*/
private int sectors;
/**
* The angle between each sector line
*/
private double sectorsAngle;
/**
* How big the size of the pen is
*/
private int penSize;
/**
* The color of the pen
*/
private Color color = Color.WHITE;
/**
* Whether sector lines are activated
*/
private boolean sectorLines = true;
private String sectorLinesStatus;
/**
* Whether reflected drawing is activated
*/
private boolean reflectedDrawing = false;
private String reflectedDrawingStatus;
/**
* The drawing area of the doily
*/
private BufferedImage canvas;
private Pen stroke;
private ArrayList<Pen> strokes;
/**
* |---------------------------------- Methods ----------------------------------|
*/
/**
* Get method for sectors property
* @return the number of sectors
*/
public int getSectors() {
return sectors;
}
/**
* Set method for sectors property
* @param sectors - new number of sectors
*/
public void setSectors(int sectors) {
this.sectors = sectors;
}
public void setSectorsAngle(double sectorsAngle) {
this.sectorsAngle = sectorsAngle;
}
public double getSectorsAngle() {
return sectorsAngle;
}
/**
* Get method for
* @return
*/
public int getPenSize() {
return penSize;
}
public void setPenSize(int penSize) {
this.penSize = penSize;
}
public Pen getStroke() {
return stroke;
}
public void setStroke(Pen stroke) {
this.stroke = stroke;
}
public void setStrokeColor(Color color) {
this.stroke.setColor(color);
}
public void setStrokePenSize(int size) {
this.stroke.setSize(size);
}
public void setColor(Color color) {
this.color = color;
}
public Color getColor() {
return color;
}
public void setCanvas(BufferedImage canvas) {
this.canvas = canvas;
}
public BufferedImage getCanvas() {
return canvas;
}
public boolean getSectorLines() {
return sectorLines;
}
public String getSectorLinesStatus() {
return sectorLinesStatus;
}
public void setSectorLinesStatus(String sectorLinesStatus) {
this.sectorLinesStatus = sectorLinesStatus;
}
public boolean getReflectDrawing() {
return reflectedDrawing;
}
public String getReflectedDrawingStatus() {
return reflectedDrawingStatus;
}
public void setReflectedDrawingStatus(String reflectedDrawingStatus) {
this.reflectedDrawingStatus = reflectedDrawingStatus;
}
public void addPoint(MouseEvent event) {
if (!(sectors % 2 == 0)) {
stroke.addPoint(new Point(event.getY() - this.getWidth() / 2, event.getX() - this.getWidth() / 2));
} else {
stroke.addPoint(new Point(event.getY() - this.getWidth() / 2, -event.getX() - this.getWidth() / 2));
}
repaint();
}
public ArrayList<Pen> getStrokes() {
return strokes;
}
public int getStrokesSize() {
return strokes.size() - 1;
}
public void removeStrokes(int index) {
this.strokes.remove(index);
}
public void removeStrokes() {
this.strokes.clear();
}
public String updateSectorLinesStatus() {
if (sectorLines) {
return "On";
}
return "Off";
}
public String updateReflectDrawingStatus() {
if (reflectedDrawing) {
return "On";
}
return "Off";
}
public DoilyPanel() {
setSectors(6);
setSectorsAngle(360.0 / getSectors());
setPenSize(2);
setColor(Color.BLUE);
stroke = new Pen(this);
strokes = new ArrayList<>();
canvas = new BufferedImage(800, 800, BufferedImage.TYPE_4BYTE_ABGR);
setSectorLinesStatus(updateSectorLinesStatus());
setReflectedDrawingStatus(updateReflectDrawingStatus());
this.setBackground(Color.BLACK);
this.addMouseListener(new DoilyPanelListener(this));
this.addMouseMotionListener(new DoilyPanelListener(this));
}
public void toggleSectorLines() {
sectorLines = !sectorLines;
}
public void toggleReflectDrawing() {
reflectedDrawing = !reflectedDrawing;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setColor(Color.BLACK);
// Centering the image
graphics2D.translate(this.getWidth() / 2, this.getHeight() / 2);
if (sectorLines) {
for (int i = 0; i < sectors; i++) {
graphics2D.setColor(Color.WHITE);
graphics2D.setStroke(new BasicStroke(1));
graphics2D.drawLine(0, 0, 0, 364);
graphics2D.rotate(Math.toRadians(sectorsAngle));
}
}
graphics2D.setColor(Color.BLACK);
graphics2D.setStroke(new BasicStroke(penSize));
for (int i = 0; i < strokes.size(); i++) {
strokes.get(i).paint(graphics2D);
}
stroke.paint(graphics2D);
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
public static BufferedImage resizeDoily(BufferedImage doily, int width, int height) {
BufferedImage resized = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = resized.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(doily, 0, 0, width, height, null);
g2d.dispose();
return resized;
}
public BufferedImage saveDoily(JPanel panel) {
BufferedImage doily = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
panel.paint(doily.getGraphics());
return doily;
}
}
DoilyPanelListener.java
public class DoilyPanelListener implements MouseListener, MouseMotionListener {
private DoilyPanel doilyPanel;
public DoilyPanelListener(DoilyPanel doilyPanel) {
this.doilyPanel = doilyPanel;
}
@Override
public void mouseClicked(MouseEvent e) {
doilyPanel.addPoint(e);
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
doilyPanel.getStrokes().add(doilyPanel.getStroke());
doilyPanel.setStroke(new Pen(doilyPanel));
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
doilyPanel.addPoint(e);
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
Pen.java
public class Pen {
private DoilyPanel doilyPanel;
private int size;
private Color color;
private boolean isReflectedOn;
private ArrayList<Point> points;
public void setSize(int size) {
this.size = size;
}
public int getSize() {
return size;
}
public void setColor(Color color) {
this.color = color;
}
public Color getColor() {
return color;
}
public void setReflectedOn(boolean reflectedOn) {
isReflectedOn = reflectedOn;
}
public void setPoints(ArrayList<Point> points) {
this.points = points;
}
public ArrayList<Point> getPoints() {
return points;
}
public Pen(DoilyPanel doilyPanel) {
this.doilyPanel = doilyPanel;
setSize(doilyPanel.getPenSize());
setColor(doilyPanel.getColor());
setReflectedOn(doilyPanel.getReflectDrawing());
points = new ArrayList<>();
}
public void addPoint(Point p) {
this.points.add(p);
}
public void paint(Graphics graphics) {
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.setColor(color);
for (int i = 0; i < doilyPanel.getSectors(); i++) {
graphics2D.setStroke(new BasicStroke(size));
Point point1 = null;
if (points.size() == 1) {
point1 = points.get(0);
graphics2D.drawRect((int)point1.getX(), (int)point1.getY(), doilyPanel.getPenSize(), doilyPanel.getPenSize());
// Draw Reflections if they are on
if (isReflectedOn) {
graphics2D.drawRect(-(int)point1.getX(), (int)point1.getY(), doilyPanel.getPenSize(), doilyPanel.getPenSize());
}
graphics2D.rotate(Math.toRadians(doilyPanel.getSectorsAngle()));
} else if (points.size() > 1){
Iterator<Point> pointsIterator = points.iterator();
point1 = pointsIterator.next();
while (pointsIterator.hasNext()) {
Point point2 = pointsIterator.next();
graphics2D.drawRect((int)point1.getX(), (int)point1.getY(), (int)point2.getX(), (int)point2.getY());
// Draw Reflections if they are on
if (isReflectedOn) {
graphics2D.drawLine(-(int)point1.getX(), (int)point1.getY(), -(int)point2.getX(), (int)point2.getY());
}
point1 = point2;
}
graphics2D.rotate(Math.toRadians(doilyPanel.getSectorsAngle()));
}
}
}
}