java - 如何使 JButtons 的这些 JLabels 不可见

标签 java swing jbutton jlabel

我有一个名为 BoardSquare 的类,它是 JButton 的继承类。每个 BoardSquare 对象都存储在数组 BoardSquare[][] boardsquares 中。我使用了以下代码

BoardSquare.boardSquares[j][i].add(new JLabel((j+1)+":"+(i+1)));

根据坐标为数组中的每个正方形添加标签。我需要它们具有这些标签(我认为),以便我可以识别它们和 addActionListeners 等。如何使 JLabel 不可见,这样它们就不会出现在我的 JFrame 中?

或者,如何使每个按钮的 JLabel 成为实例变量,以便我可以调用 JLabel.setVisible(false) 但在添加 Action 监听器时仍然使用它们?

编辑:如果有人感兴趣,这是跳棋游戏。

这是我的类(class):
GameWindow
BoardSquare
Checker
MyListener

最佳答案

感谢您的编辑。如果这是我的应用程序,我可能会做一些非常不同的事情,包括,

  • 使用 JLabel 而非 JButton 的网格。我认为没有必要使用 JButton,但问题是按钮在视觉上不如其他可能的解决方案那么吸引人。
  • 为 JLabel 单元格或包含 JPanel 的 JPanel 提供一个 MouseListener,
  • 让 JPanel 单元格没有图标,因此如果上面没有检查器则为空,
  • 或者如果它们不为空,则让他们持有颜色适当的方格的 ImageIcon。
  • 您甚至可以通过使用玻璃 Pane 来放置 JPanel 以及用户可以拖动的适当检查器 ImageIcon 来制作 GUI 动画。

请注意,如果您绝对必须使用 JButton,则不要向它们添加 JLabel。只需将 JButton 的图标设置为 null 或适当的 Checker ImageIcon。


编辑
例如,作为概念证明的错误代码示例。尝试编译并运行它。

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;

import javax.swing.*;

@SuppressWarnings("serial")
public class Checkers extends JPanel {
   public static final int SIDE_LENGTH = 60;
   public static final int ROW_COUNT = 8;
   private static final String ROW = "row";
   private static final String COLUMN = "column";
   private static final Color LIGHT_COLOR = new Color(210, 180, 140);
   private static final Color DARK_COLOR = new Color(107, 68, 35);
   private Map<Checker, Icon> checkerIconMap = new EnumMap<Checker, Icon>(
         Checker.class);
   private JLabel[][] labelGrid = new JLabel[ROW_COUNT][ROW_COUNT];
   private Checker[][] checkerGrid = new Checker[ROW_COUNT][ROW_COUNT];

