2016-05-04 7 views
1

現在、Javaでチェスアプリケーションを作成していますが、タイルの境界線を作成したり、イメージのスムージングを行うにはいくつか問題があります。Java JPanel setBorderとアンチエイリアスが機能しない

編集: ボーダーに関する問題が解決されました。下記のmy answerを参照してください。

結果:

enter image description here

あなたはチェスの駒とタイル境界上のジャギーエッジがある見ることができるように欠けています。 しかし、getScaledInstance(width、height、Image.SCALE_SMOOTH)を追加するとアンチエイリアスが効いていますが、これによりアプリケーションの速度が遅くなり、ウィンドウのサイズを変更するとアイコンが醜いように見えます。

With getScaledInstance()

マイコード:

テーブルクラス:

import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.WindowConstants; 
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class Table { 
    private final BoardPanel boardPanel; 
    private final Board chessBoard; 

    private final static Dimension OUTER_FRAME_DIMENSION = new Dimension(650, 650); 
    private final static Dimension MIN_FRAME_DIMENSION = new Dimension(550, 550); 

    public Table(Board chessBoard) { 
     this.chessBoard = chessBoard; 
     boardPanel = new BoardPanel(chessBoard); 

     JFrame gameFrame = new JFrame("Chess"); 
     gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     gameFrame.setLayout(new BorderLayout()); 
     gameFrame.setSize(OUTER_FRAME_DIMENSION); 
     gameFrame.setMinimumSize(MIN_FRAME_DIMENSION); 


     gameFrame.setJMenuBar(createMenuBar()); 
     gameFrame.add(boardPanel, BorderLayout.CENTER); 
     gameFrame.pack(); 
     gameFrame.setVisible(true); 
    } 

    private JMenuBar createMenuBar() { 
     final JMenuBar menuBar = new JMenuBar(); 
     menuBar.add(createFileMenu()); 
     menuBar.add(createPreferencesMenu()); 
     return menuBar; 
    } 

    private JMenu createFileMenu() { 
     final JMenu fileMenu = new JMenu("File"); 
     final JMenuItem exitMenuItem = new JMenuItem("Exit"); 
     exitMenuItem.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 
      } 
     }); 
     fileMenu.add(exitMenuItem); 
     return fileMenu; 
    } 

    private JMenu createPreferencesMenu() { 
     final JMenu preferencesMenu = new JMenu("Preferences"); 
     final JMenuItem flipBoardMenuItem = new JMenuItem("Flip Board"); 
     flipBoardMenuItem.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       boardPanel.reverse(); 
       boardPanel.drawBoard(); 
      } 
     }); 
     preferencesMenu.add(flipBoardMenuItem); 
     return preferencesMenu; 
    } 
} 

BoardPanelクラス:

import javax.swing.BorderFactory; 
import javax.swing.JPanel; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.Image; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.geom.AffineTransform; 

import static javax.swing.SwingUtilities.invokeLater; 
import static javax.swing.SwingUtilities.isLeftMouseButton; 
import static javax.swing.SwingUtilities.isRightMouseButton; 

class BoardPanel extends JPanel { 
    private final Board chessBoard; 
    private final TilePanel[][] boardTiles; 

    private Point start; // first click 
    private Point target; // second click 

    private static final Dimension BOARD_PANEL_DIMENSION = new Dimension(650, 650); 
    private static final Dimension TILE_PANEL_DIMENSION = new Dimension(100, 100); 

    BoardPanel(Board chessBoard) { 
     super(new GridLayout(Board.N, Board.N)); 
     this.chessBoard = chessBoard; 
     this.boardTiles = new TilePanel[Board.N][Board.N]; 

     ImageManager.readPieceImages(); 
     setPreferredSize(BOARD_PANEL_DIMENSION); 
     fillBoard(); 
     validate(); 
    } 

    private void fillBoard() { 
     for (int x = 0; x < Board.N; x++) { 
      for (int y = 0; y < Board.N; y++) { 
       TilePanel tilePanel = new TilePanel(new Point(x, y)); 
       boardTiles[x][y] = tilePanel; 
      } 
     } 
     for (int i = Board.N; i > 0; i--) { 
      for (int j = 0; j < Board.N; j++) { 
       add(boardTiles[j][i - 1]); 
      } 
     } 
     validate(); 
    } 

    void drawBoard() { 
     removeAll(); 
     for (int i = Board.N; i > 0; i--) { 
      for (int j = 0; j < Board.N; j++) { 
       boardTiles[j][i - 1].drawTile(); 
       add(boardTiles[j][i - 1]); 
      } 
     } 
     revalidate(); 
     repaint(); 
    } 

