2016-02-01 32 views
1

我需要学习如何创建自己的Painter方法的JPanel颜色。我为示例创建一个示例项目;绘制用自己的Painter创建的JPanel

问题:按钮操作中的直接颜色更改代码不会改变任何内容。

问题1)是覆盖paintComponent方法是有道油漆他JPanelGradient颜色,同时面板创造?

问题2)如何将此JPanel的背景颜色与其他Gradient颜色或Direct颜色更改为背景颜色?

--CODE--

package tryingproject2; 

import java.awt.Color; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 


public class TryingProject2 { 

    public static void main(String[] args) { 

     class ImagePanel extends JPanel{ 

      public void paintComponent(Graphics g) { 
       Graphics2D g2d = (Graphics2D) g; 
       int w = getWidth(); 
       int h = getHeight(); 
       Color color1; 
       Color color2; 
       color1 = new Color(223,130,24,255); 
       color2 = new Color(255,255,255,255); 

       GradientPaint gp = new GradientPaint(0, 0, color1, w, 0, color2); 
       g2d.setPaint(gp); 
       g2d.fillRect(0, 0, w, h); 
      } 

     } 

     JFrame frame = new JFrame(); 
     frame.setLayout(null); 
     frame.setSize(400,400); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel userPanel = new ImagePanel(); 
     userPanel.setBounds(100, 40, 200, 200); 
     userPanel.setLayout(null); 

     JLabel newLabel = new JLabel("Sample Label"); 
     newLabel.setBounds(50, 10, 100, 100); 
     userPanel.add(newLabel); 


     JButton button = new JButton("Change Color To Red"); 
     button.setBounds(100, 300, 200, 40); 
     button.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       userPanel.setBackground(Color.red); 
       userPanel.repaint(); 
       System.out.println("Button Pressed."); 
      } 
     }); 

     frame.add(userPanel); 
     frame.add(button); 
     frame.setVisible(true); 

    } 

} 
+2

当你重写paintComponent时,你的方法必须做的第一件事就是调用'super.paintComponent(g);'。 – VGR

+1

*“问题1)覆盖paintComponent方法是否适合使用面板创建时使用渐变颜色绘制JPanel?” - 是的;但请参阅VGR评论; *“问题2)如何用其他渐变颜色或直接颜色更改此JPanel的背景颜色?” - 使用实例字段来存储当前值,使用setter来更改它们,getter来检索它们,调用'repaint'在组件上安排重新绘制。 – MadProgrammer

+0

避免使用'null'布局,像素完美的布局是现代UI设计中的幻想。影响组件的个体大小的因素太多,其中没有一个可以控制。 Swing旨在与布局经理一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来尝试纠正 – MadProgrammer

回答

3

我重新安排你的一些代码来摆脱其他问题。

这是我创建的GUI。

Color Gradient GUI 1

这里的GUI我离开单击该按钮后。

Color Gradient GUI 2

我做了以下修改你的代码。

  1. 我感动了所有的JFrame代码到一个run方法,所以我能拿出来的静态方法和成面向对象的类和方法,尽可能快。

  2. 我加入到SwingUtilitiles的invokeLater方法的调用,以确保创建和修改对Event Dispatch thread组件摆动。

  3. 我创建了一个createMainPanel方法来创建主面板。我用一个Swing layout(BorderLayout)来定位组件,而不是用像素精度设置来使用丑陋的空布局。这允许用户扩展GUI以填充屏幕,以及GUI适合具有不同屏幕尺寸的不同计算机。

  4. ImagePanel类是一个完整的第一类Java类。这意味着你可以拥有类字段和类构造函数。我提供了一种设置课堂外颜色的方法。如果您不想使用渐变,请将两种颜色设置为相同的颜色。

  5. ImagePanel类的paintComponent方法应该以超级调用开始,以维护Swing Paint链。 paintComponent方法除了绘画之外不应该做任何事情。期。句号。没有其他的。我删除了与绘画无关的代码。

  6. 查看createMainPanel方法中的actionPerformed方法,您会看到如何更改渐变颜色之一并执行重绘。动作侦听器是GUI的控制器。只有控制器代码应该更改模型(ImagePanel中的颜色)或视图(ImagePanel和JFrame)。创建Swing GUI时始终寻找model/view/controller pattern

下面是修改后的代码。

package com.ggl.testing; 

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.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class TryingProject2 implements Runnable { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new TryingProject2()); 
    } 

    @Override 
    public void run() { 
     JFrame frame = new JFrame("Color Gradient Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.add(createMainPanel()); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private JPanel createMainPanel() { 
     JPanel panel = new JPanel(); 
     panel.setLayout(new BorderLayout()); 

     JPanel imageLabelPanel = new JPanel(); 
     imageLabelPanel.setLayout(new BorderLayout()); 

     final ImagePanel imagePanel = new ImagePanel(new Color(223, 130, 24, 
       255), new Color(255, 255, 255, 255)); 
     imageLabelPanel.add(imagePanel, BorderLayout.CENTER); 

     JLabel newLabel = new JLabel("Sample Label"); 
     newLabel.setHorizontalAlignment(JLabel.CENTER); 
     imageLabelPanel.add(newLabel, BorderLayout.SOUTH); 

     panel.add(imageLabelPanel, BorderLayout.CENTER); 

     JButton button = new JButton("Change Color To Red"); 
     button.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       imagePanel.setColor1(Color.RED); 
       imagePanel.repaint(); 
       System.out.println("Button Pressed."); 
      } 
     }); 
     panel.add(button, BorderLayout.SOUTH); 

     return panel; 
    } 

    public class ImagePanel extends JPanel { 

     private static final long serialVersionUID = 6970287820048941335L; 

     private Color color1; 
     private Color color2; 

     public ImagePanel(Color color1, Color color2) { 
      this.color1 = color1; 
      this.color2 = color2; 
      this.setPreferredSize(new Dimension(200, 200)); 
     } 

     public void setColor1(Color color1) { 
      this.color1 = color1; 
     } 

     public void setColor2(Color color2) { 
      this.color2 = color2; 
     } 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      Graphics2D g2d = (Graphics2D) g; 
      int w = getWidth(); 
      int h = getHeight(); 

      GradientPaint gp = new GradientPaint(0, 0, color1, w, 0, color2); 
      g2d.setPaint(gp); 
      g2d.fillRect(0, 0, w, h); 
     } 

    } 

} 
+0

感谢您的努力第一吉尔伯特。这个真的很有启发性。我从你的代码中学习一些机制。但是我使用NetBeans GUI Builder来创建GUI,并且我有许多用于更改颜色的JPanel取决于一些if else语句。我怎么能实现你的解决方案,我的整个真正的项目,我还不知道。但仔细阅读你的例子谢谢。 –

+0

我以非常不同的方式解决了我的问题。很难解释,但这个解决方案足以用于这个插图。我会接受答案。再次感谢你。 –