当 Int 更改时,一个 JPanel 中 MousePressed 中的 Int 值不会更新

Posted

技术标签:

【中文标题】当 Int 更改时,一个 JPanel 中 MousePressed 中的 Int 值不会更新【英文标题】:Int value in MousePressed in one JPanel not updating when the Int changes 【发布时间】:2013-11-16 05:28:29 【问题描述】:

我正在编写一个应用程序来打印网格中的积木,并且我已经对其进行了设置,理想情况下,为了更改颜色,菜单选择会更改一个 int,它设置积木类中的颜色。

我有两个面板,一个用于网格(绘制事物的位置),一个用于菜单栏。如果我手动更改网格中的数字,它可以工作,所以我认为这可能是菜单的问题,但我不确定。我想知道如何在菜单 jpanel 更改时将 int 从菜单 jpanel 获取到网格 jpanel。

这是菜单代码:

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

public class Selector extends JPanel implements Common, ActionListener
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public Color colorValues[] = Color.BLACK, Color.YELLOW, Color.RED, Color.ORANGE;
    public String colors[] = "Black", "Yellow", "Red", "Orange";
    public JMenuItem colorItems[];
    public int display;

    //constructor
    public Selector()
        //set size and layout
        setPreferredSize(new Dimension(SELECTOR_WIDTH, SELECTOR_HEIGHT));
        setLayout(new BorderLayout());

        //menu bar
        JMenuBar bar = new JMenuBar();
        Font f = new Font("Helvetica", Font.BOLD, 15);

        //menus
        JMenu colorMenu = new JMenu("Colour");

        //create Color menu
        String colors[] = "Black", "Yellow", "Red", "Orange";
        colorItems = new JMenuItem[colors.length];

        for (int i = 0; i<colors.length; i++)
            colorItems [i] = new JMenuItem(colors[i]);
            colorMenu.add(colorItems[i]);
            colorItems[i].addActionListener(this);
        // end of for loop


        //set all font the same
        UIManager.put("Menu.font", f);
        UIManager.put("MenuBar.font", f);
        UIManager.put("MenuItem.font", f);

        //add menus
        bar.add(colorMenu);

        //add menu bar
        add(bar, BorderLayout.PAGE_START);

    //constructor end

    public void actionPerformed(ActionEvent e)

        if (e.getSource()==colorItems[0])
            display=0;
        
        else if (e.getSource()==colorItems[1])
            display=1;
        
        else if (e.getSource()==colorItems[2])
            display=2;
        
        else if (e.getSource()==colorItems[3])
            display=3;
        
    
//class end

这是地图网格代码:

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

public class MapGrid extends JPanel implements Common, MouseListener
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    //brick array
    public Bricks [] brick = new Bricks[COLUMN*ROW];

    //number array to save
    public int [] cell = new int[COLUMN*ROW];

    //coordinate variables
    private int x=0;
    private int y=0;

    Selector s = new Selector();

    //constructor
    public MapGrid()
        //sets size, layout, and background colour
        setPreferredSize(new Dimension(MAPGRID_WIDTH, MAPGRID_HEIGHT));
        setLayout(new GridLayout(ROW, COLUMN));

        addMouseListener(this);

        //draws grid of bricks
        for (int i = 0; i <COLUMN*ROW; i++)
            cell[i] = 4;
            if ((i%COLUMN==0)&&(i>COLUMN-1))
                x=0;
                y+=22;
            
            brick[i] = new Bricks(x,y);
            x+=40;
        
    //constructor end

    //draws bricks
    public void paint(Graphics g)
        super.paint(g);
        for (int i = 0; i <COLUMN*ROW; i++)
            brick[i].draw(g);
        
    //paint end

    public void mousePressed(MouseEvent evt) 
        //gets mouse  and y coordinates
        int x = evt.getX();
        int y = evt.getY();

        //gets column and row of mouse location
        int c =x/BRICK_WIDTH;
        int r =y/BRICK_HEIGHT;

        //checks if mouse is within range
        if ((c>=0&&c<=COLUMN)&&(r>=0&&r<=ROW))
            int index = (r)*COLUMN+c; //calculates brick number

            //right click - delete brick
            if (evt.isMetaDown()) 
                brick[index].setChoice(4);
                cell[index]=4;
            
            //left click - draws brick
            else
                brick[index].setChoice(s.display);
                cell[index]=s.display;
            
        
        repaint();
    //mousePressed end

    //unused
    public void mouseEntered(MouseEvent evt)   
    public void mouseExited(MouseEvent evt)    
    public void mouseClicked(MouseEvent evt)   
    public void mouseReleased(MouseEvent evt) 
