Java 不好的颜色引用? 我正在设计一个非常类似于无流量的游戏。我在代码中遇到了一个问题,我希望能够单击网格中的一个圆,能够测量其颜色,然后检查颜色是否为白色。如果颜色是白色,我将打印错误,这是目前的占位符。但是,即使我单击非白色的平铺,我仍然可以看到正在打印的错误消息。我做错了什么
我的代码:Java 不好的颜色引用? 我正在设计一个非常类似于无流量的游戏。我在代码中遇到了一个问题,我希望能够单击网格中的一个圆,能够测量其颜色,然后检查颜色是否为白色。如果颜色是白色,我将打印错误,这是目前的占位符。但是,即使我单击非白色的平铺,我仍然可以看到正在打印的错误消息。我做错了什么,java,swing,colors,panel,paint,Java,Swing,Colors,Panel,Paint,我的代码: import javax.swing.JFrame; //JFrame Class import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import java.awt.Shape; import java.util.ArrayList; import javax.swing.JPanel; import java.awt.geom.Ellipse2D; import java.awt.Gra
import javax.swing.JFrame; //JFrame Class
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Shape;
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.geom.Ellipse2D;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class DriverV2 extends JPanel {
static ArrayList<Shape> circles;
static ArrayList<Color> colors;
public DriverV2() {
circles = new ArrayList<Shape>();
colors = new ArrayList<Color>();
colors.add( Color.CYAN);//1
colors.add( Color.BLUE);//2
colors.add( Color.WHITE);//3
colors.add( Color.WHITE);//4
colors.add( Color.GREEN);//5
colors.add( Color.WHITE);//6
colors.add( Color.CYAN);//7
colors.add( Color.WHITE);//8
colors.add( Color.WHITE);//9
colors.add( Color.RED);//10
colors.add( Color.WHITE);//11
colors.add( Color.YELLOW);//12
colors.add( Color.WHITE);//13
colors.add( Color.GREEN);//14
colors.add( Color.WHITE);//15
colors.add( Color.WHITE);//16
colors.add( Color.BLUE);//17
colors.add( Color.WHITE);//18
colors.add( Color.RED);//19
colors.add( Color.WHITE);//20
colors.add( Color.WHITE);//21
colors.add( Color.WHITE);//22
colors.add( Color.WHITE);//23
colors.add( Color.WHITE);//24
colors.add( Color.YELLOW);//25
int rows = 5;
for (int y=0;y< rows;y++)
{
for (int x=0;x<rows;x++)
{
circles.add( new Ellipse2D.Double((x + 1) * 150, (y + 1) *150, 100, 100) );
}
}
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
Color foreground = g2d.getColor();
int h = 0;
for (Shape shape : circles)
{
g2d.setColor( colors.get(h));
g2d.draw( shape );
g2d.fill(shape);
h++;
}
}
public static boolean checkLinearity(int index1, int index2){
if((index1%5) == (index2 %5)) { //vertical line check
return true;
}
if(Math.abs(index1-index2) < 5) { //horizantal line check
return true;
}
else {
return false;
}
}
static int counter = 0;
static int index1 = 0;
static int index2 = 0;
public static void main(String[] args)
{
JFrame f = new JFrame("Flow"); //new JFrame
DriverV2 t = new DriverV2();
f.setSize(900,900);//sets size of frame
// f.setLocation(100,50);//sets location of frame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//sets default close operation
// f.setContentPane(new Panel()); //sets content pane
f.setVisible(true);//makes panel visible
f.add(t);
f.addMouseListener( new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
for (Shape shape: circles) {
if (shape.contains(x,y)) {
counter++;
if(counter % 2 == 1) {
index1 = circles.indexOf(shape)+1;
if(Color.WHITE.equals(colors.get(index1))) {
counter--;
System.out.println("error");
}
}
else{
index2 = circles.indexOf(shape) +1;
if(checkLinearity(index1, index2) == true) {
//I want to be able to draw a rectange here
}
}
}
}
}
});
}
}
你的问题似乎是另一个例子,说明为什么包括我在内的许多人都主张即使在单语句块上也要加花括号——他们可能不会一直这样: 请看一下这个片段:
if (shape.contains(x,y))
counter++;
if(counter % 2 == 1) {
...
它不会做你认为的事情,也就是说,如果你点击形状计数器,得到的值会增加,但其余的检查会针对每个形状执行。这是因为对于编译器来说,代码如下所示:
if (shape.contains(x,y))
counter++;
if(counter % 2 == 1) {
...
class Circle {
Shape shape;
Color color;
... //additional properties, e.g. position, and methods
public boolean wasHit(int x, int y) {
return shape.contains(x,y);
}
public boolean isValid() {
return Color.WHITE.equals( color );
}
}
for( Circle circle : circles ) {
if( circle.wasHit(x, y) {
if( circle.isValid() ) {
//do what you'd need here, e.g. change the shape to a rectangle
} else {
//error
}
//break the loop since other circles can't be hit or we're not interested in those
break;
}
}
因此,当您点击一个圆圈时,计数器将为1,因此计数器%2==1将在此后检查的每个圆圈中为真
因此,在缩进的代码周围添加大括号。此外,一旦检测到命中,您可能希望打破循环,因为您可能对检查所有其他圆圈也不感兴趣
您可能还想引入一个类圆,它可能如下所示:
if (shape.contains(x,y))
counter++;
if(counter % 2 == 1) {
...
class Circle {
Shape shape;
Color color;
... //additional properties, e.g. position, and methods
public boolean wasHit(int x, int y) {
return shape.contains(x,y);
}
public boolean isValid() {
return Color.WHITE.equals( color );
}
}
for( Circle circle : circles ) {
if( circle.wasHit(x, y) {
if( circle.isValid() ) {
//do what you'd need here, e.g. change the shape to a rectangle
} else {
//error
}
//break the loop since other circles can't be hit or we're not interested in those
break;
}
}
然后,您将迭代如下内容:
if (shape.contains(x,y))
counter++;
if(counter % 2 == 1) {
...
class Circle {
Shape shape;
Color color;
... //additional properties, e.g. position, and methods
public boolean wasHit(int x, int y) {
return shape.contains(x,y);
}
public boolean isValid() {
return Color.WHITE.equals( color );
}
}
for( Circle circle : circles ) {
if( circle.wasHit(x, y) {
if( circle.isValid() ) {
//do what you'd need here, e.g. change the shape to a rectangle
} else {
//error
}
//break the loop since other circles can't be hit or we're not interested in those
break;
}
}
另外,除了Thomas在回答中提到的1+之外,不要将鼠标听筒添加到JFrame中。将其添加到正在绘制的JPanel中,否则您的x和y位置将关闭 对于我自己,我会使用一个由jlabel组成的网格,这些标签包含图标。您甚至可以将标签的行和列值作为可以检索的属性。如果这是您的目标,这将允许轻松交换图标,并允许轻松检索按下的网格单元 一些优点: 如果JLabel也被放入一个列表中,那么如果您需要随机放置颜色,它们可以很容易地被洗牌 白色的错误测试很容易。只需从所选JLabel获取图标,并测试是否与白色图标相等:if label.getIcon==whiteIcon。 同样,获取所选磁盘的行/列位置很容易,因为它是JLabel本身的固有属性,可以通过调用JLabel上的getClientProperty来检索,例如:label1.getClientPropertyROW; 如果需要检查一行中是否有两次鼠标按下,请将第一次鼠标按下结果保存到类的字段中,这里是一个名为label1的JLabel。 例如:
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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
public class DriverV2b extends JPanel {
private static final String ROW = "row";
private static final String COLUMN = "column";
private static final int DIM = 5;
private static final int ICON_WIDTH = 150;
private static final int CIRCLE_WIDTH = 100;
private JLabel[][] labelGrid = new JLabel[DIM][DIM];
private Icon whiteIcon = createIcon(Color.WHITE);
private Icon blueIcon = createIcon(Color.BLUE);
private Icon greenIcon = createIcon(Color.GREEN);
private Icon yellowIcon = createIcon(Color.YELLOW);
private Icon redIcon = createIcon(Color.RED);
private Icon[] coloredIcons = {blueIcon, greenIcon, yellowIcon, redIcon};
private JLabel label1 = null;
public DriverV2b() {
// grid to hold the JLabels
setLayout(new GridLayout(DIM, DIM));
// mouse listener to add to all JLabels
MyMouse myMouse = new MyMouse();
// list of JLabels so we can shuffle them for random placement
List<JLabel> labels = new ArrayList<>();
for (int row = 0; row < labelGrid.length; row++) {
for (int col = 0; col < labelGrid[row].length; col++) {
// initially give all a white icon
labelGrid[row][col] = new JLabel(whiteIcon);
// add mouselistener
labelGrid[row][col].addMouseListener(myMouse);
// client property so we know what row and column the label is on
labelGrid[row][col].putClientProperty(ROW, row);
labelGrid[row][col].putClientProperty(COLUMN, col);
// add JLabel to the array list
labels.add(labelGrid[row][col]);
// add it to the GUI
add(labelGrid[row][col]);
}
}
// shuffle the array list of JLabels, so we can add colored icons randomly
Collections.shuffle(labels);
// for each colored icon in the array, add *two** to the list
for (int i = 0; i < coloredIcons.length; i++) {
int index = 2 * i;
labels.get(index).setIcon(coloredIcons[i]);
labels.get(index + 1).setIcon(coloredIcons[i]);
}
}
private Icon createIcon(Color color) {
int w = ICON_WIDTH;
BufferedImage img = new BufferedImage(w, w, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
// rendering hints used to smooth the image edges
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
int width = CIRCLE_WIDTH;
int x = (ICON_WIDTH - CIRCLE_WIDTH) / 2;
g2.fillOval(x, x, width, width);
g2.dispose();
return new ImageIcon(img);
}
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
if (label.getIcon() == whiteIcon) {
System.out.println("error -- ignoring this press");
return;
}
if (label1 == null) {
// first press
label1 = label;
} else {
JLabel label2 = label;
int row1 = (int) label1.getClientProperty(ROW);
int col1 = (int) label1.getClientProperty(COLUMN);
int row2 = (int) label2.getClientProperty(ROW);
int col2 = (int) label2.getClientProperty(COLUMN);
Icon icon1 = label1.getIcon();
Icon icon2 = label2.getIcon();
// just to show that this works:
System.out.printf("Locaions: [%d, %d] [%d, %d]%n",
row1, col1, row2, col2);
if (checkLinearity(row1, col1, row2, col2)) {
// TODO: do something
}
label1 = null; // reset this
}
}
private boolean checkLinearity(int row1, int col1, int row2, int col2) {
// TODO finish this method
return false;
}
}
private static void createAndShowGui() {
DriverV2b mainPanel = new DriverV2b();
JFrame frame = new JFrame("DriverV2b");
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());
}
}
添加了对whiteIcon press的错误测试我们可以看到您的类形状吗?请注意,索引是基于0的,因此colors.getindex1可能会因index1=圆圈而关闭。indexOfshape+1;。顺便说一句,因为你无论如何都在循环中迭代,所以没有必要使用circles.indexOfshape-只需再次计算循环迭代次数,从0开始。更好的是,创建一个包含形状和颜色的类圆。这样,形状和颜色的索引就不会因为编程错误而失去同步。@Thomas我知道情况并非如此,因为我尝试单击网格中的所有内容,每次都会显示错误消息printed@mackycheese21Shape是一个内置的java接口,只是google的documentation@mackycheese21例如他没有阶级特征。他正在引用核心Java形状接口。请检查导入。我已经添加了大括号,我的代码似乎仍然不起作用。我已经更新了问题代码,使之匹配。@shuryusd我在你更新的帖子中没有看到花括号。您添加了一些,但它们位于错误的位置-请仔细阅读我的答案。@shuryusd现在看起来更好了。我现在明白了,我只需要删除我在索引中使用的+1,现在就可以了。谢谢