2014-03-03 82 views
0

当前显示一个带有8x8随机彩色按钮网格的GUI。 newButton是将乐谱显示重置为0,并重新设置网格,类似于它在点击后启动时的效果。除了Java处理按钮和分层方式的方式之外,我还找不到许多解决方案。这是我正在使用的2个课程。JButtons不会更新按钮单击

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; } 
} 
+2

好吧,现在我已经读了五次这个问题,你有什么问题? – MadProgrammer

+0

@MadProgrammer对不起,当我点击“新游戏”按钮时,8x8网格不会随新的随机彩色图标更新。我相信它只是在程序启动时创建的第一个8x8网格之下进行分层。 – user3373360

+0

不确定这是否与我们的问题有关,但[** this answer **](http://stackoverflow.com/a/22110203/2587435)使用布局管理器(如您应该这样做)而不是设置位置和大小。看起来似乎与你的情况类似,即使它不能解决这个特殊问题,也许你会获得某种形式的东西。 –

回答

2

建立在this answer指出什么(使用布局管理器而不是设置大小,因为你应该在做)你可以通过循环浏览JPanel的组件(JLabels)并更改它们的图标来重置图像。

这个特殊的例子使用JLabelsMouseListeners但它可以很容易地与ActionListeners

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]); 
     } 
    } 
} 

enter image description here

下面是完整的运行代码,切换到JButtons。你只需要更换图像路径。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.FlowLayout; 
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 java.util.Random; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.border.LineBorder; 

public class CircleImages { 

    private int score = 0; 
    private JTextField scoreField = new JTextField(10); 

    public CircleImages() { 
     scoreField.setEditable(false); 

     final ImageIcon[] icons = createImageIcons(); 
     final JPanel iconPanel = createPanel(icons, 8); 

     JPanel bottomLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); 
     bottomLeftPanel.add(new JLabel("Score: ")); 
     bottomLeftPanel.add(scoreField); 

     JPanel bottomRightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING)); 
     JButton newGame = new JButton("New Game"); 
     bottomRightPanel.add(newGame); 
     JButton quit = new JButton("Quit"); 
     bottomRightPanel.add(quit); 

     JPanel bottomPanel = new JPanel(new GridLayout(1, 2)); 
     bottomPanel.add(bottomLeftPanel); 
     bottomPanel.add(bottomRightPanel); 

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

     JFrame frame = new JFrame(); 
     frame.add(iconPanel); 
     frame.add(bottomPanel, BorderLayout.PAGE_END); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    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]); 
      } 
     } 
    } 

    private JPanel createPanel(ImageIcon[] icons, int gridSize) { 
     Random random = new Random(); 
     JPanel panel = new JPanel(new GridLayout(gridSize, gridSize)); 
     for (int i = 0; i < gridSize * gridSize; i++) { 
      int index = random.nextInt(icons.length); 
      JLabel label = new JLabel(icons[index]); 
      label.addMouseListener(new MouseAdapter(){ 
       public void mouseClicked(MouseEvent e) { 
        score += 1; 
        scoreField.setText(String.valueOf(score)); 
       } 
      }); 
      label.setBorder(new LineBorder(Color.GRAY, 2)); 
      panel.add(label); 
     } 
     return panel; 
    } 

    private ImageIcon[] createImageIcons() { 
     String[] files = {"blackcircle.png", 
      "bluecircle.png", 
      "greencircle.png", 
      "greycircle.png", 
      "orangecircle.png", 
      "redcircle.png", 
      "yellowcircle.png" 
     }; 
     ImageIcon[] icons = new ImageIcon[files.length]; 
     for (int i = 0; i < files.length; i++) { 
      icons[i] = new ImageIcon(getClass().getResource("/circles/" + files[i])); 
     } 
     return icons; 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new CircleImages(); 
      } 
     }); 
    } 
} 
+0

谢谢,这会起作用 – user3373360

2

您在resetButtons2()创建新组按钮,并把它们放在顶部(或者说下)已经存在一组在同一地点按钮组成。您应该创建一组按钮,并且只能在重置时更新其图标。

你应该做一些事情:

  • 使用适当的布局管理器,例如,网格布局
  • 创建按钮的8X8格只有一次,必要时更换它们的图标
  • 呼叫无效/重绘刷新内容窗格

而对于一个JFrame你不需要getContentPane().add(...),你可以直接做add(...)

+0

我将如何去取代它们?用列表? – user3373360

+0

您可以使用数组,就像使用'icons'一样。 – Kavka

2

两件事。

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

二,利用合适的布局管理器。 A null布局是一个非常糟糕的主意。您不控制底层平台的字体指标,这将改变您的按钮在不同系统上的外观,从而使您的UI不那么动态,那么它应该是

+0

如何“删除”现有的按钮? – user3373360

+0

鉴于你没有提及他们,很难。你可以使用一个'getComponents'和一个循环结果数组在'for-loop'中寻找'JButton'的实例...但是'List'将会更加简单 – MadProgrammer