2017-07-17 49 views
2

我正在生成一個六邊形網格,並且能夠這樣做,但是當我將MouseListener添加到單個六邊形(創建它們時)時,它幾乎與如果他們背後的東西,因爲懸停/點擊六角形不會註冊或做任何事情。我希望能夠最終與六邊形進行交互,但如果我無法實現這個功能,就無法做到這一點。無法讓MouseListener在Hexagon上工作(生成的多邊形)

我主要GUI元素:

import java.awt.*; 
import javax.swing.*; 

public class Game2 
{ 
    public Game2(int radius,int num_hexes) 
    { 
    if(num_hexes%2==0) throw new AssertionError("Can't generate map with 
    an even number of hexagons."); 

    JFrame frame=new JFrame(); 
    JPanel panel=new JPanel(); 

    panel.setBorder(BorderFactory.createLineBorder(Color.RED)); 
    panel.setLayout(new BoxLayout(panel,1)); 

    frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    frame.setTitle("HexGame"); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setLayout(new BorderLayout()); 

    Rectangle r=frame.getBounds(); 
    int screen_height=r.height; 
    int screen_width=r.width; 

    Hexes2 hexes2=new Hexes2(num_hexes,radius,screen_width,screen_height); 

    panel.add(hexes2); 
    JScrollPane scroll_pane=new JScrollPane(panel); 
    frame.getContentPane().add(scroll_pane); 
    panel.setOpaque(false); 
    frame.pack(); 
    frame.setVisible(true); 
} 

public static void main(String[] args) 
{ 
    Runnable r=new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      new Game2(100,11); 
     } 
    }; 
    SwingUtilities.invokeLater(r); 
} 
} 

我的多個六邊形:

import java.awt.*; 
import java.util.LinkedList; 
import java.util.List; 
import javax.swing.JPanel; 

public class Hexes2 extends JPanel 
{ 
private static final long serialVersionUID=1L; 
private static List<Polygon> hexagons; 
private static int[] rows; 
private int radius; 

public Hexes2(int num_columns,int radius,int screen_width,int screen_height) 
{ 
    super(); 

    this.radius=radius; 
    hexagons=new LinkedList<Polygon>(); 
    rows=Functions.columns(num_columns); 

    int x=screen_width/6; 
    int y=screen_height/2; 

    double height=radius*Math.sqrt(3); 
    double range=num_columns-rows[0]; 

    //build by columns, first 
    for(int j=0;j<num_columns;j++) 
    { 
     x+=((3/2)*radius)*1.5015; 

     if(j<=Math.floor(num_columns/2)) y=(int) (100-(j*(height/2))); 
     else y=(int) ((100-(height*(range/2))+(num_columns-rows[j])*(height/2))); 

     for(int i=0;i<rows[j];i++) 
     { 
      y+=height; 
      Hex2 hex=new Hex2(i,radius,x,y); 
      hexagons.add(hex.getHex()); 
     } 
    } 
} 

protected void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    Graphics2D g2=(Graphics2D) g; 
    setOpaque(false); 

    for(int i=0;i<hexagons.size();i++) 
    { 
     Stroke stroke=new BasicStroke(radius/20, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 
     g2.setStroke(stroke); 

     g2.setColor(Color.BLACK); 
     g2.drawPolygon(hexagons.get(i)); 
    } 
} 
}; 

我的單數六邊形類:

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JLabel; 

public class Hex2 extends JLabel implements MouseListener 
{ 
private static final long serialVersionUID = 1L; 
private int ID; 
private Polygon hexagon; 

public Hex2(int ID,int r,int x,int y) 
{ 
    super(); 
    this.ID=ID; 

    hexagon=generateHex(r,x,y); 

    addMouseListener(this); 
} 

public Polygon generateHex(int r, int x, int y) 
{ 
    Polygon hexagon=new Polygon(); 

    for(int i=0;i<6;i++) 
    { 

     /*int _x=(int) (x + r*Math.cos(Math.PI/3.0 * i)); 
     int _y=(int) (y + r*Math.sin(Math.PI/3.0 * i));*/ 

     int _x=(int) (x + r*Math.cos(i*2*Math.PI/6)); 
     int _y=(int) (y + r*Math.sin(i*2*Math.PI/6)); 

     hexagon.addPoint(_x,_y); 
    } 

    return hexagon; 
} 

public int getID() 
{ 
    return ID; 
} 

public Polygon getHex() 
{ 
    return hexagon; 
} 

@Override 
public void mouseClicked(MouseEvent arg0) { 
    System.out.println("Clicked on hexagon "+ID); 

} 

@Override 
public void mouseEntered(MouseEvent arg0) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void mouseExited(MouseEvent arg0) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void mousePressed(MouseEvent arg0) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void mouseReleased(MouseEvent arg0) { 
    // TODO Auto-generated method stub 

} 
}; 

功能:

import java.awt.Dimension; 

public class Functions 
{ 
//takes in the max width, n (# hexagons), of the largest row (in the middle) 
public static int[] columns(int n) 
{ 
    int[] columns=new int[n]; 
    int deviation=(int) java.lang.Math.floor(n/2); 

    for(int i=0;i<n;i++) 
    { 
     columns[i]=n-(java.lang.Math.abs(i-deviation)); 
    } 

    return columns; 
} 

public static Dimension getScreenSize() 
{ 
    return java.awt.Toolkit.getDefaultToolkit().getScreenSize(); 
} 
} 

我爲長碼道歉,只是想徹底。任何幫助非常感謝,提前感謝。

+1

問題編輯。請理解,「我搜索過的地方......」這些陳述並不能幫助我們理解您在搜索中找到的內容,以及這些信息對您的幫助。我們需要具體細節。 –