    void reverse() { 
     // revers coloums 
     for (int col = 0; col < Board.N; col++) { 
      for (int row = 0; row < Board.N/2; row++) { 
       TilePanel temp = boardTiles[row][col]; 
       boardTiles[row][col] = boardTiles[Board.N - row - 1][col]; 
       boardTiles[Board.N - row - 1][col] = temp; 
      } 
     } 

     // reverse rows 
     for (int row = 0; row < Board.N; row++) { 
      for (int col = 0; col < Board.N/2; col++) { 
       TilePanel temp = boardTiles[row][col]; 
       boardTiles[row][col] = boardTiles[row][Board.N - col - 1]; 
       boardTiles[row][Board.N - col - 1] = temp; 
      } 
     } 
    } 

    private class TilePanel extends JPanel { 
     private final Tile tile; 
     private Image pieceImage; 


     TilePanel(final Point p) { 
      super(new GridBagLayout()); 
      this.tile = chessBoard.getTile(p); 

      setPreferredSize(TILE_PANEL_DIMENSION); 
      setColor(); 
      setPieceIcon(); 
      highlightBorder(); 

      addMouseListener(new MouseListener() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 
        if (isRightMouseButton(e)) { 
         start = null; 
         target = null; 
        } else if (isLeftMouseButton(e)) { 
         if (start == null) { // first click 
          start = tile.isOccupied() ? tile.getPosition() : null; 
          System.out.println(tile); 
         } else { // second click 
          target = tile.getPosition(); 
          Move move = new Move(chessBoard, start, target); 
          if (move.isValid()) { 
           System.out.println(move); 
           chessBoard.movePiece(start, target); 
           System.out.println(chessBoard); 
           repaint(); 
          } 
          start = null; 
          target = null; 
         } 
        } 
        invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          drawBoard(); 
         } 
        }); 
       } 

       @Override 
       public void mousePressed(MouseEvent e) { 

       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 

       } 

       @Override 
       public void mouseEntered(MouseEvent e) { 

       } 

       @Override 
       public void mouseExited(MouseEvent e) { 

       } 
      }); 
      validate(); 
     } 

     private void highlightLegalMoves() { 
      if (start != null && chessBoard.getTile(start).isOccupied()) { 
       Piece piece = chessBoard.getTile(start).getPiece(); 
       for (Move move : piece.generateMoves(chessBoard, start)) { 
        if (tile == move.getStartTile()) { 
         setBorder(BorderFactory.createLineBorder(new Color(255, 255, 102))); 
        } else if (tile == move.getTargetTile()) { 
         setBackground(new Color(255, 255, 102)); 
        } 
       } 
      } 
     } 

     private void highlightBorder() { 
      setBorder(BorderFactory.createLineBorder(Color.GRAY)); 
     } 

     private void setPieceIcon() { 
      removeAll(); 
      if (tile.isOccupied()) { 
       Piece piece = tile.getPiece(); 
       pieceImage = ImageManager.getPieceImage(piece.toString()); 
      } else { 
       pieceImage = null; 
      } 
     } 

     private void drawTile() { 
      setColor(); 
      setPieceIcon(); 
      highlightLegalMoves(); 
      highlightBorder(); 
      revalidate(); 
      repaint(); 
     } 

     final AffineTransform getTransform() { 
      AffineTransform at = new AffineTransform(); 
      at.scale(getWidth()/900.0, 
        getHeight()/900.0); 
      return at; 
     } 

     private void setColor() { 
      Color light = new Color(247, 236, 202); 
      Color dark = new Color(102, 68, 46); 
      boolean black 
        = (tile.getPosition().x % 2 == 0) == (tile.getPosition().y % 2 == 0); 
      setBackground(black ? dark : light); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.transform(getTransform()); 
      AffineTransform at = new AffineTransform(); 

      g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, 
        RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
        RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, 
        RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
        RenderingHints.VALUE_RENDER_QUALITY); 


      at.setToTranslation(10, 0); 
      g2d.drawImage(pieceImage, at, null); 
      g2d.dispose(); 
     } 
    } 
} 

私はこの問題を解決できることはありますか?事前に多くの感謝。

答えて

0

paintComponent()メソッドからg2d.disposeを削除して罫線を修正しました。しかし、私はまだアンチエイリアスに問題があります。

0

アイコンのサイズを変更するとアイコンが醜いです。

  1. アイコンを動的に拡大/縮小しないでください。または、
  2. ボードの再スケーリングを許可しないでください。
  3. Stretch Iconを使用すると、アイコンが拡大縮小されたときに元の割合を維持できる場合があります。このクラスは描画ヒントを設定しないので、追加する必要があることに注意してください。
関連する問題