2017-11-19 5 views
2

Also im Grunde versuche ich ein Reversi-Spiel zu erstellen. Zuerst habe ich ein Board erstellt, das mit Buttons und angehängten IDs gefüllt ist, damit ich später darauf zugreifen kann. Jetzt versuche ich, ein Spielstück auf jedem der Knöpfe zu zeichnen, aber ich kann Graphics() des Knopfes nicht bekommen, da ich lese, dass das eine schlechte Idee ist und null zurückgibt. Bedenken Sie, dass ich alle meine Entitäten getrennt halten möchte: das Board, die Zelle und das Stück, da ich dies mit dem MVC-Muster entwickle.Ein Oval oben auf JButton zeichnen

board.java

import java.awt.GridLayout; 
import javax.swing.JPanel; 

public class Board extends JPanel { 
    private static final int sizeOfBoard = 8; 

    public Board() { 
     int id =0; 
     setLayout(new GridLayout(sizeOfBoard,sizeOfBoard)); 
     for (int i = 0; i < sizeOfBoard; i++) { 
      for (int j = 0; j < sizeOfBoard; j++) { 
       Cell cell = new Cell(id++); 
       Disk disk = new Disk(); 
       cell.add(disk); 
       add(cell); 
      } 
     } 

     setSize(600,500); 
     setVisible(true); 
    } 

cell.java

import java.awt.Graphics; 
import javax.swing.JButton; 
import javax.swing.Painter; 

    public class Cell extends JButton{ 
     private int id; 
     private boolean taken; 
     private String colour; 
     private Painter painter; 

     public Cell(int id){ 
      this.id = id; 
     } 

     public int getId(){ 
      return id; 
     } 

     @Override 
     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
     } 
    } 

disk.java

import java.awt.Graphics; 
import javax.swing.JComponent; 


public class Disk extends JComponent{ 

    @Override 
    public void paintComponent (Graphics g) { 
     super.paintComponent(g); 
     g.drawOval(50,50,50,50); 
    } 
} 

TL; DR Wie soll ich meinen Code umschreiben, damit er auf jeder Taste ein Oval hat.

Vielen Dank im Voraus.

Antwort

3

Die einfachste Lösung: Erstellen Sie Ihre Oval- oder Disk-Images in einem BufferedImage, legen Sie sie in ein ImageIcon und tauschen Sie einfach Icons auf Ihrem JButton oder JLabel über die setIcon(myIcon)-Methode aus. Ich würde 3 ImageIcons erstellen, wenn dies meine GUI wäre, eine leere für den Anfangszustand und dann zwei verschiedenfarbige für die besetzten Zustände.

Zum Beispiel:

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class ReversiPanel extends JPanel { 
    private static final int SIDES = 8; 
    private static final int ICON_LENGTH = 60; 
    private static final Color BG = Color.BLACK; 
    private static final Color LABEL_COLOR = Color.GREEN.darker(); 
    private JLabel[][] labelGrid = new JLabel[SIDES][SIDES]; 
    private Icon blankIcon; 
    private Icon blackIcon; 
    private Icon whiteIcon; 

    public ReversiPanel() { 
     blankIcon = createIcon(new Color(0, 0, 0, 0)); 
     blackIcon = createIcon(Color.BLACK); 
     whiteIcon = createIcon(Color.WHITE); 

     setBackground(BG); 
     setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); 
     setLayout(new GridLayout(SIDES, SIDES, 1, 1)); 
     MyMouse myMouse = new MyMouse(); 
     for (int i = 0; i < labelGrid.length; i++) { 
      for (int j = 0; j < labelGrid[i].length; j++) { 
       JLabel label = new JLabel(blankIcon); 
       label.setOpaque(true); 
       label.setBackground(LABEL_COLOR); 
       label.addMouseListener(myMouse); 
       labelGrid[i][j] = label; 
       add(label); 
      } 
     } 
    } 

    private Icon createIcon(Color color) { 
     BufferedImage img = new BufferedImage(ICON_LENGTH, ICON_LENGTH, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2 = img.createGraphics(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(color); 
     int gap = 4; 
     int w = ICON_LENGTH - 2 * gap; 
     int h = w; 
     g2.fillOval(gap, gap, w, h); 
     g2.dispose(); 
     return new ImageIcon(img); 
    } 

    private class MyMouse extends MouseAdapter { 
     @Override 
     public void mousePressed(MouseEvent e) { 
      JLabel label = (JLabel) e.getSource(); 
      Icon icon = label.getIcon(); 
      if (icon == blankIcon) { 
       label.setIcon(blackIcon); 
      } else if (icon == blackIcon) { 
       label.setIcon(whiteIcon); 
      } else { 
       label.setIcon(blankIcon); 
      } 
     } 
    } 

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

     JFrame frame = new JFrame("ReversiPanel"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
+0

@RMS: zum Beispiel kompilieren und ausführen meinen [MCVE] Code oben. Es benutzt JLabels, da mir das sauberer erscheint, aber ein JButton würde genauso gut funktionieren. –

+0

Vielen Dank. Diese Art von Ansatz sieht besser aus als alles, was ich gemacht habe. Schätze es wirklich. – Frisco