【问题标题】:Drawing program duplicates JMenuBar绘图程序重复 JMenuBar
【发布时间】:2012-12-10 17:25:31
【问题描述】:

我用 Java 编写了一个简单的绘图程序,它允许用户在不同的形状、大小和颜色之间进行选择(在 JMenuBar 中)并用鼠标绘制它们。在克服了程序的许多问题之后(我最初在AWT 中编写它,但被说服切换到 Swing,所以请原谅任何糟糕的Swing 编码,因为这是我第一次使用它),我有一个问题留待解决。每当用户在屏幕上绘制一些东西时(默认情况下是一个带有黑色边框的红色矩形),JMenuBar 会在原始JMenuBar 的正下方复制。我认为paintComponent 缓冲屏幕的方式有些奇怪,但由于我以前从未使用过它,所以我不知道它是如何工作的。

有什么办法可以让它停止复制JMenuBar吗?

import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import javax.swing.*;

public class E3G04 extends JFrame implements WindowListener, ActionListener, MouseListener, MouseMotionListener
{
    //Variables are declared as volatile to ensure that they're always called from system RAM
    static volatile String type = "rectangle";
    static volatile Boolean fill = true;
    static Color lineColor = Color.BLACK;
    static Color fillColor = Color.RED;
    static int size = 1;

    CanvasEX cx = new CanvasEX();

    static boolean running = true;

    JMenuBar mb = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
            JMenuItem newItem = new JMenuItem("New");
            JMenuItem quitItem = new JMenuItem ("Quit");


    protected E3G04()
    {

        mb.add(fileMenu);
        fileMenu.add(newItem);
        fileMenu.add(quitItem);             
        newItem.setMnemonic('N');
        quitItem.setMnemonic('Q');
        newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
        quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));          
        newItem.addActionListener(this);
        quitItem.addActionListener(this);
        cx.setSize(800,600);
        cx.addMouseListener(this);
        cx.addMouseMotionListener(this);
        setJMenuBar(mb);
        setBounds(100,100,800,600);
        setLayout(new BorderLayout());
        add("Center",cx);
        addWindowListener(this);
        setResizable(true);
        setVisible(true);
    }

    public static void main(String [] args)
    {
        new E3G04();
    }


    public void stop()
    {
        newItem.removeActionListener(this);
        quitItem.removeActionListener(this);    
        dispose();
        System.exit(0);
    }

    public void actionPerformed(ActionEvent e)
    {
        Object o = e.getSource();

        if (o == newItem)
        {
            cx.erase = true;
            cx.repaint();
        }

        if (o == quitItem)
        {   
            running = false;
            stop();
        }

    }      

    public void mousePressed(MouseEvent m)
    {
        cx.start = m.getPoint();
        cx.end = cx.start;
        cx.cur = cx.start;
    }

    public void mouseDragged(MouseEvent m)
    {
        cx.cur = m.getPoint();
    }   

    public void mouseReleased(MouseEvent m)
    {
        cx.end = cx.cur;
        cx.repaint();
    }   
    public void itemStateChanged(ItemEvent e)
    {
        Object o = e.getSource();

    }
    public void windowClosing(WindowEvent e)
    {
        running = false;
        stop();
    }
    public void mouseClicked(MouseEvent m){}    
    public void mouseExited(MouseEvent m){}
    public void mouseEntered(MouseEvent m){}    
    public void mouseMoved(MouseEvent m){}
    public void windowClosed(WindowEvent e){}
    public void windowOpened(WindowEvent e){}
    public void windowActivated(WindowEvent e){}
    public void windowDeactivated(WindowEvent e){}
    public void windowIconified(WindowEvent e){}
    public void windowDeiconified(WindowEvent e){}
}


class CanvasEX extends JPanel
{
    Point start = new Point(100,100);
    Point cur = new Point(100,100);
    Point end = new Point(100,100);
    boolean erase = false;



    public void paintComponent(Graphics g)
    {

        Graphics buffer = g;
        if (erase)
        {
            g.dispose();
            erase = false;
        }   
        g.setColor(E3G04.lineColor);
        if (end.x > start.x && end.y > start.y)
            g.fillRect(start.x,start.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y));
        if (end.x > start.x && end.y < start.y)
            g.fillRect(start.x,end.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y));  
        if (end.x < start.x && end.y > start.y)
            g.fillRect(end.x, start.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y));
        if (end.x < start.x && end.y < start.y)
            g.fillRect(end.x, end.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y));
        g.setColor(E3G04.fillColor);
        if (end.x > start.x && end.y > start.y)
            g.fillRect(start.x + E3G04.size,start.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size);
        if (end.x > start.x && end.y < start.y)
            g.fillRect(start.x + E3G04.size,end.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size);  
        if (end.x < start.x && end.y > start.y)
            g.fillRect(end.x + E3G04.size, start.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size);
        if (end.x < start.x && end.y < start.y)
            g.fillRect(end.x + E3G04.size, end.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size);          
    }
}

【问题讨论】:

    标签: java swing jframe paintcomponent jmenubar


    【解决方案1】:

    通过在覆盖的paintComponent(..) 方法中调用super.paintComponent(Graphics g),您不尊重绘制链(您应该这样做):

    @Override
    public void paintComponent(Graphics g)
    {
         super.paintComponent(g);
    
        //do rest of painting etc
    }  
    

    【讨论】:

    • 好的,这解决了菜单栏存在的问题,但现在我的绘图不再持久。我该如何解决?
    • 你需要像ArrayList这样的东西,它将保存所有要绘制的Rectanlges,在paintComponent中,你将遍历数组列表并重绘每个Rectangle,因此绘图将持续存在
    • 虽然不是所有的矩形。有没有一种方法可以创建屏幕图像(减去 JMenubar),然后将该图像重新绘制到屏幕上?
    • @AlexKibler 我相信你可以,但这不是正确的方法,你只需要有更多的数组列表来保存所有对象或使用泛型(每个类都将扩展一个具有基础的实体类像 x,y 位置宽度高度等),因此可以将不同的对象添加到同一个列表中。这是持久矩形的一个小例子:stackoverflow.com/questions/13358658/…
    • 哦,好吧,那我就这么做。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多