I'm building a Poker Odds Calc app in Java. I want to select a new card by clicking the card's placeholder which is basically an extended JPanel that I "draw" the card's face and has a mouseListener.
What I have imagined to do is that when I clicked the card, I would like a round menu to pop up around the mouse cursor having a circle in the middle cut in four with each suite in a quarter and a ring around it cut in thirteen for the value of the card. Then I will select suit and value and it would d开发者_如何学Cisappear. Do you know any way I could do this? I researched a bit and I think it can be done with JavaFX by making a transparent JDialog but I'm not sure.
Is there a way to draw a totally custom shaped JComponent like a JButton shaped for each quarter of the circle etc.? I have some experience in Java but not GUI building.
Thanks in advance for your time.
edit: Used your comment and have answered my question about the circular dialog (don't know if it's the best way to do it but works for now). Now, is there anyway I know in which area the click belongs (if the click was on a useful area) without hardcoding the coordinates?
I would suggest doing custom graphics rather than trying to customize JButton and so on. When you click on the JPanel you can draw the circle and so on using the java.awt.Shape interfaces and its various implementations such as java.awt.geom.Ellipse2D.
These shapes come with contains() method that can tell you if a point is in the Shape or not. This way, when the user next clicks on the JPanel, you can determine which shape the user clicked on by going through all the shapes and checking.
The code to create the graphics is this in case anyone needs it:
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D.Double;
import javax.swing.JDialog;
/**
*
* @author Dimitris Klimis <dnklimis at gmail.com>
*/
public class CardChooser extends JDialog implements MouseListener {
int sizeX = 140;
int sizeY = sizeX; //in case I don't want it to be circle
int x, y;
Point point;
public CardChooser(Point point) {
x = point.x;
y = point.y;
this.point = point;
this.initComponents();
}
public static int[] getCard(Point point) {
int[] output = {0, 0};
CardChooser chooser = new CardChooser(point);
return output;
}
@Override
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Drawing the transparent dialog
g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.0f));
g2.fillRect(0, 0, getWidth(), getHeight());
//Drawing the circles
g2.setColor(Color.BLACK);
drawCircle(g2, 100, new GradientPaint(0.0f, 0.0f, Color.darkGray, (float) getWidth(), (float) getHeight(), Color.lightGray, false));
drawLines(g2, 13, 100);
int smallCircle = 38;
drawCircle(g2, smallCircle + 3, Color.GRAY);
drawCircle(g2, smallCircle, new GradientPaint((float) (getWidth() * 0.25), (float) (getHeight() * 0.25), Color.lightGray, (float) (getWidth() * 0.75), (float) (getHeight() * 0.75), Color.darkGray, false));
drawLines(g2, 4, smallCircle);
drawCircle(g2, 10, Color.LIGHT_GRAY);
drawSuiteLetters(g2);
drawCardValues(g2);
drawClosingX(g2);
} else {
super.paint(g);
}
}
private void drawCircle(Graphics2D g2, int percentage, Paint fill) {
double perc = (double) percentage / 100.0;
Ellipse2D ellipse = new Ellipse2D.Double(((1 - perc) / 2) * sizeX, ((1 - perc) / 2) * sizeY, perc * sizeX, perc * sizeY);
g2.setPaint(fill);
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.draw(ellipse);
}
private void drawLines(Graphics2D g2, int outOf, int percentage) {
double rads = Math.toRadians(360.0 / outOf);
double perc = (double) percentage / 100.0;
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
for (int i = 0; i < outOf; i++) {
g2.draw(new Line2D.Double(zeroAxis.x, zeroAxis.y, zeroAxis.x + (zeroAxis.x * perc * Math.sin(rads * i)), zeroAxis.y + (zeroAxis.y * perc * Math.cos(rads * i))));
}
}
private void drawSuiteLetters(Graphics2D g2) {
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
g2.setFont(new Font("Courier New", Font.BOLD, 25));
g2.drawString("\u2660", (float) zeroAxis.x - 18, (float) zeroAxis.y - 5);//spades
g2.drawString("\u2663", (float) zeroAxis.x + 3, (float) zeroAxis.y + 20);//clubs
g2.setColor(Color.RED);
g2.drawString("\u2665", (float) zeroAxis.x + 3, (float) zeroAxis.y - 3);//hearts
g2.drawString("\u2666", (float) zeroAxis.x - 18, (float) zeroAxis.y + 19);//diamonds
g2.setColor(Color.BLACK);
}
private void drawCardValues(Graphics2D g2) {
Double zeroAxis = new Point.Double((sizeX / 2.0) - 8, 21);
float xx = (float) zeroAxis.x;
float yy = (float) zeroAxis.y;
g2.setFont(new Font("Arial", Font.BOLD, 24));
String[] letters = {"A", "K", "Q", "J", "T", "9", "8", "7", "6", "5", "4", "3", "2"};
float[] xPosition = {0, 25, 46, 63, 58, 42, 15, -10, -37, -53, -58, -46, -25};
float[] yPosition = {0, 7, 23, 50, 80, 102, 115, 115, 102, 80, 50, 23, 7};
for (int i = 0; i < 13; i++) {
g2.drawString(letters[i], xx + xPosition[i], yy + yPosition[i]);
}
}
private void drawClosingX(Graphics2D g2) {
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
g2.draw(new Line2D.Double(zeroAxis.x - 5, zeroAxis.y - 5, zeroAxis.x + 5, zeroAxis.y + 5));
g2.draw(new Line2D.Double(zeroAxis.x - 5, zeroAxis.y + 5, zeroAxis.x + 5, zeroAxis.y - 5));
}
private void initComponents() {
this.addMouseListener(this);
this.setBounds(x - (sizeX / 2), y - (sizeY / 2), sizeX + 1, sizeX + 1);
this.setUndecorated(true);
this.setModal(true);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setVisible(true);
}
public void mouseClicked(MouseEvent e) {
this.dispose();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
PS. I extended JDialog cause I couldn't get JPanel to show up...
精彩评论