   public Checkers() {
      for (Checker checker : Checker.values()) {
         checkerIconMap.put(checker, createCheckerIcon(checker));
      }
      setLayout(new GridLayout(ROW_COUNT, ROW_COUNT));

      for (int row = 0; row < labelGrid.length; row++) {
         for (int col = 0; col < labelGrid[row].length; col++) {
            checkerGrid[row][col] = Checker.EMPTY;
            JLabel gridCell = new JLabel(checkerIconMap.get(Checker.EMPTY));
            gridCell.setOpaque(true);
            gridCell.putClientProperty(ROW, row);
            gridCell.putClientProperty(COLUMN, col);
            Color c = row % 2 == col % 2 ? LIGHT_COLOR : DARK_COLOR;
            gridCell.setBackground(c);
            add(gridCell);
            labelGrid[row][col] = gridCell;
         }
      }

      for (int i = 0; i < labelGrid.length / 2 - 1; i++) {
         for (int j = 0; j < labelGrid.length / 2; j++) {
            int row = i;
            int col = j * 2;
            col += row % 2 == 0 ? 1 : 0;
            labelGrid[row][col].setIcon(checkerIconMap.get(Checker.BLACK));
            checkerGrid[row][col] = Checker.BLACK;

            row = ROW_COUNT - row - 1;
            col = ROW_COUNT - col - 1;
            labelGrid[row][col].setIcon(checkerIconMap.get(Checker.RED));
            checkerGrid[row][col] = Checker.RED;
         }
      }

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   private Icon createCheckerIcon(Checker checker) {
      BufferedImage img = new BufferedImage(SIDE_LENGTH, SIDE_LENGTH,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setColor(checker.getColor());
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      int x = 3;
      int y = x;
      int width = SIDE_LENGTH - 2 * x;
      int height = width;
      g2.fillOval(x, y, width, height);
      g2.dispose();

      return new ImageIcon(img);
   }

   private class MyMouseAdapter extends MouseAdapter {
      private int selectedRow = -1;
      private int selectedCol = -1;
      private Checker selectedChecker = null;
      private JPanel glassPane = null;
      private Point p = null;
      private JLabel movingLabel = new JLabel(checkerIconMap.get(Checker.EMPTY));

      public MyMouseAdapter() {
         movingLabel.setSize(movingLabel.getPreferredSize());
         movingLabel.setVisible(false);
      }

      @Override
      public void mousePressed(MouseEvent e) {
         p = e.getPoint();
         for (int row = 0; row < labelGrid.length; row++) {
            for (int col = 0; col < labelGrid[row].length; col++) {
               JLabel gridCell = labelGrid[row][col];
               if (gridCell == getComponentAt(p)) {
                  if (checkerGrid[row][col] != Checker.EMPTY) {
                     selectedRow = row;
                     selectedCol = col;
                     selectedChecker = checkerGrid[row][col];
                     checkerGrid[row][col] = Checker.EMPTY;
                     labelGrid[row][col].setIcon(checkerIconMap.get(Checker.EMPTY));

                     JRootPane rootPane = SwingUtilities.getRootPane(Checkers.this);
                     glassPane = (JPanel) rootPane.getGlassPane();
                     glassPane.setVisible(true);
                     glassPane.setLayout(null);
                     movingLabel.setIcon(checkerIconMap.get(selectedChecker));
                     movingLabel.setVisible(true);
                     glassPane.add(movingLabel);
                     int x = p.x - SIDE_LENGTH / 2;
                     int y = p.y - SIDE_LENGTH / 2;
                     movingLabel.setLocation(x, y);
                  }
               }
            }
         }
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (selectedChecker == null) {
            return;
         }

         p = e.getPoint();
         if (!Checkers.this.contains(p)) {
            // if mouse releases and is totally off of the grid
            returnCheckerToOriginalCell();
            clearGlassPane();
            return;
         }

         for (int row = 0; row < labelGrid.length; row++) {
            for (int col = 0; col < labelGrid[row].length; col++) {
               JLabel gridCell = labelGrid[row][col];
               if (gridCell == getComponentAt(p)) {
                  if (isMoveLegal(row, col)) {
                     checkerGrid[row][col] = selectedChecker;
                     labelGrid[row][col].setIcon(checkerIconMap.get(selectedChecker));

                     // todo: check for jumped pieces...
                  } else {
                     // illegal move
                     returnCheckerToOriginalCell();
                  }
               }
            }
         }
         clearGlassPane();
      }

      // this code would go in the model class
      private boolean isMoveLegal(int row, int col) {
         if (checkerGrid[row][col] != Checker.EMPTY) {
            // trying to put a checker on another checker
            returnCheckerToOriginalCell();
         } else if (row == selectedRow && col == selectedCol) {
            // trying to put checker back in same position
            returnCheckerToOriginalCell();
         } else if (row % 2 == col % 2) {
            // invalid square
            returnCheckerToOriginalCell();
         } else {
            // TODO: more logic needs to go here to test for a legal move
            // and to remove jumped pieces

            return true;
         }
         return false;
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (selectedChecker == null || p == null) {
            return;
         }
         p = e.getPoint();
         int x = p.x - SIDE_LENGTH / 2;
         int y = p.y - SIDE_LENGTH / 2;
         movingLabel.setLocation(x, y);
      }

      private void clearGlassPane() {
         glassPane.setVisible(false);
         movingLabel.setVisible(false);
         selectedChecker = null;
         p = null;
         selectedCol = -1;
         selectedRow = -1;
      }

      private void returnCheckerToOriginalCell() {
         checkerGrid[selectedRow][selectedCol] = selectedChecker;
         labelGrid[selectedRow][selectedCol].setIcon(checkerIconMap.get(selectedChecker));
      }
   }

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

      JFrame frame = new JFrame("JLabelGrid");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
         }
      });
   }
}

class CheckerModel {

}

enum Checker {
   EMPTY(new Color(0, 0, 0, 0)), RED(Color.red), BLACK(Color.black);
   private Color color;

   private Checker(Color color) {
      this.color = color;
   }

   public Color getColor() {
      return color;
   }
}

正在开发更好的模型- View 示例...

关于java - 如何使 JButtons 的这些 JLabels 不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25725085/

相关文章:

java - Jython 和 Java 嵌套类

java - 如何将一个xml导入到另一个xml中?

java - 每次单击 JButton 时如何将值增加 1?

java - JButton 被工具提示文本渲染为不可点击

java - 如何在文本字段中包含 'some' 文本时禁用按钮,并在该文本在文本字段中消失时重新启用它们

java - 在布局底部创建一个三角形

java - 从使用 AJAX 的网页获取 HTML

Java - 设置装饰 JFrame 的大小

java - Java Swing 的 UTF-8 支持问题?

java - 在 Swing 应用程序中扩展系统外观