按钮点击后JButtons不会更新

时间:2014-03-03 03:28:57

标签: java jbutton

目前显示一个带有8x8随机彩色按钮网格的GUI。 newButton将分数显示重置为0并重新设置网格,就像点击后启动一样。我无法找到许多解决方案,除了它与Java显示它的按钮和分层工作方式有关。这是我正在使用的两个班级。

import javax.swing.JFrame; 
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.awt.Color;

public class ShinyButtonsApp extends JFrame implements ActionListener {

    private static byte ROWS = 8;
    public int useThis; 
    ShinyButtons shiny = new ShinyButtons();
    public static ImageIcon[] icons = {new ImageIcon("RedButton.png"),
                                       new ImageIcon("OrangeButton.png"), 
                                       new ImageIcon("YellowButton.png"), 
                                       new ImageIcon("GreenButton.png"), 
                                       new ImageIcon("BlueButton.png"), 
                                       new ImageIcon("LightGrayButton.png"), 
                                       new ImageIcon("DarkGrayButton.png")}; 


    public ShinyButtonsApp(String title) { 
        super(title); // Set title of window 
        setDefaultCloseOperation(EXIT_ON_CLOSE); // allow window to close 
        setSize(578, 634); // Set size of window 
        setResizable(false);

        getContentPane().setLayout(null);   

        JLabel aLabel = new JLabel("Score: "); 
        aLabel.setLocation(10, 570); 
        aLabel.setSize(80,30); 
        getContentPane().add(aLabel);

        JTextField scoreField = new JTextField(); 
        scoreField.setText(Integer.toString(shiny.score));
        scoreField.setEditable(false);
        scoreField.setHorizontalAlignment(JTextField.RIGHT);
        scoreField.setLocation(60, 570); 
        scoreField.setSize(120,30);
        scoreField.setBackground(Color.WHITE); 
        getContentPane().add(scoreField);

        JButton newButton = new JButton("New Game");
        newButton.addActionListener(this);
        newButton.setLocation(348,570);
        newButton.setSize(110,30);
        getContentPane().add(newButton);

        JButton quitButton = new JButton("Quit");
        quitButton.setLocation(468,570);
        quitButton.setSize(80,30);
        getContentPane().add(quitButton);

        resetButtons2();
    } 

    public void actionPerformed(ActionEvent e) {
                shiny.score = 0;
                shiny.resetButtons();
                resetButtons2();
    }

    public void resetButtons2() {
        for (int r=0; r<ROWS; r++) {
            for (int c=0; c<ROWS; c++) {
                ImageIcon image1 = icons[(int)shiny.getButton(r,c)];
                JButton button = new JButton(image1);
                button.setLocation(10+(69*r),10+(69*c));
                button.setSize(69,69);
                button.setBorder(BorderFactory.createLineBorder(Color.GRAY,1));
                getContentPane().add(button);
            }
        }
    }

    public static void main(String[] args) { 
        ShinyButtonsApp frame;      
        frame = new ShinyButtonsApp("Shiny Buttons"); // Create window 
        frame.setVisible(true); // Show window      
    }   
}

import javax.swing.JFrame; 
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.awt.Color;

public class ShinyButtons extends JPanel{ 
    public static byte RED = 0; 
    public static byte ORANGE = 1; 
    public static byte YELLOW = 2; 
    public static byte GREEN = 3; 
    public static byte BLUE = 4; 
    public static byte LIGHT_GRAY = 5; 
    public static byte DARK_GRAY = 6; 

    public static byte ROWS = 8; 

    public byte[][] buttonTable;

    public int score = 0; 

    public ShinyButtons() { 
        buttonTable = new byte[ROWS][ROWS]; 
        resetButtons(); 
    } 

    public void resetButtons() { 
        for (int r=0; r<ROWS; r++) 
            for (int c=0; c<ROWS; c++) 
                buttonTable[r][c] = (byte)(Math.random()*7); 
    } 

    public byte getButton(int r, int c) { return buttonTable[r][c]; } 

    public int getScore() { return score; }
} 

3 个答案:

答案 0 :(得分:2)

您正在resetButtons2()中创建一组新按钮,并将它们放在相同位置的现有按钮组的顶部(或更低)。您应该创建一次按钮组,并且仅在重置时更新它们的图标。

你应该做很多事情:

  • 使用适当的布局管理器,例如GridLayout
  • 仅创建一次8x8按钮网格,并在需要时替换其图标
  • 调用invalidate / repaint以刷新内容窗格

对于JFrame您不需要getContentPane().add(...),您可以直接add(...)

答案 1 :(得分:2)

两件事。

首先,确保先删除现有按钮。或者,您可以简单地更新按钮的状态。这将要求您首先创建一个数组或List按钮,然后您的重置方法将迭代并根据需要更新其属性。

其次,使用适当的布局管理器。 null布局是一个非常糟糕的主意。您无法控制底层平台的字体指标,这将改变您的按钮在不同系统上的显示方式,使您的UI不那么动态,应该是

答案 2 :(得分:2)

基于this answer指出的内容(使用布局管理器而不是设置大小,因为应该正在做),您可以通过循环组件来重置图像({ {1}} JLabels并更改其图标。

此特定示例将JPanelJLabels一起使用,但可以使用MouseListeners轻松切换到JButtons

ActionListeners

enter image description here

这是完整的运行代码。您只需要替换图像路径。

newGame.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
         reset(iconPanel, icons);               <--- call reset method from below
         score = 0;
         scoreField.setText(String.valueOf(score));
    }
});
....

private void reset(JPanel panel, ImageIcon[] icons) {
    Component[] comps = panel.getComponents();
    Random random = new Random();
    for(Component c : comps) {
        if (c instanceof JLabel) {
            JLabel button = (JLabel)c;
            int index = random.nextInt(icons.length);
            button.setIcon(icons[index]);
        }
    }
}