繁体   English   中英

这是一个简单的绘图板。 为什么在鼠标事件期间调用 UpdateUI() 时按钮出现在角落? 我如何解决它?

[英]Here is a simple drawing pad. Why do the buttons appear in the corner when the UpdateUI() is called during a mouseevent? How do I fix it?

如果我在调用 repaint() 时按下按钮笔/橡皮擦,它会在顶角创建按钮的图像。 为什么会这样? 如何防止这些按钮图像出现?

我试图将框架和许多其他东西分层,但我似乎无法弄清楚。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JPanel implements MouseListener, MouseMotionListener {
    private int lineThickness = 10;
    private int xMousePos, yMousePos;
    private boolean isPressed = true;
    private static JLayeredPane layered;
    private static JToolBar toolBar;
    private static JToggleButton pen, eraser, color;
    private static Main screen;
    private static JFrame app, toolWindow;
    private static Color drawColor;
    private static int i=0;
    public Main() {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(drawColor);
        g.fillRect(xMousePos, yMousePos, lineThickness, lineThickness);
    }

    public static void main(String[] args) {
        screen = new Main();
        screen.setBounds(0, 0, 20, 20);
        app = new JFrame("Drawing-Pad");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(2, 1));
        panel.setFocusable(false);
        panel.setBounds(0, 0, 600, 60);
        panel.setBackground(Color.RED);

        app.setBackground(Color.WHITE);
        app.add(panel);
        app.add(screen);
        app.setVisible(true);
        app.setBounds(0, 0, 600, 400);


        pen = new JToggleButton("Pen");
        eraser = new JToggleButton("Eraser");
        toolBar = new JToolBar();
        toolBar.add(pen);
        toolBar.add(eraser);
        panel.add(toolBar);

        pen.addActionListener(e->{
            ++i;
            eraser.setSelected(false);
            drawColor = Color.BLACK;
        });

        eraser.addActionListener(e->{
            ++i;
            pen.setSelected(false);
            drawColor = Color.WHITE;
        });
    }



    @Override
    public void mouseClicked(MouseEvent e) {
        //isPressed = false;
    }

    @Override
    public void mousePressed(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
        if(e.getY()>60 && i == 0) updateUI();
        i=0;
    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
        if(e.getY()>60 && i == 0) updateUI();
        i=0;
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        xMousePos = e.getX();
        yMousePos = e.getY();
    }
}

我不知道为什么会这样,请帮忙。

Oracle 有一个有用的教程,使用 Swing 创建 GUI 跳过学习 Swing 和 NetBeans IDE 部分。

我修改了您的代码并创建了以下 GUI。

画板

我用一个JToggleButton JToggleButtons 这样,state 要么绘制,要么擦除。

我创建了一个绘图JPanel 在 Swing 中,每次重新绘制JPanel时,绘图JPanel都会被完全擦除。 这意味着每次调用JPanel重绘时都必须重绘整个图像。

我将您的整体main方法分解为几个方法和类。 这有助于保持代码的组织性,并使代码更易于阅读、理解,更重要的是,便于调试。

任何 Swing 应用程序的第一行都是对SwingUtilities invokeLater方法的调用。 此方法确保 Swing 组件在Event Dispatch Thread上创建和执行。

我使用Swing 布局管理器来创建 GUI。 JFrame 使用默认的BorderLayout 绘图JPanel具有首选大小。

我创建了一个应用程序 model 来保存所有绘图点。 我保留了这些绘图点的java.util.List ,这样每次我重新绘制绘图JPanel时,我都可以重新绘制整个图像。

我使用了MouseAdapter ,所以我只需要编写我实际需要的MouseListenerMouseMotionListener方法。

这是完整的可运行代码。 我制作了额外的类内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

