0

我第一次使用 Swing 并且遇到了一些问题。我所拥有的是一个分成四个 JPanel 的 JFrame。JFrame 上有一个 MouseListener,它的行为是这样的

单击时,如果单击位于左侧栏内,请确定选择了 13 个图标中的哪一个。如果单击位于右侧“游戏窗格”内并且已选择图标,请将其放置在单击的位置。

这是在这里完成的

@Override
public void mouseClicked(MouseEvent event) {
    // TODO Auto-generated method stub
    xPos = event.getX();
    yPos = event.getY()-25;
    //If click is inside tool bar
    if(xPos<=75){
        if(yPos>-1 && yPos<48)
            //First tool image
              image = new ImageIcon(getClass().getResource(_image path_)).getImage();
        else if(yPos>=48 && yPos<96)
            //Second tool image
              image = new ImageIcon(getClass().getResource(_image path_)).getImage();
        else if(yPos>=96 && yPos<144)
            //Third tool image
              image = new ImageIcon(getClass().getResource(_image path_)).getImage();
        else if(yPos>=144 && yPos<192)
            //Fourth tool image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=192 && yPos<240)
            //Fifth tool image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=240 && yPos<288)
            //Sixth tool image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=288 && yPos<336)
            //Seventh tool image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=336 && yPos<384)
            //First NPC image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=384 && yPos<432)
            //second NPC image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=432 && yPos<480)
            //Third NPC image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=480 && yPos<528)
            //First Decoration image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=528 && yPos<576)
            //Second Decoration image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
        else if(yPos>=576 && yPos<=625)
            //Third Decoration image
              image = new ImageIcon(getClass().getResource(imagepath)).getImage();
    }
    //If click is within Game Pane
    else if (xPos>75 && yPos<625){
        //A tool has been selected
        if(image!=null){
            placedTool = this.image;
            this.image = null;
            placeable = true;
        }
    }
    //An image and location on the game pane has been selected
    if(placeable && this.image==null){
        ImageInfo newImg = new ImageInfo(xPos, yPos, image);
        gamePane.additions.add(newImg);
        gamePane.repaint();
        System.out.println("IMAGE PLACED @ " + xPos + ", " + yPos);
        placeable = false;
    }

    System.out.println("CLICK: (" + xPos + "," + yPos +")");
}

其中 imagepath 是 50x50 图标的路径。这部分工作正常,没有错误。但是,gamePane 没有正确重新绘制。

gamePane 现在只有一个背景图像。随着组件的添加,它们应该被绘制在顶部。不过,被绘制的只是背景图像。有没有办法使用 Graphics.drawImage(); 指定 Z 组件?这是我对 gamePane 的 paintComponent 函数的内容(加粗,因为这是主要问题)

@Override
protected void paintComponent(Graphics g) {
    g.drawImage(backgroundImg, 0, 0, null);
    for(ImageInfo add : additions){
        g.drawImage(add.getImage(), add.getX(), add.getY(), null);
    }
}

像这样定义添加的地方

列表添加 = new ArrayList();

ImageInfo 类只包含一个图像、一个 x 坐标和一个 y 坐标

public class ImageInfo {
private int x;
private int y;
private Image image;

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public Image getImage() {
    return image;
}

public ImageInfo(int x, int y, Image image) {
    super();
    this.x = x;
    this.y = y;
    this.image = image;
}

}

固定的:

谢谢mKorbel。通过在 mouseClicked 方法之外定义所有图像

Image tool1 = new ImageIcon(getClass().getResource(toolBar.TOOL1)).getImage();
Image tool2 = new ImageIcon(getClass().getResource(toolBar.TOOL2)).getImage();
Image tool3 = new ImageIcon(getClass().getResource(toolBar.TOOL3)).getImage();
Image tool4 = new ImageIcon(getClass().getResource(toolBar.TOOL4)).getImage();
Image tool5 = new ImageIcon(getClass().getResource(toolBar.TOOL5)).getImage();
Image tool6 = new ImageIcon(getClass().getResource(toolBar.TOOL6)).getImage();
Image tool7 = new ImageIcon(getClass().getResource(toolBar.TOOL7)).getImage();
Image npc1 = new ImageIcon(getClass().getResource(toolBar.NPC1)).getImage();
Image npc2 = new ImageIcon(getClass().getResource(toolBar.NPC2)).getImage();
Image npc3 = new ImageIcon(getClass().getResource(toolBar.NPC3)).getImage();
Image decor1 = new ImageIcon(getClass().getResource(toolBar.DECOR1)).getImage();
Image decor2 = new ImageIcon(getClass().getResource(toolBar.DECOR2)).getImage();
Image decor3 = new ImageIcon(getClass().getResource(toolBar.DECOR3)).getImage();

和执行 mouseClicked 函数,如

