2016-04-03 67 views
1

我想向JFrame添加漸變背景。在JFrame中,我沒有創建JPanel,而是使用了創建JFrame時自動添加的JPanel。我在網上找到的所有例子都在JPanel實例上調用paintComponent(),但如前所述,在我的例子中,我沒有具體實例化一個例子。我知道paintComponent()需要在組件上調用,因此無法在JFrame上調用,那麼是否需要創建並添加JPanel才能實現此目的?我以前用這種方式取得了成功,但我試圖儘可能簡化我的代碼,所以如果我不需要,我不想創建第二個JPanel。這裏是我有的代碼:在默認JFrame面板上使用paintComponent()

public class Main extends JFrame { 

private static final long serialVersionUID = 1L; 

JPanel pane; 

public Main() { 

    int WIDTH = 700, HEIGHT = 400; 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBackground(Color.GRAY); 
    setSize(WIDTH, HEIGHT); 
    setLocationRelativeTo(null); 

    pane = (JPanel) getContentPane(); 
    pane.setOpaque(false); 
    pane.setLayout(new BorderLayout()); 
    pane.setBorder(new EmptyBorder(20, 20, 20, 20)); 

    // SOME OTHER STUFF 
    } 
    protected void paintComponent(Graphics grphcs) { 
    Graphics2D g2d = (Graphics2D) grphcs; 
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    GradientPaint gp = new GradientPaint(0, 0, new Color(255, 195, 225), 0, getHeight(), new Color(139, 207, 236)); 
    g2d.setPaint(gp); 
    paintComponent(grphcs); 
    } 
} 

任何幫助,我可以得到讚賞。

+0

請參閱編輯以回答。 –

回答

3

那麼我需要創建並添加一個JPanel才能實現這個目標?

是的。

但我試圖讓我的代碼儘可能簡化,所以我不想創建第二個JPanel,如果我不需要。

這裏沒有浪費,因爲簡化上述代碼的方法是擺脫extends JFrame。沒有必要這樣做,很多理由不這樣做。通過讓類擴展JFrame,迫使您創建和顯示JFrame,而且通常需要更多的靈活性,從而將自己繪製在一個角落。事實上,我敢打賭,我已經創建了大多數Swing GUI代碼,而且我已經看到了而不是擴展了JFrame,事實上很少有人會想要這樣做。更常見的是,您的GUI類將專門用於創建JPanel,然後可將其放置到JFrame或JDialogs或JTabbedPanes中,或在需要時通過CardLayouts進行交換。這將大大增加您的GUI編碼的靈活性。

例如,

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 

public class MainPanel extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private static final int PREF_W = 700; 
    private static final int PREF_H = 400; 
    private static final Color GRAD_COLOR_1 = new Color(255, 195, 225); 
    private static final Color GRAD_COLOR_2 = new Color(139, 207, 236); 

    public MainPanel() { 
     setBackground(Color.GRAY); 
     setSize(WIDTH, HEIGHT); 
     setLayout(new BorderLayout()); 
     setBorder(new EmptyBorder(20, 20, 20, 20)); 

     // SOME OTHER STUFF 
    } 

    // to set the preferred size of the JPanel/GUI 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    @Override 
    protected void paintComponent(Graphics grphcs) { 
     super.paintComponent(grphcs); // ** don't forget this. 
     Graphics2D g2d = (Graphics2D) grphcs; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     GradientPaint gp = new GradientPaint(0, 0, GRAD_COLOR_1, 0, getHeight(), GRAD_COLOR_2); 
     g2d.setPaint(gp); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 
    } 

    private static void createAndShowGui() { 
     MainPanel mainPanel = new MainPanel(); 

     // create the JFrame when/if needed 
     JFrame frame = new JFrame("Main"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      createAndShowGui(); 
     }); 
    } 
} 

但不會仍然產生不必要的JPanels?

這是擔心錯誤的事情。創建單個JPanel,contentPane,並且這不會對您的程序或您的資源使用產生真正的不利影響。

我的實際類擴展了JPanel,所以當我實例化創建了一個,加上我們創建JFrame時創建的默認面板。 是不是那種像我以前那樣,我的意思是我可以剛創建第二個JPanel並將其添加到我的主類(JFrame)並調用paintComponent()。

如上所述 - 不要讓山脈遠離鼴鼠山丘,也不要過早優化。如果您擔心程序中濫用資源,請對其進行分析,然後修復具有實際影響的問題。

什麼是延長的JPanel,而不是JFrame的

我提到的很多人已經優勢 - 對我的回答上面什麼特別混亂?

+0

謝謝,這將解決我的'paintComponent()'問題。但是它不會創建不需要的JPanel?我的實際類擴展了JPanel,所以當我實例化創建的時候,加上我們創建JFrame時創建的默認面板。是不是像我以前那樣,我的意思是我可以剛剛創建第二個JPanel並將其添加到我的主類(JFrame)並在其上調用'paintComponent()'。擴展JPanel而不是JFrame有什麼好處? – user3226170

+0

@ user3226170:查看編輯。你陷入了一個不成熟的優化陷阱,你會想擺脫它。 –

+0

我想我沒有得到的是當你提到我強迫自己創建並顯示JFrame時。我無法顯示沒有JFrame的JPanel,甚至在您的示例中創建了JFrame。那麼爲什麼不讓我的主類成爲JFrame並將面板添加到它呢?在我看來,JFrame是窗口的基礎,那麼爲什麼不從這個開始呢? – user3226170