布尔值不保持值



我有一个应用程序,用户可以在其中绘制线条。有一个JButton btnClear,当用户单击时,它必须清除图形,以便用户可以重新绘制。我在btnClear上使用ActionListener来了解它何时被点击。我设置了一个布尔值Clear,以便在paintComponent()中执行正确的IF语句。然而,布尔型Clear在paintComponent()中保留了一个False值,尽管我在重新绘制()之前将其设置为True。为什么会这样?

注意:我尝试将框架的背景设置为红色,只是为了测试paintComponent()中的布尔值。

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;
public class Clipping extends JPanel implements MouseListener, ActionListener
{
    static JFrame frame;
    static JComboBox cboDraw;
    static JButton btnClear;
    static JButton btnClip;
    double x1, y1, x2, y2;
    boolean FirstPoint;
    boolean Clear = false;
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() 
            {
                CreateFrame();
            }
        });
    }
    private static void CreateFrame()
    {
        frame = new JFrame("Clipping");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Clipping());
        frame.setSize(500,500);
        frame.setVisible(true);
    }
    public Clipping()
    {
        setLayout(new BorderLayout());
        JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
        PopulateToolBar(toolbar);
        add(toolbar, BorderLayout.WEST);
        addMouseListener(this);
        cboDraw.addMouseListener(this);
        btnClip.addActionListener(this);
        btnClear.addActionListener(this);
    }
    private static void PopulateToolBar(JToolBar toolbar)
    {
        String[] cboList = {"Line", "Polygon"};
        cboDraw = new JComboBox(cboList);
        cboDraw.setMaximumSize(new Dimension(70,30));
        btnClip = new JButton("Set clip area");
        btnClear = new JButton("Clear");
        toolbar.add(cboDraw);
        toolbar.addSeparator();
        toolbar.add(btnClip);
        toolbar.addSeparator();
        toolbar.add(btnClear);
        cboDraw.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnClip.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnClear.setAlignmentX(Component.CENTER_ALIGNMENT);
        toolbar.setMargin(new Insets(10,10,10,10));
        toolbar.setFloatable(false);
        toolbar.setBackground(Color.black);
    }
    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        if (cboDraw.getSelectedIndex() == 0) //draw line
        {
            g2.draw(new Line2D.Double(x1, y1, x2, y2));
        }
        else if (Clear == true)
        {
            frame.setBackground(Color.red); //ONLY FOR TESTING PURPOSE
        }
    }
    public void mousePressed(MouseEvent e)
    {
        if (e.getSource() != cboDraw) //to prevent line coordinates from being saved when selecting from combobox
        {
            if (cboDraw.getSelectedIndex() == 0) //user wants to draw line
            {
                if (FirstPoint == false) //first coordinates
                {
                    x1 = e.getX();
                    y1 = e.getY();
                    FirstPoint = true;
                }
                else //second coordinates
                {
                    x2 = e.getX();
                    y2 = e.getY();
                    repaint();
                    FirstPoint = false;
                }
            }
        }
    }
    public void actionPerformed(ActionEvent e) 
    {
        if (e.getSource() == btnClear)
        {
            Clear = true;
            repaint();
            Clear = false;
        }
    }
    public void mouseClicked(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}

您应该只执行setBackground(Color.red);在JPanel上调用它,而不是在JFrame 上调用它

我认为您的actionPerformedmousePressed都是同时执行的。在mousePressed中,如果btnClear()是源,则也满足mousePressed中的if条件。所以无论如何都会调用repaint方法,并且您看不到任何更改。

您没有在paintComponent方法覆盖中调用super.paintComponent(g)方法。先打这个电话,否则,清除是行不通的。

请注意,在当前代码中,这将不适用于您,因为您的绘制不正确,因为您没有指定、迭代并绘制所有需要在paintComponent方法中绘制的线。解决这一问题的方法是通过以下两种方法之一:

  • 创建一个List<Line2D>(如ArrayList<Line2D>),将其填充到MouseListener/MouseMotionListener代码中,然后在paintComponent方法中迭代该List,绘制每一行。如果您这样做,那么清除按钮的操作将是通过clear()清除列表并调用repaint()。不需要布尔值
  • 或者,您可以在BufferedImage上绘制线条,然后通过g.drawImage(...)方法在paintComponent方法中绘制BufferedImage。如果执行此操作,请在绘制之前始终检查图像是否为null。然后在你的鼠标监听代码中,你会画到这张图片上。在清除按钮操作中,您需要创建一个新的BufferedImage,或者清除当前的BufferedImage

还要从paintComponent中去掉setBackground(...)调用,因为它们真的不应该在那里。

