2013-01-16 4 views
1

SwingGUI으로 사용하여 작은 게임을 작성하고 있는데 문제가 발생했습니다. 스크린 샷을 게시하면 상황을 더 잘 이해할 수 있습니다. 스윙 위치 지정 문제

enter image description here

는 처음에 나는 단지 내가 GridLayout을 사용하는 보드를했다.

그러나 점수를 표시하는 데 패널을 추가해야하므로 GridLayoutGridBagLayout으로 변경했습니다. 나는 점수에 대해 새로운 JPanel을 올바르게 배치하고 결과를 표시하기 위해 2 JTextArea을 추가했습니다.

플레이어가 움직일 때마다 보드가 새로운 상태를 반영하여 다시 그려지는 것이므로 텍스트 영역이 깜박 거리고 보드가 부분적으로 덮어 버립니다 (스크린 샷 참조). 그 문제가 어떤 생각일까요? 모든 구성 요소의 기본 크기를 설정하고 setOpaque을 사용해 보았지만 아무 소용이 없었습니다.

주 레이아웃 홀더의 코드입니다.

패널의
public class BoardLayout extends JFrame implements ModelObserver { 

    /** 
    * {@value} 
    */ 
    private static final long serialVersionUID = 5834762299789973250L; 

    /** 
    * {@value} 
    */ 
    private static final int RESULTS_PANEL_HEIGHT = 100; 

    private final BoardEventsListener eventsListener; 

    private final ResultsLayout resultsLayout; 

    private class CellMouseListener implements MouseListener { 

     private final int cellIndex; 

     public CellMouseListener(final int index) { 
      cellIndex = index; 
     } 

     @Override 
     public void mouseClicked(final MouseEvent event) { 
      eventsListener.onCellSelected(cellIndex); 
     } 

     @Override 
     public void mouseEntered(final MouseEvent event) { 
      // blank 
     } 

     @Override 
     public void mouseExited(final MouseEvent event) { 
      // blank 
     } 

     @Override 
     public void mousePressed(final MouseEvent event) { 
      // blank 
     } 

     @Override 
     public void mouseReleased(final MouseEvent event) { 
      // blank 
     } 

    } 

    public BoardLayout(final BoardEventsListener listener) throws HeadlessException { 
     this(listener, "", null); 
    } 

    public BoardLayout(GraphicsConfiguration graphicsConfiguration) { 
     this(null, "", graphicsConfiguration); 
    } 

    public BoardLayout(final BoardEventsListener listener, String title, 
      GraphicsConfiguration graphicsConfiguration) { 
     super(title, graphicsConfiguration); 

     eventsListener = listener; 

     setLayout(new GridBagLayout()); 
     setBoardSize(); 
     populateCells(); 
     resultsLayout = attachResultsLayout(); 

     resultsLayout.setOpaque(true); 

     setVisible(true); 
    } 

    private ResultsLayout attachResultsLayout() { 
     final ResultsLayout resultsLayout = new ResultsLayout(Game.BOARD_COLUMN_COUNT 
       * BoardCellLayout.WIDTH_BOARD_CELL, RESULTS_PANEL_HEIGHT); 
     final GridBagConstraints constraints = new GridBagConstraints(); 
     constraints.gridwidth = GridBagConstraints.REMAINDER; 
     constraints.gridheight = GridBagConstraints.REMAINDER; 
     constraints.gridx = 0; 
     constraints.gridy = 8; 
     getContentPane().add(resultsLayout, constraints, 64); 
     return resultsLayout; 
    } 

    private void setBoardSize() { 
     final Dimension boardDimension = getBoardDimension(); 
     setMinimumSize(boardDimension); 
     setSize(boardDimension); 
     setResizable(false); 
    } 

    private void populateCells() { 
     final Container container = getContentPane(); 
     for (int i = 0; i < Game.BOARD_ROW_COUNT; ++i) { 
      for (int j = 0; j < Game.BOARD_COLUMN_COUNT; ++j) { 
       final BoardCellLayout currentCell = new BoardCellLayout(); 
       final int cellIndex = i * Game.BOARD_COLUMN_COUNT + j; 
       final GridBagConstraints constraints = new GridBagConstraints(); 
       constraints.gridx = j; 
       constraints.gridy = i; 
       container.add(currentCell, constraints, cellIndex); 
       currentCell.setOpaque(true); 
       currentCell.addMouseListener(new CellMouseListener(cellIndex)); 
      } 
     } 
    } 

    private Dimension getBoardDimension() { 
     final Dimension boardDimension = new Dimension(Game.BOARD_COLUMN_COUNT 
       * BoardCellLayout.WIDTH_BOARD_CELL, (Game.BOARD_ROW_COUNT + 1) 
       * BoardCellLayout.HEIGHT_BOARD_CELL); 
     return boardDimension; 
    } 

    public BoardLayout(String title) throws HeadlessException { 
     this(null, title, null); 
    } 

    @Override 
    public void setVisible(final boolean isVisible) { 
     super.setVisible(isVisible); 
     setBackground(Color.WHITE); 
     pack(); 
    } 

    @Override 
    public void onModelChanged(Collection<Cell> changedCells, final int whiteDiscsCount, 
      final int blackDiscsCount) { 
     for (final Cell cell : changedCells) { 
      final BoardCellLayout boardCell = getCellAt(cell.getIndex()); 
      boardCell.take(cell.getOwner()); 
     } 
     resultsLayout.onResultChanged(whiteDiscsCount, blackDiscsCount); 

    } 