//class end

这是砖代码:

import java.awt.*;

public class Bricks implements Common

    //variables
    public int x=0;
    public int y=0;
    public int choice=3;
    public boolean clear = true;

    //size of bricks
    private static final int width = BRICK_WIDTH;
    private static final int height = BRICK_HEIGHT;

    //constructor
    public Bricks(int x, int y)
        this.x=x;
        this.y=y;
    //constructor end

    //draw bricks
    public void draw(Graphics g)
        //set color or blank
        switch(choice)
            case 0: g.setColor(Color.BLACK);
                break;
            case 1: g.setColor(Color.YELLOW);
                break;
            case 2: g.setColor(Color.RED);
                break;
            case 3: g.setColor(Color.ORANGE);
                break;
            case 4: clear = true;
                break;
        

        //check if set blank
        if (clear==true)
            g.setColor(Color.BLACK);
            g.drawRect(x,y,width,height);
        
        else
            g.fillRect(x,y,width,height);
        
    //draw end

    //set choice of color
    public void setChoice (int c)
        choice=c;
        clear = false;
    //choice end
//class end

【问题讨论】:

如需尽快获得更好的帮助,请发帖SSCCE。 @Andrew Thompson 感谢您教人们如何正确提问,但在每个问题中看到相同的评论真的很奇怪:( @iShaalan “感谢您教人们如何正确提问” 这不是“正确的”,而只是“有助于获得答案”。使用“适当”一词特别聪明 - 原因请参见 this thread。 @iShaalan:您在这里闲逛的次数越多,您对回答问题的贡献就越大,您就越会看到 Andrew 最初的评论有多么有用。如果原贴可以贴一个简洁的、可编译的小程序,我们可以自己编译运行,不用修改,我们可以观察看到他的问题,我们可以修改以尝试解决他的问题,那么这通常会导致一个快速、完整的程序。和充实的解决方案。没有什么比这个概念更胜一筹了,所以以一种非威胁、非对抗的方式提出它经常很有帮助,比你的评论更有用。 下次我会尽量让它更紧凑。不过还是谢谢你的帮助。 【参考方案1】:

你的问题在这里:

public class MapGrid extends JPanel implements Common, MouseListener
    //...

    Selector s = new Selector();  // ******* HERE **********

    // ...

    public void mousePressed(MouseEvent evt) 
        // ....

            else
                brick[index].setChoice(s.display);
                cell[index]=s.display;
            
        // ....
    

    //...

您在上面创建了一个新的 Selector 对象,但它可能与您的 GUI 中显示的 Selector 对象完全不同。因此,GUI 持有和显示的 Selector 状态的更改不会反映在您上面使用的 Selector 对象中。

要解决此问题,请确保 Selector 变量引用 GUI 中显示的同一个 Selector。

例如,将其更改为:

public class MapGrid extends JPanel implements Common, MouseListener
    //...

    Selector s = null;

    public MapGrid(Selector s) 
      this.s = s;
    

    // .... etc....

然后,当您创建 MapGrid 对象时,请务必传入对显示的真实 Selector 实例的引用。

【讨论】:

我今天没有上网。谢谢回答。这对我有用。

以上是关于当 Int 更改时,一个 JPanel 中 MousePressed 中的 Int 值不会更新的主要内容,如果未能解决你的问题,请参考以下文章

在 JFrame 上更改 JPanel 组件时无法显示它

java swing编程问题:一个jframe中添加一个jpanel后,为jpanel添加一个滚动条,当jpanel中内容过多时滑动

当面板中的 JButton 悬停时,JPanel 上的 MouseExited 运行?

使用框架状态变量更新 JFrame 中的 JPanel 内容

如何将变量打印到 JPanel 中,然后在变量更改时使用 main 方法重新打印变量?

jQuery - DOM更改后悬停