2014-09-08 6 views
1

У меня есть класс под названием BoardSquare, который является унаследованным классом JButton. Каждый из объектов BoardSquare хранится в массиве BoardSquare[][] boardsquares. Я использовал следующий кодКак сделать эти JLabels JButtons невидимыми

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

добавить метки к каждому из квадратов в массиве в соответствии с их координатами. Мне нужно, чтобы у них были эти ярлыки (я думаю), чтобы я мог их идентифицировать и addActionListeners и т. Д. Как сделать JLabels невидимыми, чтобы они не отображались в моем JFrame?

В качестве альтернативы, как я могу сделать JLabel каждой кнопки переменной экземпляра, чтобы я мог звонить JLabel.setVisible(false), но все еще использую их, когда добавляю слушателей действий?

EDIT: Если кому-то интересно, это для игры с шашками.

Вот мои классы:
GameWindow
BoardSquare
Checker
MyListener

+2

Это звучит как возможный [XY Проблема] (http://mywiki.wooledge.org/XyProblem). Для чего все это используется? Игра MineSweeper? Какое поведение вы хотите, чтобы пользователь ощущал ваш графический интерфейс и этот компонент? Возможно, существует лучший подход к тому, что вы пытаетесь сделать, поэтому давайте попробуем помочь вам найти этот подход. –

+0

Я не понимаю, почему вы хотели бы добавить ярлык, чтобы сделать его неотразимым. Если вы просто хотите добавить actionlisteners, почему бы не просто «BoardSquare.boardSquares [j] [i] .addActionListener (...);'? –

+0

@HovercraftFullOfEels Пожалуйста, см. Мое редактирование. – aidandeno

ответ

0

Вместо добавления нового JLabel() непосредственно в массив, сделайте экземпляр первого затем добавить, что ... я думаю, это делается в петле, например, так:

JLabel lbl; 
for(....) { 
lbl = new JLabel(new JLabel((j+1)+":"+(i+1)); 
lbl.addActionListener(new ActionListener(){ 

public void actionPerformed(ActionEvent evt()){ 
    // TODO here 
    } 
}); 
BoardSquare.boardSquares[j][i].add(lbl); 
3

Благодарим за редактирование. Если бы это была моя заявка, я бы, наверное, делал совсем по-другому, включая:

  • Использовать сетку JLabels, а не JButtons. Я не вижу необходимости использовать JButtons, и проблема в том, что кнопка не будет столь же визуально привлекательной, как другие возможные решения.
  • Либо дать клетки JLabel или содержащий JPanel MouseListener,
  • Have клетки JPanel не имеют значок и, таким образом, быть пустым, если нет проверки не на них,
  • Или им провести ImageIcon из соответствующим образом окрашенного проверки если они не пусты.
  • Вы даже можете анимировать графический интерфейс, используя стеклянную панель, чтобы удерживать JPanel с помощью соответствующей проверки ImageIcon, которую пользователь может перетащить.

Обратите внимание, что если вам абсолютно необходимо использовать JButtons, то не добавляйте к ним JLabels. Вместо этого просто установите для значка JButton значение null или соответствующий контрольный файл 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; 
    } 
} 

Лучше Model-View пример прорабатывается ...

+1

* ".. кнопка не была бы столь же визуально привлекательной, как другие возможные решения." * Что да? Учитывая, что кнопка может быть невидимой, как в графическом интерфейсе шахмат, я не вижу, как кнопка может быть менее красивой, чем отображаемый значок. –

+0

@AndrewThompson: правда, но, возможно, тогда он переходит к одному из них, просто не чувствуя «права» на меня. Ячейка не действует так сильно, как кнопка, но как интерактивное местоположение (снова JLabel будет работать отлично), который содержит иконку и не попадает в депрессию. Возможно, я просто упрям, потому что да, это будет работать как JButton с меняющимися значками (как я добавил к моему ответу, прежде чем увидеть ваш комментарий). Но спасибо за комментарий! –

+0

* ", что пользователь может перетащить." * Arrg .. Как насчет вашей мыши бросали вызов пользователям? Только на другой неделе я оказался без мыши и играл в Solitaire, используя только клавиатуру! –

Смежные вопросы