    @Override 
    public void onNextMovesAcquired(Collection<Cell> nextMoves) { 
     clearCellHighlight(); 
     for (final Cell cell : nextMoves) { 
      final BoardCellLayout boardCell = getCellAt(cell.getIndex()); 
      boardCell.highlight(); 
     } 
    } 

    private void clearCellHighlight() { 
     final Container container = getContentPane(); 
     for (int i = 0; i < container.getComponentCount() - 1; ++i) { 
      final BoardCellLayout boardCellLayout = (BoardCellLayout) container.getComponent(i); 
      boardCellLayout.clearHighlight(); 
     } 
    } 

    private BoardCellLayout getCellAt(final int index) { 
     final Container container = getContentPane(); 
     return (BoardCellLayout) container.getComponent(index); 
    } 
} 

코드, 유지하는 결과 : JTextArea에의

public class ResultsLayout extends JPanel { 

    /** 
    * {@value} 
    */ 
    private static final long serialVersionUID = 8379710427718395507L; 

    private final ResultsTextView whiteTextView; 

    private final ResultsTextView blackTextView; 

    public ResultsLayout(final int width, final int height) { 
     super(new GridLayout(2, 1)); 

     setVisible(true); 

     final Dimension dimension = new Dimension(width, height); 
     setMinimumSize(dimension); 
     setPreferredSize(dimension); 
     setSize(dimension); 

     whiteTextView = new ResultsTextView(Player.WHITE); 
     blackTextView = new ResultsTextView(Player.BLACK); 

     add(whiteTextView, 0); 
     add(blackTextView, 1); 
    } 

    public void onResultChanged(final int whiteDiscsCount, final int blackDiscsCount) { 
     whiteTextView.setDiscCount(whiteDiscsCount); 
     blackTextView.setDiscCount(blackDiscsCount); 
    } 

} 

코드, 결과 유지 :

public class ResultsTextView extends JTextArea { 

    /** 
    * {@value} 
    */ 
    private static final long serialVersionUID = -6354085779793155063L; 

    /** 
    * {@value} 
    */ 
    public static final String BACKGROUND_COLOR = "#066f02"; 

    private static final int START_DISCS_NUMBER = 2; 

    private final Player player; 

    public ResultsTextView(final Player player) { 
     super(); 
     setEditable(false); 

     setBackground(Color.decode(BACKGROUND_COLOR)); 

     this.player = player; 
     setText(player.toString() + " result is: " + START_DISCS_NUMBER); 

     final Dimension dimension = new Dimension(100, 20); 
     setPreferredSize(dimension); 
     setMinimumSize(dimension); 
     setMaximumSize(dimension); 
    } 

    public void setDiscCount(final int discCount) { 
     setText(player.toString() + " result is:" + discCount); 
    } 

} 
+0

사용하는 코드는 없지만 유용하지 않은 것은 아닙니다. – MadProgrammer

+0

편집 내 대답 :) 감사합니다! – asenovm

+0

빨리 도움을 받으려면 [SSCCE] (http://sscce.org/)를 게시하십시오. –

답변

1

문제는 내가 GUI를 업데이트 SwingUtilities.invokeLater를 사용하지되었고, 그 깜박임을 일으키는 것이 었습니다. 나는 그것을 사용하기 시작했고 이제는 모두 괜찮습니다. :)

+0

확신 할 수있는 유일한 방법입니다. – trashgod

2

점수 패널을 추가 내게는 MVC 패턴을 생각한다 게임 보드와 점수가 모두 이고같은 게임을 듣는보기. 또한 example에는 디자인과 레이아웃에 대한 통찰력을 제공하는 그리드 기반 게임이있다. 특히 RCStatus보기는 BorderLayout.NORTHRCInfo보기에서 BorderLayout.SOUTH에 각각 RCModel을 수신합니다. 게임 패널은 BorderLayout.CENTER을 차지합니다. 귀하가 제공 한 조각에

몇 가지 참고 사항 :

  • 는 메인 뷰가 JPanel을 확장하고 JFrame 인스턴스에 추가 할 수 있습니다.

  • 단일 레이아웃으로 모든 문제를 해결하려고 시도하지 마십시오.

  • extends MouseAdapterimplements MouseListener 이상으로 생각하십시오.

  • 재검색 setXxxSize().

+2

동의하면, 보드 패널을 하단 패널과 분리하십시오.그들에게 각각의 패널이되도록하십시오; BorderLayout.CENTER'와'BorderLayout.SOUTH'를 사용하여 컨테이너에 추가하고 하단 패널의 적절한 크기를'new Dimension (0, preferredHeight);으로 설정하십시오. – rtheunissen

+0

@ paranoid-android : 좋은 지적; 의견을 주셔서 감사합니다. 인용 된 예제는 그리드를 직접 렌더링합니다. 대안으로,이 [게임] (https://sites.google.com/site/drjohnbmatthews/buttons)은 버튼의'GridLayout'을 사용합니다. – trashgod

+0

감사! 문제가 다른 곳에 있었지만 BorderLayout을 사용하기 시작했습니다. :) – asenovm