@Override
public void mouseClicked(MouseEvent event) {
    // TODO Auto-generated method stub
    xPos = event.getX();
    yPos = event.getY()-25;
    //If click is inside tool bar
    if(xPos<=75){
        if(yPos>-1 && yPos<48)
            //First tool image
              image = tool1;
        else if(yPos>=48 && yPos<96)
            //Second tool image
              image = tool2;
        else if(yPos>=96 && yPos<144)
            //Third tool image
              image = tool3;
        else if(yPos>=144 && yPos<192)
            //Fourth tool image
              image = tool4;
        else if(yPos>=192 && yPos<240)
            //Fifth tool image
              image = tool5;
        else if(yPos>=240 && yPos<288)
            //Sixth tool image
              image = tool6;
        else if(yPos>=288 && yPos<336)
            //Seventh tool image
              image = tool7;
        else if(yPos>=336 && yPos<384)
            //First NPC image
              image = npc1;
        else if(yPos>=384 && yPos<432)
            //second NPC image
              image = npc2;
        else if(yPos>=432 && yPos<480)
            //Third NPC image
              image = npc3;
        else if(yPos>=480 && yPos<528)
            //First Yard Decoration image
              image = decor1;
        else if(yPos>=528 && yPos<576)
            //Second Yard Decoration image
              image = decor2;
        else if(yPos>=576 && yPos<=625)
            //Third Yard Decoration image
              image = decor3;
    }
    //If click is within Game Pane
    else if (xPos>75 && yPos<625){
        //A tool has been selected
        if(image!=null){
            placedTool = this.image;
            this.image = null;
            placeable = true;
        }
    }

    if(placeable && this.image==null){
        GamePiece newImg = new GamePiece(placedTool, xPos, yPos);
        gamePane.additions.add(newImg);
        gamePane.repaint();
        System.out.println("IMAGE PLACED @ " + xPos + ", " + yPos);
        placeable = false;
    }

    System.out.println("CLICK: (" + xPos + "," + yPos +")");
}

这些图像是通过先前给出的paintComponent 方法添加到背景图像之上的。它们有点偏离位置,但仍然可见。

4

3 回答 3

2

只有一条评论

  1. 发布SSCCE短期可运行、可编译

  2. 为什么有yPos = event.getY()-25;什么逻辑代表一个integer at -25

  3. 全部存储ImageIcons在局部变量中,将它们存储ImageIcons在任何数组中,或者List在有固定逻辑而不是获取坐标然后加载image = new ImageIcon(getClass().getResource(绘制的情况下,在运行时paintComponent不提供任何FileIO


  • 创建一个由JLabels 铺设的网格GridLayout,添加MouseListener到每个JLabels,更改JLabel.setIcon(myImageIcon)from Mouse Event,其余逻辑我在没有 SSCCE 的情况下丢失

例如

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class ChessBoard extends JFrame {

    private JFrame frame = new JFrame();
    private JPanel panel = new JPanel();
    private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
    private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
    private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
    private Icon questnIcon = UIManager.getIcon("OptionPane.questionIcon");
    private JButton button = new JButton("Reset my board");

    public ChessBoard() {
        panel.setLayout(new GridLayout(8, 8, 0, 0));
        for (int i = 0; i < 64; i++) {
            final JLabel label = new JLabel();
            label.setIcon(errorIcon);
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON3) {
                        label.setIcon(infoIcon);
                    } else {
                        label.setIcon(warnIcon);
                    }
                }

                @Override
                public void mouseEntered(MouseEvent me) {
                    label.setIcon(questnIcon);
                }
            });
            panel.add(label);
        }
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (Component c : panel.getComponents()) {
                    if (c instanceof JLabel) {
                        JLabel label = (JLabel) c;
                        label.setIcon(errorIcon);
                    }
                }
            }
        });
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.add(button, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ChessBoard();
            }
        });
    }
}
于 2013-11-04T14:13:05.767 回答
0

这看起来很可疑:

if(placeable && this.image==null){

你没有image在方法中声明,所以它和 一样this.image,所以添加代码只有在image == null. 也许你的意思是:

if (placeable && this.image != null) {

(我不知道 的目的placeable,所以我保持原样)

于 2013-11-04T14:09:46.983 回答
0

感谢@MadProgrammer 提供这段代码,他帮我解决了这个问题(意味着他做了所有事情)

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;


import  sun.audio.*;

public class SHR {

    public static void main(String[] args) {
        new SHR();
    }

    public SHR() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("To Battle");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new ToBattle());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ToBattle extends JPanel {

        private BufferedImage image;
        private Point drawPoint;

        public ToBattle() {
            try {
                image = ImageIO.read(getClass().getResource("SilverHandRecruit.png"));
                addMouseListener(new MouseAdapter() {

                    @Override
                    public void mouseClicked(MouseEvent e) {
                        drawPoint = new Point(e.getPoint());

                        repaint();
                    }

                });
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (drawPoint != null) {
                g2d.drawImage(image, drawPoint.x - 100, drawPoint.y - 100, this);
            }
            g2d.dispose();
        }

    }

}

您可以查看他在此处发布的确切答案: 单击鼠标时添加图像?Java 小程序

于 2015-09-16T19:38:58.543 回答