diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml new file mode 100644 index 0000000..bf85dad --- /dev/null +++ b/.idea/libraries/lib.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/PaintingBoard.iml b/PaintingBoard.iml index c90834f..615e3ef 100644 --- a/PaintingBoard.iml +++ b/PaintingBoard.iml @@ -7,5 +7,6 @@ + \ No newline at end of file diff --git a/src/Codes/start/MyFrame.java b/src/Codes/start/MyFrame.java index e14d2cd..2a03375 100644 --- a/src/Codes/start/MyFrame.java +++ b/src/Codes/start/MyFrame.java @@ -4,12 +4,13 @@ import Codes.tools.*; import javax.swing.*; +import javax.swing.event.ChangeEvent; import java.awt.*; import java.awt.event.*; +import java.awt.geom.AffineTransform; import java.io.Serial; import java.util.Objects; - public class MyFrame extends JFrame { @Serial @@ -18,6 +19,9 @@ public class MyFrame extends JFrame { * 保存文件的标志 */ public static int saved = 0; + static int height; + static int width; + static double offSetX, offSetY, zoomlvl; /** @@ -78,6 +82,7 @@ public class MyFrame extends JFrame { 粗细调节滑动条 */ public static MySlide slider; + public static MyZoom zoom; MyFrame() { init(); @@ -104,7 +109,7 @@ private void init() { // slider.add(Box.createVerticalGlue()); // 添加弹性空间 slider = new MySlide(); add(slider, BorderLayout.EAST); - + //add(zoom, BorderLayout.SOUTH); // 添加菜单 menu = new MyMenu(this); @@ -127,8 +132,16 @@ private void init() { // 创建各种基本图形的按钮 drawingArea = new DrawPanel(); this.add(drawingArea, BorderLayout.CENTER); + zoom=new MyZoom(drawingArea); statusBar = new JLabel(); - this.add(statusBar, BorderLayout.SOUTH); + JPanel southPanel = new JPanel(); + southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.X_AXIS)); + + southPanel.add(statusBar); + southPanel.add(Box.createHorizontalStrut(30)); // 添加间距 + southPanel.add(zoom); + + add(southPanel, BorderLayout.SOUTH); statusBar.setText("坐标"); /* diff --git a/src/Codes/start/Start.java b/src/Codes/start/Start.java index b979c85..8e7e335 100644 --- a/src/Codes/start/Start.java +++ b/src/Codes/start/Start.java @@ -6,13 +6,6 @@ public class Start { */ public static MyFrame wds; public static void main(String[] args) { - -// try { -// //调用Windows的文件系统 -// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); -// } catch (Exception e) { -// e.printStackTrace(); -// } wds = new MyFrame(); } diff --git a/src/Codes/tools/DrawPanel.java b/src/Codes/tools/DrawPanel.java index ed413f8..87c5265 100644 --- a/src/Codes/tools/DrawPanel.java +++ b/src/Codes/tools/DrawPanel.java @@ -8,6 +8,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; +import java.awt.geom.AffineTransform; import java.io.Serial; import java.util.Objects; @@ -21,7 +22,8 @@ public class DrawPanel extends JPanel @Serial private static final long serialVersionUID = 1L; - + private double zoomLevel = 1.0; + private double offsetX = 0, offsetY = 0; public DrawPanel() { // 设置光标类型,为十字形 this.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); @@ -31,19 +33,34 @@ public DrawPanel() { this.addMouseListener(new MouseAction()); this.addMouseMotionListener(new MouseMotion()); } - + public void setZoomAndOffset(double zoom, double offsetX, double offsetY) { + this.zoomLevel = zoom; + this.offsetX = offsetX; + this.offsetY = offsetY; + repaint(); + } //重写paintComponent方法,使得画板每次刷新时可将之前的所有图形重新画出来。 @Override public void paintComponent(Graphics g) { super.paintComponent(g); - Graphics2D g2d = (Graphics2D) g; // 定义画板 - int j = 0; + Graphics2D g2d = (Graphics2D) g; - while (j <= index) { - draw(g2d, itemList[j]); - j++; + // 保存当前变换 + AffineTransform originalTransform = g2d.getTransform(); + // 应用缩放和平移 + g2d.translate(offsetX, offsetY); + g2d.scale(zoomLevel, zoomLevel); + + // 绘制所有图形 + for (int j = 0; j <= index; j++) { + if (itemList[j] != null) { + draw(g2d, itemList[j]); + } } + + // 恢复原始变换 + g2d.setTransform(originalTransform); } void draw(Graphics2D g2d, AbstractShape abstractShape) { @@ -69,6 +86,7 @@ void draw(Graphics2D g2d, AbstractShape abstractShape) { // // System.out.println(index); // } + public void undo() { if (index > 0) { // 确保有图形可以撤销 System.out.println(index); @@ -241,5 +259,8 @@ public void mouseMoved(MouseEvent e) { statusBar.setText("坐标:[" + e.getX() + "," + e.getY() + "]像素"); } } - + public void setZoomLevel(double zoomLevel) { + this.zoomLevel = zoomLevel; + repaint(); // 重新绘制面板 + } } diff --git a/src/Codes/tools/MyMenu.java b/src/Codes/tools/MyMenu.java index 0af44e5..8ba6e75 100644 --- a/src/Codes/tools/MyMenu.java +++ b/src/Codes/tools/MyMenu.java @@ -2,13 +2,11 @@ import Codes.start.MyFrame; import Codes.start.Start; -import javafx.geometry.Pos; -import javafx.scene.control.Label; -import javafx.scene.control.Slider; -import javafx.scene.layout.HBox; import javax.imageio.ImageIO; import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.filechooser.FileFilter; import java.awt.*; import java.awt.event.InputEvent; @@ -23,10 +21,6 @@ * 菜单初始化部分 */ public class MyMenu { - static int height; - static int width; - static double offSetX, offSetY, zoomlvl; - private final String[] strokes = {"/image/stroke1.png", "/image/stroke2.png", "/image/stroke3.png", "/image/stroke4.png"}; @@ -37,8 +31,8 @@ public MyMenu(MyFrame frame) { void addMenu(MyFrame frame) { /* - ** 顶部菜单条 - */ + ** 顶部菜单条 + */ JMenuBar jMenuBar = new JMenuBar(); JMenuItem[] strokeItems = new JMenuItem[strokes.length]; @@ -212,76 +206,39 @@ void openFile() { if (fileName.getName().isEmpty()) { JOptionPane.showMessageDialog(fileChooser, "无效的文件名", "无效的文件名", JOptionPane.ERROR_MESSAGE); } - /* - BufferedImage image; -try { - image = ImageIO.read(fileName); - if (image == null) { - JOptionPane.showMessageDialog(MyFrame.this, "无法读取图片!"); - return; - } - - // 获取图片原始尺寸 - int imgWidth = image.getWidth(); - int imgHeight = image.getHeight(); - - // 设置画布大小为图片大小 - drawingArea.setPreferredSize(new Dimension(imgWidth, imgHeight)); - drawingArea.revalidate(); - drawingArea.repaint(); - - // 如果需要缩放图片适应画布(可选) - int canvasWidth = drawingArea.getWidth(); - int canvasHeight = drawingArea.getHeight(); - if (canvasWidth > 0 && canvasHeight > 0) { - // 按比例缩放图片 - Image scaledImage = image.getScaledInstance(canvasWidth, canvasHeight, Image.SCALE_SMOOTH); - BufferedImage resizedImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = resizedImage.createGraphics(); - g2d.drawImage(scaledImage, 0, 0, null); - g2d.dispose(); - image = resizedImage; - } - - // 更新画布显示图片 - index = 0; - currentChoice = 0; - drawingArea.createNewGraphics(); - itemList[index].image = image; - itemList[index].board = drawingArea; - drawingArea.repaint(); - index++; - currentChoice = 3; - drawingArea.createNewGraphics(); - ColorChanger colorChanger=new ColorChanger(drawingArea); - colorChanger.processImage(image); -} catch (IOException e) { - e.printStackTrace(); -} - * */ - BufferedImage image; - - //添加窗口缩放 - - HBox zoom = new HBox(10); - zoom.setAlignment(Pos.CENTER); - Slider zoomLvl = new Slider(); - zoomLvl.setMax(4); - zoomLvl.setMin(1); - zoomLvl.setMaxWidth(200); - zoomLvl.setMinWidth(200); - javafx.scene.control.Label hint = new javafx.scene.control.Label("缩放程度"); - javafx.scene.control.Label value = new Label("1.0"); - zoom.getChildren().addAll(hint, zoomLvl, value); - - offSetX = width / 2; - offSetY = height / 2; - try { index = 0; currentChoice = 0; - image = ImageIO.read(fileName); + BufferedImage image = ImageIO.read(fileName); + if (image == null) { + JOptionPane.showMessageDialog(Start.wds, "无法读取图片!"); + return; + } + + // 获取图片原始尺寸 + int imgWidth = image.getWidth(); + int imgHeight = image.getHeight(); + + // 设置画布大小为图片大小 + drawingArea.setPreferredSize(new Dimension(imgWidth, imgHeight)); + drawingArea.revalidate(); + drawingArea.repaint(); + + // 如果需要缩放图片适应画布(可选) + int canvasWidth = drawingArea.getWidth(); + int canvasHeight = drawingArea.getHeight(); + if (canvasWidth > 0 && canvasHeight > 0) { + // 按比例缩放图片 + Image scaledImage = image.getScaledInstance(canvasWidth, canvasHeight, Image.SCALE_SMOOTH); + BufferedImage resizedImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = resizedImage.createGraphics(); + g2d.drawImage(scaledImage, 0, 0, null); + g2d.dispose(); + image = resizedImage; + } + + // 更新画布显示图片 drawingArea.createNewGraphics(); itemList[index].image = image; itemList[index].board = drawingArea; @@ -292,9 +249,7 @@ void openFile() { } catch (IOException e) { e.printStackTrace(); } - } - private JFileChooser getjFileChooser() { // 文件选择器 JFileChooser fileChooser = new JFileChooser(); @@ -413,4 +368,4 @@ public String getDescription() { } -} +} \ No newline at end of file diff --git a/src/Codes/tools/MyZoom.java b/src/Codes/tools/MyZoom.java new file mode 100644 index 0000000..56ba3de --- /dev/null +++ b/src/Codes/tools/MyZoom.java @@ -0,0 +1,95 @@ +package Codes.tools; + +import Codes.tools.DrawPanel; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.util.Hashtable; + +public class MyZoom extends JPanel { + + private double zoomLevel = 1.0; // 当前缩放比例 + private DrawPanel drawingArea; // 绘图区域 + private JSlider zoomSlider; // 缩放滑动条 + private JLabel zoomValueLabel; // 显示缩放值的标签 + + public MyZoom(DrawPanel drawingArea) { + this.drawingArea = drawingArea; + initComponents(); + } + + private void initComponents() { + // 设置布局 + setLayout(new FlowLayout(FlowLayout.CENTER, 10, 5)); + + // 创建缩放滑动条 + zoomSlider = new JSlider(JSlider.HORIZONTAL, 10, 40, 10); // 最小值 10,最大值 40,初始值 10 + zoomSlider.setMajorTickSpacing(10); // 大刻度间隔 + zoomSlider.setMinorTickSpacing(1); // 小刻度间隔 + zoomSlider.setPaintTicks(false); // 显示刻度 + zoomSlider.setPaintLabels(false); // 显示刻度标签 + zoomSlider.setPreferredSize(new Dimension(200, 50)); // 设置滑动条大小 + + // 自定义刻度标签 + Hashtable labelTable = new Hashtable<>(); + for (int i = 10; i <= 40; i += 1) { + labelTable.put(i, new JLabel(String.format("%.1f", i / 10.0))); + } + zoomSlider.setLabelTable(labelTable); + + // 创建缩放值标签 + zoomValueLabel = new JLabel("1.0"); + zoomValueLabel.setFont(new Font("宋体", Font.PLAIN, 14)); + + // 添加滑动条和标签到面板 + add(new JLabel("缩放程度:")); + add(zoomSlider); + add(zoomValueLabel); + + // 添加滑动条值变化监听器 + zoomSlider.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + // 获取滑动条的值 + int sliderValue = zoomSlider.getValue(); + zoomLevel = sliderValue / 10.0; // 将整数值转换为小数值 + + // 更新缩放值标签 + zoomValueLabel.setText(String.format("%.1f", zoomLevel)); + + // 更新绘图区域的缩放比例 + updateZoom(); + } + }); + } + + private void updateZoom() { + // 获取绘图区域的大小 + int width = drawingArea.getWidth(); + int height = drawingArea.getHeight(); + + // 计算缩放后的偏移量 + double offSetX = width / 2; + double offSetY = height / 2; + + // 调整偏移量以保持缩放中心 + if (offSetX < (width / zoomLevel) / 2) { + offSetX = (width / zoomLevel) / 2; + } + if (offSetX > width - ((width / zoomLevel) / 2)) { + offSetX = width - ((width / zoomLevel) / 2); + } + if (offSetY < (height / zoomLevel) / 2) { + offSetY = (height / zoomLevel) / 2; + } + if (offSetY > height - ((height / zoomLevel) / 2)) { + offSetY = height - ((height / zoomLevel) / 2); + } + + // 更新绘图区域的缩放比例 + drawingArea.setZoomLevel(zoomLevel); + drawingArea.repaint(); // 重新绘制绘图区域 + } +} \ No newline at end of file diff --git a/src/image/pencil2.png b/src/image/pencil2.png index 8fe40f3..0f57a74 100644 Binary files a/src/image/pencil2.png and b/src/image/pencil2.png differ diff --git a/src/image/themeicon.png b/src/image/themeicon.png index 1b32b74..ba3231a 100644 Binary files a/src/image/themeicon.png and b/src/image/themeicon.png differ