使用Swing鼠标绘制(单色)数组的最简单方法是什么?

时间:2011-10-03 22:03:38

标签: java arrays swing

我一直在寻找一种在屏幕上绘制黑白阵列的方法。这是一个简单的阵列,只有20x20。我打算用鼠标在数组上绘制,以便每个像素从黑色切换到白色并在单击时返回,然后将数组作为一组布尔(或整数)传递给另一个函数。目前我正在使用Swing。我记得在画布上使用Swing绘图,但我仍然无法找到实际用法。我应该使用画布,还是依靠JToggleButtons?

2 个答案:

答案 0 :(得分:5)

您可以简单地使用JFrame(或其他Swing组件)并覆盖paint(Graphics)方法来绘制布尔矩阵的表示(请注意,在轻量级组件的情况下,例如{{ 1}}你应该覆盖JPanel。这将为你提供所需的点击和拖动功能(使用单个Swing组件的网格很难实现)。

正如其他人所评论的那样,AWT paintComponent(Graphics)并未向您提供Swing组件未提供的任何内容,您将在下面的示例中看到我使用了Canvas方法。 createBufferStrategy以确保无闪烁显示。

smiley face

请注意,我的示例相当简单,因为它会切换您拖动的每个像素而非点击操作,确定您是处于“绘画”模式还是“擦除”模式,然后在此期间专门应用黑色或白色像素阻力。

JFrame

答案 1 :(得分:3)

为什么不在GridLayout(20,20)中保存一个简单的20 x 20网格JPanel,如果通过MouseListener的mousePressed方法单击,则翻转面板的背景颜色。您可以将面板保持在2D阵列中,并在需要时查询其背景颜色。

您也可以使用JLabel,但您必须记住将其不透明属性设置为true。一个JButton也可以工作或者JToggleButton,......这些选项几乎是无限的。我不建议您使用AWT(Canvas),因为他们无需向后退功能,因为Swing处理得非常好。

如果您对此感到困惑,为什么不回来向我们展示您的代码,我们最好能够为您提供更具体的帮助。

解决此问题的另一种方法是使用单个JPanel并覆盖其paintComponent方法。你可以给它一个int [] []数组作为它的模型,然后在paintComponent方法中根据模型的状态绘制任何所需颜色的矩形。然后给它一个MouseListener,它改变模型的状态并调用重绘。

例如,

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

@SuppressWarnings("serial")
public class BlackWhiteGridPanel extends JPanel {
   // can have multiple colors if desired
   // public static final Color[] COLORS = {Color.black, Color.red, Color.blue, Color.white}; 
   public static final Color[] COLORS = {Color.black, Color.white};
   public static final int SIDE = 20;
   private static final int BWG_WIDTH = 400;
   private static final int BWG_HEIGHT = BWG_WIDTH;

   private int[][] model = new int[SIDE][SIDE]; // filled with 0's.

   public BlackWhiteGridPanel() {
      addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent e) {
            myMousePressed(e);
         }
      });
   }

   private void myMousePressed(MouseEvent e) {
      // find relative position of mouse press on grid.
      int i = (e.getX() * SIDE) / getWidth();
      int j = (e.getY() * SIDE) / getHeight();

      int value = model[i][j];
      // the model can only hold states allowed by the COLORS array. 
      // So if only two colors, then value can only be 0 or 1.
      value = (value + 1) % COLORS.length;
      model[i][j] = value;
      repaint();
   }

   public int[][] getModel() {
      // return a copy of model so as not to risk corruption from outside classes 
      int[][] copy = new int[model.length][model[0].length];
      for (int i = 0; i < copy.length; i++) {
         System.arraycopy(model[i], 0, copy[i], 0, model[i].length);
      }
      return copy;
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      int width = getWidth();
      int ht = getHeight();
      for (int i = 0; i < model.length; i++) {
         for (int j = 0; j < model[i].length; j++) {
            Color c = COLORS[model[i][j]];
            g.setColor(c);
            int x = (i * width) / SIDE;
            int y = (j * ht) / SIDE;
            int w = ((i + 1) * width) / SIDE - x;
            int h = ((j + 1) * ht) / SIDE - y;
            g.fillRect(x, y, w, h);
         }
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(BWG_WIDTH, BWG_HEIGHT);
   }

   private static void createAndShowGui() {
      BlackWhiteGridPanel mainPanel = new BlackWhiteGridPanel();

      JFrame frame = new JFrame("BlackWhiteGrid");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}