-1

我正在制作一个类似于 MS Paint 的简单程序。我创建了一个空白的自定义图像作为我的“画布”。但是,每当我放大窗口时,图像都会保持相同的大小。当我调整窗口大小时,如何才能使图像适合?

我的代码是:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ScribblePad extends JFrame {

    // Setting GUI variables...

    public static int WIDTH = 800;
    public static int HEIGHT = 800;

    public static int X = 10;
    public static int Y = 10;

    public static String TITLE = "ScribblePad";

    // Create GUI components...

    PaintPanel paintPanel = new PaintPanel();

    JPanel buttonPanel = new JPanel();

    Container mainContainer = getContentPane();

    JButton clearButton = new JButton("Clear");

    JButton buttonBlack = new JButton();
    JButton buttonRed = new JButton();
    JButton buttonBlue = new JButton();
    JButton buttonYellow = new JButton();
    JButton buttonGreen = new JButton();

    Cursor crosshairCursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);

    // Run the entire program...

    public static void main(String []args) {

        new ScribblePad();

    }

    // Create ScribblePad constructor...

    public ScribblePad() {

        // Setting JFrame properties...

        super(TITLE);

        setVisible(true);

        setSize(WIDTH, HEIGHT);
        setLocation(X, Y);      

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // Setting properties of other components...

        paintPanel.setCursor(crosshairCursor);

        buttonPanel.setBackground(Color.WHITE);

        buttonPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));

        // Adding the components...

        mainContainer.add(paintPanel, BorderLayout.CENTER);

        mainContainer.add(buttonPanel, BorderLayout.NORTH);

        // Adding ActionListeners and setting properties of the buttons..

        buttonBlack.setBackground(Color.BLACK);
        buttonBlack.setForeground(Color.BLACK);
        buttonBlack.setPreferredSize(new Dimension(32, 32));

        buttonRed.setBackground(Color.RED);
        buttonRed.setForeground(Color.RED);
        buttonRed.setPreferredSize(new Dimension(32, 32));

        buttonGreen.setBackground(Color.GREEN);
        buttonGreen.setForeground(Color.GREEN);
        buttonGreen.setPreferredSize(new Dimension(32, 32));

        buttonBlue.setBackground(Color.BLUE);
        buttonBlue.setForeground(Color.BLUE);
        buttonBlue.setPreferredSize(new Dimension(32, 32));

        buttonYellow.setBackground(Color.YELLOW);
        buttonYellow.setForeground(Color.YELLOW);
        buttonYellow.setPreferredSize(new Dimension(32, 32));

        clearButton.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.clearCanvas();

            }

        });

        buttonBlack.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.setBlack();

            }

        });

        buttonGreen.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.setGreen();


            }

        });

        buttonRed.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.setRed();

            }

        });

        buttonYellow.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.setYellow();

            }

        });

        buttonBlue.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e){

                paintPanel.setBlue();

            }

        });

        // Adding buttons to the buttonPanel...

        buttonPanel.add(buttonBlack);
        buttonPanel.add(buttonRed);
        buttonPanel.add(buttonGreen);
        buttonPanel.add(buttonBlue);
        buttonPanel.add(buttonYellow);

        buttonPanel.add(clearButton);

    }

    public class PaintPanel extends JComponent {

        Image blankCanvas;

        Graphics2D g2D;

        int mouseX, mouseY, oldX, oldY;

        String currentColour = "BLACK";

        public PaintPanel() {

            setDoubleBuffered(true);

            addMouseListener(new MouseAdapter() {

                public void mousePressed(MouseEvent e) {

                    oldX = e.getX();
                    oldY = e.getY();

                    g2D.drawOval(oldX, oldY, 1, 1);

                    System.out.println("[Debug] Point drawn at (" + oldX + ", " + oldY + ").");

                    repaint();

                }

            });

            addMouseMotionListener(new MouseMotionAdapter(){

                public void mouseDragged(MouseEvent e){

                    mouseX = e.getX();
                    mouseY = e.getY();

                    if(g2D != null)

                    g2D.drawLine(oldX, oldY, mouseX, mouseY);

                    repaint();

                    System.out.println("[Debug] Line drawn from (" + oldX + ", " + oldY + ") to (" + mouseX + ", " + mouseY + ").");

                    oldX = mouseX;
                    oldY = mouseY;

                }

            });

        }

        public void paintComponent(Graphics g) {

            if (blankCanvas == null) {

                blankCanvas = this.createImage(getWidth(), getHeight());

                g2D = (Graphics2D)blankCanvas.getGraphics();

                g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                clearCanvas();

            }

            g.drawImage(blankCanvas, 0, 0, null);   

        }

        public void clearCanvas() {

            g2D.setPaint(Color.WHITE);
            g2D.fillRect(0, 0, getSize().width, getSize().height);

            switch(currentColour) {

            case "BLACK": g2D.setColor(Color.BLACK); break;

            case "RED": g2D.setColor(Color.RED); break;

            case "GREEN": g2D.setColor(Color.GREEN); break;

            case "BLUE": g2D.setColor(Color.BLUE); break;

            case "YELLOW": g2D.setColor(Color.YELLOW); break;

            }

            System.out.println("[Debug] Canvas cleared.");

            repaint();

        }

        public void setBlack() {

            g2D.setColor(Color.BLACK);

            System.out.println("[Debug] Colour changed to black.");

            currentColour = "BLACK";

        }

        public void setRed() {

            g2D.setColor(Color.RED);

            System.out.println("[Debug] Colour changed to red.");

            currentColour = "RED";

        }

        public void setBlue() {

            g2D.setColor(Color.BLUE);

            System.out.println("[Debug] Colour changed to blue.");

            currentColour = "BLUE";

        }

        public void setYellow() {

            g2D.setColor(Color.YELLOW);

            System.out.println("[Debug] Colour changed to yellow.");

            currentColour = "YELLOW";

        }

        public void setGreen() {

            g2D.setColor(Color.GREEN);

            System.out.println("[Debug] Colour changed to green.");

            currentColour = "GREEN";

        }

    }

}
4

