2016-03-07 37 views
1

我想編寫我的程序,以便我的JFrame上的所有組件都具有一致的配色方案。爲了做到這一點,我想用Java的for-each循環來影響同一類型的每個組件。我已經嘗試過爲JPanel着色,但它沒有任何影響。Java - 選擇所有類型的GUI組件

public void colourGUI() 
{ 
    for (Component comp : this.getComponents()) 
    { 
     if (comp instanceof JPanel) 
     { 
      ((JPanel) comp).setOpaque(true); 
      comp.setBackground(Color.gray); 
     } 
    } 
} 

我會想象這會工作,但是當我加載應用程序它沒有影響。 我對Java很新,我以前使用C#作爲這樣的程序,我會使用C#的OfType<>方法。我希望Java會有一些相同的東西,但我還沒有找到任何東西。

任何人都可以指出我正確的方向來完成我期待的目標嗎?我想我錯過了一些非常明顯的東西!

謝謝, 馬克

+0

難道你沒有使用'repaint()'和'revalidate()'? – Dan

+0

嗨,就像我說我不太熟悉Java的方法。我什麼時候需要使用這些? @丹 – marcuthh

+0

我剛發佈了一個答案。如果它不起作用,請發表評論 – Dan

回答

2

我爲我的第一個答案道歉。如本例中所示,您的代碼,

public void colourGUI() 
{ 
    for (Component comp : this.getComponents()) 
    { 
     if (comp instanceof JPanel) 
     { 
      ((JPanel) comp).setOpaque(true); 
      comp.setBackground(Color.gray); 
     } 
    } 
} 

,確實沒有改變地工作。

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.event.*; 
import java.awt.Color.*; 
import java.io.IOException; 
import java.lang.*; 
import java.util.*; 

public class Test extends JFrame { 
    private Box boxHolder; 
    private JPanel scrollPaneContainer; 

    Test(int i) { 
     super("Test Frame"); 
     this.setLayout(new BorderLayout()); 
     this.getContentPane().add(initScrollPane(),BorderLayout.CENTER); 
     this.getContentPane().add(initButtonAdd(),BorderLayout.SOUTH); 

     for(int j = 0; j < i; j++) { 
      boxHolder.add(createPanel()); 
     } 

     this.setLocationRelativeTo(null); 
     this.pack(); 
     this.setVisible(true); 
    } 

    private Component initButtonAdd() { 
     JButton button = new JButton("Recolour"); 
     button.setBackground(Color.green); 
     button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Component comp : boxHolder.getComponents()) 
       { 
        if (comp instanceof JPanel) 
        { 
         ((JPanel) comp).setOpaque(true); 
         comp.setBackground(Color.gray); 
        } 
       } 
      } 
     }); 
     return button; 
    } 

    private Component initScrollPane() { 
     scrollPaneContainer = new JPanel(new BorderLayout()); 
     boxHolder = Box.createVerticalBox(); 
     scrollPaneContainer.add(boxHolder, BorderLayout.PAGE_START); 
     JScrollPane jSP = new JScrollPane(scrollPaneContainer); 
     jSP.getVerticalScrollBar().setUnitIncrement(16); 
     return jSP; 
    } 

    private Component createPanel() { 
     JPanel panel = new JPanel(); 
     panel.setBackground(randomColor()); 
     panel.setPreferredSize(new Dimension(100,50)); 
     panel.add(new JLabel("a colored Panel")); 
     panel.addMouseListener(new MouseListener() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       int indexPosition = boxHolder.getComponentZOrder(panel); 
       try 
       { 
        boxHolder.remove(indexPosition); 
       } 
       catch(Exception ex){} 
       try //Will only add here if you have a component in index position 1 
       { 
        boxHolder.add(createPanel(),indexPosition); 
       } 
       catch(Exception ex){} 
       scrollPaneContainer.revalidate(); 
      } 
      @Override public void mousePressed(MouseEvent e) {} 
      @Override public void mouseReleased(MouseEvent e) {} 
      @Override public void mouseEntered(MouseEvent e) {} 
      @Override public void mouseExited(MouseEvent e) {} 
     }); 
     return panel; 
    } 

    private Color randomColor() { 
     Random rand = new Random(); 
     float r = rand.nextFloat()/2f ; 
     float g = rand.nextFloat()/2f; 
     float b = rand.nextFloat()/2f; 
     Color randomColor = new Color(r, g, b); 
     return randomColor; 
    } 

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

你可以從你的GUI發佈更多的代碼嗎?

+0

剛剛嘗試過,沒有任何改變,是否還有比它更重要的事情? – marcuthh

+0

首先,該命令應該是revalidate()和repaint()。但是,無需執行此操作,因爲每當組件的屬性發生更改時,Swing組件都會自動執行此操作。 – camickr

0

當您問一個問題發佈一個合適的SSCCE,說明問題。基本的代碼看起來很合理,但是如果沒有SSCCE,我們不能說明這個代碼是如何被使用的。例如,我們不知道this.getComponents()是指什麼。

我想這個問題是,你的代碼不使用遞歸,所以你實際上並沒有得到框架上所有組件的列表。這很容易測試,只需在循環中添加一個顯示語句即可查看您實際找到的面板數量。

框架的結構比您想象的更復雜。請看Using Top Level Containers以更好地描述結構。

您可以使用Swing Utils類,該類使用遞歸獲取給定類型的所有子組件。