2016-04-03 70 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