例如使用行的ArrayList:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class DrawPanelViaArrayList extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = PREF_W;
   private static final Color LINES_COLOR = Color.black;
   private static final Color DRAW_LINE_COLOR = Color.pink;
   private static final Stroke STROKE = new BasicStroke(3f);
   private List<Line2D> lineList = new ArrayList<>();
   private int x1 = 0;
   private int y1 = 0;
   private int x2 = 0;
   private int y2 = 0;

   public DrawPanelViaArrayList() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
      add(new JButton(new ClearAction("Clear")));
   }
   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      // for smooth graphics
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      // first draw the temporary line to show the user
      // where he's drawing
      if (x1 != x2 && y1 != y2) {
         g2.setColor(DRAW_LINE_COLOR);
         g2.drawLine(x1, y1, x2, y2);
      }
      // then draw all the lines held in the linesList.
      Stroke oldStroke = g2.getStroke();
      g2.setColor(LINES_COLOR);
      g2.setStroke(STROKE); // draw thicker lines
      for (Line2D line2d : lineList) {
         g2.draw(line2d);
      }
      g2.setStroke(oldStroke); // reset stroke
   }
   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }
   private class MyMouseAdapter extends MouseAdapter {
      @Override
      public void mousePressed(MouseEvent e) {
         x1 = e.getPoint().x;
         y1 = e.getPoint().y;
      }
      @Override
      public void mouseReleased(MouseEvent e) {
         x2 = e.getPoint().x;
         y2 = e.getPoint().y; 
         Line2D line = new Line2D.Double(x1, y1, x2, y2);
         // add line to ArrayList
         lineList.add(line);
         x1 = x2 = y1 = y2 = 0;
         repaint();
      }
      @Override
      public void mouseDragged(MouseEvent e) {
         x2 = e.getPoint().x;
         y2 = e.getPoint().y; 
         // draw temporary line
         repaint();
      }
   }
   private class ClearAction extends AbstractAction {
      public ClearAction(String name) {
         super(name);
      }
      @Override
      public void actionPerformed(ActionEvent e) {
         lineList.clear();
         repaint();
      }
   }
   private static void createAndShowGui() {
      JFrame frame = new JFrame("Foo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new DrawPanelViaArrayList());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

见鬼,一个BufferedImage版本的

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class DrawPanelViaBufferedImage extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = PREF_W;
   private static final Color LINES_COLOR = Color.black;
   private static final Color DRAW_LINE_COLOR = Color.pink;
   public static final Color CLEAR_COLOR = new Color(0, 0, 0, 0);
   public static final Stroke STROKE = new BasicStroke(3f);
   private int x1 = 0;
   private int y1 = 0;
   private int x2 = 0;
   private int y2 = 0;
   private BufferedImage img = new BufferedImage(PREF_W, PREF_W, BufferedImage.TYPE_INT_ARGB);

   public DrawPanelViaBufferedImage() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
      add(new JButton(new ClearAction("Clear")));
      // if the GUI is to be re-sizeable, then consider adding a 
      // ComponentListener here, and resizing the BufferedImage in it
   }
   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      // for smooth graphics
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      // first draw the temporary line to show the user
      // where he's drawing
      if (x1 != x2 && y1 != y2) {
         g2.setColor(DRAW_LINE_COLOR);
         g2.drawLine(x1, y1, x2, y2);
      }
      // then draw the BufferedImage if not null
      if (img != null) {
         g2.drawImage(img, 0, 0, null);
      }
   }
   // size of our GUI
   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }
   private class MyMouseAdapter extends MouseAdapter {
      @Override
      public void mousePressed(MouseEvent e) {
         x1 = e.getPoint().x;
         y1 = e.getPoint().y;
      }
      @Override
      public void mouseReleased(MouseEvent e) {
         x2 = e.getPoint().x;
         y2 = e.getPoint().y; 
         Line2D line = new Line2D.Double(x1, y1, x2, y2);
         // draw to the BufferedImage
         Graphics2D g2 = img.createGraphics();
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         g2.setStroke(STROKE);
         g2.setColor(LINES_COLOR);
         g2.draw(line);
         g2.dispose();
         x1 = x2 = y1 = y2 = 0;
         repaint();
      }
      @Override
      public void mouseDragged(MouseEvent e) {
         x2 = e.getPoint().x;
         y2 = e.getPoint().y; 
         repaint();
      }
   }
   private class ClearAction extends AbstractAction {
      public ClearAction(String name) {
         super(name);
      }
      @Override
      public void actionPerformed(ActionEvent e) {
         Graphics2D g2 = img.createGraphics();
         g2.setBackground(CLEAR_COLOR);
         g2.clearRect(0, 0, getWidth(), getHeight());
         g2.dispose();
         repaint();
      }
   }
   private static void createAndShowGui() {
      JFrame frame = new JFrame("Foo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new DrawPanelViaBufferedImage());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

相关内容

  • 没有找到相关文章

最新更新