+0

你的代碼不適合我們編譯。什麼是「函數」,「函數。列(num_columns)」是做什麼的?最好創建併發布有效的[mcve],以使調試更加容易,無論你和我們。 –

+0

謝謝。剛編輯顯示我的函數類有什麼。 – JoshuaK98

回答

1

你想要添加您的MouseListener您Hex2的JLabel:

public Hex2(int ID, int r, int x, int y) { 
    super(); 
    this.ID = ID; 
    hexagon = generateHex(r, x, y); 
    addMouseListener(this); 
} 

這些的JLabel你從不添加到GUI,因爲你在A線在這裏創建它們:

for (int j = 0; j < num_columns; j++) { 
     x += ((3/2) * radius) * 1.5015; 
     if (j <= Math.floor(num_columns/2)) 
      y = (int) (100 - (j * (height/2))); 
     else 
      y = (int) ((100 - (height * (range/2)) + (num_columns - rows[j]) * (height/2))); 
     for (int i = 0; i < rows[j]; i++) { 
      y += height; 
      Hex2 hex = new Hex2(i, radius, x, y); // ****** [A] ***** 
      hexagons.add(hex.getHex()); // ****** [B] ***** 
     } 
    } 

但十六進制從未添加到GUI。相反,由getHex()返回的其他內容被添加,所以MouseListener將不起作用。需要將MouseListener添加到GUI中可視化的組件,以便其操作可以執行任何操作。

我認爲你在這裏使用的組件太多。只有一個組件,一個JPanel,應該做所有的繪圖,並且應該添加MouseLIstener。其他所有應該是邏輯不擴展Swing組件類的類。

例如,運行下面的代碼。它將十六進制顯示爲非組件類,它是一個響應MouseListener的類,因爲偵聽器僅添加到單個繪圖JLabel中。多邊形的形狀,並有contains(Point p)方法,可以將鼠標監聽內部使用,以讓他們「知道」時,一直壓制他們:

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Polygon; 
import java.awt.RenderingHints; 
import java.awt.Stroke; 
import java.awt.Toolkit; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.LinkedList; 
import java.util.List; 

import javax.swing.*; 

public class HexPanel extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private List<Hex2b> hex2bs = new ArrayList<>(); 
    private int radius; 
    private int[] rows; 

    public HexPanel(int num_columns, int radius, int screen_width, int screen_height) { 
     super(); 
     setBackground(Color.WHITE); 
     this.radius = radius; 
     hex2bs = new LinkedList<Hex2b>(); 
     rows = Functions.columns(num_columns); 
     int x = screen_width/6; 
     int y = screen_height/2; 
     double height = radius * Math.sqrt(3); 
     double range = num_columns - rows[0]; 
     // build by columns, first 
     for (int j = 0; j < num_columns; j++) { 
      x += ((3/2) * radius) * 1.5015; 
      if (j <= Math.floor(num_columns/2)) 
       y = (int) (100 - (j * (height/2))); 
      else 
       y = (int) ((100 - (height * (range/2)) + (num_columns - rows[j]) * (height/2))); 
      for (int i = 0; i < rows[j]; i++) { 
       y += height; 
       Hex2b hex = new Hex2b(i, radius, x, y); 
       hex2bs.add(hex); 
      } 
     } 
     addMouseListener(new MyMouse()); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // smooth graphics 
     // setOpaque(false); // doesn't belong in here 
     for (int i = 0; i < hex2bs.size(); i++) { 
      Stroke stroke = new BasicStroke(radius/20, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 
      Hex2b hex2b = hex2bs.get(i); 
      Color color = hex2b.getColor(); 
      g2.setColor(color); 
      g2.fill(hex2b.getHex()); 
      g2.setStroke(stroke); 
      g2.setColor(Color.BLACK); 
      g2.draw(hex2b.getHex()); 
     } 
    } 

    private class MyMouse extends MouseAdapter { 
     @Override 
     public void mousePressed(MouseEvent e) { 
      for (Hex2b hex2b : hex2bs) { 
       if (hex2b.getHex().contains(e.getPoint())) { 
        hex2b.changeColor(); 
        repaint(); 
        break; 
       } 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Game2b"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Toolkit toolKit = Toolkit.getDefaultToolkit(); 
     Dimension screen = toolKit.getScreenSize(); 
     int width = screen.width; 
     int height = screen.height; 
     frame.getContentPane().add(new HexPanel(11, 100, width, height)); 
     frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

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

class Hex2b { 
    private static final Color INIT_COLOR = Color.white; 
    private static final Color SELECTED_COLOR = Color.red; 
    private int ID; 
    private Polygon hexagon; 
    private Color color = INIT_COLOR; 

    public Hex2b(int ID, int r, int x, int y) { 
     super(); 
     this.ID = ID; 
     hexagon = generateHex(r, x, y); 
    } 

    public Color getColor() { 
     return color; 
    } 

    public void changeColor() { 
     color = color == INIT_COLOR ? SELECTED_COLOR : INIT_COLOR; 
    } 

    public Polygon generateHex(int r, int x, int y) { 
     Polygon hexagon = new Polygon(); 
     for (int i = 0; i < 6; i++) { 
      int _x = (int) (x + r * Math.cos(i * 2 * Math.PI/6)); 
      int _y = (int) (y + r * Math.sin(i * 2 * Math.PI/6)); 
      hexagon.addPoint(_x, _y); 
     } 
     return hexagon; 
    } 

    public int getID() { 
     return ID; 
    } 

    public Polygon getHex() { 
     return hexagon; 
    } 
} 
+0

謝謝!是的,這更有意義。 – JoshuaK98

+0

@ JoshuaK98:不客氣 –