3 回答 3

1

我不知道您的问题是关于缩放现有图像,还是随着帧大小的变化而使绘画区域变大/变小。

缩放是一个问题,因为一旦调整图像大小,您将始终需要重新缩放鼠标点以将它们恢复到原始坐标系。

所以改变绘画区域更容易,但是如果你使用一个Image,那么当你缩小窗口大小时会发生什么?您是否截断任何现有的画作?

出于这个原因,我建议您直接在组件上绘制并使用 List 来跟踪各个椭圆。这种调整大小的方式不会影响椭圆的绘制。将改变的只是随时可见的东西。

查看自定义绘画方法以获取此方法的示例。这个例子展示了如何使用不同的颜色而不用硬编码特定的方法来设置颜色。

由于这是一个让我开始使用paintComponent 的小项目,我想简单地截断该区域。

对于一个简单的解决方案,只需将图像设置为屏幕大小。然后,您不必担心每次调整框架大小时都会截断/拉伸。

否则,您需要ComponentListener在面板中添加一个并监听 componentResized() 事件。然后您需要创建一个新图像并将旧图像绘制到新图像上。您应该注意,对于调整面板大小的每个像素都会生成一个 componentResized() 事件,因此这将涉及大量后台工作。

于 2013-11-06T18:56:55.273 回答
0

要查找 Windows 的当前高度和宽度,请尝试此代码

Toolkit toolkit =  Toolkit.getDefaultToolkit ();
Dimension dim = toolkit.getScreenSize();
int width = dim.getWidth();
int height = dim.getHeight();

现在使用 Graphics 类的缩放函数 scale(int x, int y),当窗口大小发生变化时,此方法会重复快速连续调用,使用上述代码检查。

最好尝试阅读https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html

于 2013-11-06T18:52:57.187 回答
0

在您的 paintComponent 方法中使用 g2d.scale(x, y)。您需要获取当前高度和宽度并将其与之前的高度和宽度进行比较以确定比例因子。设置它,以便当屏幕处于默认大小时,您的比例因子为 0。

您需要一个窗口侦听器来计算 componentResized() 事件的比例因子。像 scaleX = getWidth() / WIDTH;

于 2013-11-06T18:37:26.223 回答