public class SimpleDrawingPad implements Runnable {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleDrawingPad());
    }
    
    private final DrawingPanel drawingPanel;
    
    private final SimpleDrawingModel model;
    
    public SimpleDrawingPad() {
        this.model = new SimpleDrawingModel();
        this.drawingPanel = new DrawingPanel(this, model);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Drawing Pad");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createToolBar(), BorderLayout.NORTH);
        frame.add(drawingPanel, BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JToolBar createToolBar() {
        JToolBar toolBar = new JToolBar();
        toolBar.setRollover(true);
        
        JToggleButton button = new JToggleButton(" Draw ");
        button.addActionListener(event -> {
            if (button.isSelected()) {
                button.setText("Erase");
                model.setDrawingColor(Color.WHITE);
            } else {
                button.setText(" Draw ");
                model.setDrawingColor(Color.BLACK);
            }
        });
        toolBar.add(button);
        
        return toolBar;
    }
    
    public void repaint() {
        drawingPanel.repaint();
    }
    
    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private final SimpleDrawingModel model;
        
        public DrawingPanel(SimpleDrawingPad view, SimpleDrawingModel model) {
            this.model = model;
            this.setBackground(Color.WHITE);
            this.setPreferredSize(new Dimension(640, 480));
            
            DrawingListener listener = new DrawingListener(view, model);
            this.addMouseListener(listener);
            this.addMouseMotionListener(listener);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            for (DrawingPoint drawingPoint : model.getDrawingPoints()) {
                g.setColor(drawingPoint.getDrawingColor());
                Point point = drawingPoint.getDrawingPoint();
                int lineThickness = drawingPoint.getLineThickness();
                g.fillRect(point.x, point.y, lineThickness, lineThickness);
            }
        }
        
    }
    
    public class DrawingListener extends MouseAdapter {
        
        private final SimpleDrawingPad view;
        
        private final SimpleDrawingModel model;
        
        public DrawingListener(SimpleDrawingPad view,
                SimpleDrawingModel model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void mousePressed(MouseEvent event) {
            DrawingPoint drawingPoint = new DrawingPoint(event.getPoint(), 
                    model.getDrawingColor(), model.getLineThickness());
            model.addDrawingPoint(drawingPoint);
            view.repaint();
        }
        
        @Override
        public void mouseDragged(MouseEvent event) {
            DrawingPoint drawingPoint = new DrawingPoint(event.getPoint(), 
                    model.getDrawingColor(), model.getLineThickness());
            model.addDrawingPoint(drawingPoint);
            view.repaint();
        }
        
    }
    
    public class SimpleDrawingModel {
        
        private int lineThickness;
        
        private Color drawingColor;
        
        private List<DrawingPoint> drawingPoints;
        
        public SimpleDrawingModel() {
            this.lineThickness = 10;
            this.drawingColor = Color.BLACK;
            this.drawingPoints = new ArrayList<>();
        }

        public int getLineThickness() {
            return lineThickness;
        }

        public void setLineThickness(int lineThickness) {
            this.lineThickness = lineThickness;
        }

        public Color getDrawingColor() {
            return drawingColor;
        }

        public void setDrawingColor(Color drawingColor) {
            this.drawingColor = drawingColor;
        }

        public List<DrawingPoint> getDrawingPoints() {
            return drawingPoints;
        }

        public void addDrawingPoint(DrawingPoint drawingPoint) {
            this.drawingPoints.add(drawingPoint);
        }
        
    }
    
    public class DrawingPoint {
        
        private final int lineThickness;
        
        private final Color drawingColor;
        
        private final Point drawingPoint;

        public DrawingPoint(Point drawingPoint, Color drawingColor,
                int lineThickness) {
            this.drawingPoint = drawingPoint;
            this.drawingColor = drawingColor;
            this.lineThickness = lineThickness;
        }

        public int getLineThickness() {
            return lineThickness;
        }

        public Color getDrawingColor() {
            return drawingColor;
        }

        public Point getDrawingPoint() {
            return drawingPoint;
        }
        
    }
    
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM