2017-07-17 27 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:不客气 –