2014-03-03 158 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