绘制使用自己的 Painter 创建的 JPanel
Posted
技术标签:
【中文标题】绘制使用自己的 Painter 创建的 JPanel【英文标题】:Painting the JPanel which created with own Painter 【发布时间】:2016-05-10 04:21:16 【问题描述】:我需要学习如何更改创建自己的 Painter 方法的JPanel
颜色的逻辑。我创建了一个示例项目用于说明;
问题:按钮操作中的直接颜色更改代码不会改变任何内容。
问题 1) 覆盖 paintComponent
方法是否适合在创建面板时使用 JPanel
绘制 Gradient
颜色?
问题 2) 如何将 JPanel
的背景颜色更改为其他 Gradient
颜色或 Direct
颜色?
--代码--
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);
【问题讨论】:
当你重写paintComponent时,你的方法必须做的第一件事就是调用super.paintComponent(g);
。
"问题 1) 是否覆盖paintComponent 方法是在面板创建时使用渐变颜色绘制JPanel 的正确方法? - 是的;但见 VGR 评论; *"问题 2) 如何用其他渐变颜色或直接颜色更改此 JPanel 的背景颜色? - 使用实例字段存储当前值,使用 setter 更改它们并使用 getter 检索它们,调用repaint
在组件上安排重绘。
避免使用null
布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正
【参考方案1】:
我重新排列了您的一些代码以解决其他问题。
这是我创建的 GUI。
这是我左键单击按钮后的 GUI。
我对您的代码进行了以下更改。
我将所有 JFrame 代码移到一个 run 方法中,这样我就可以尽快摆脱静态方法并进入面向对象的类和方法中。
我添加了对 SwingUtilitiles 的 invokeLater 方法的调用,以确保在 Event Dispatch thread 上创建和修改 Swing 组件。
我创建了一个 createMainPanel 方法来创建主面板。我没有使用带有像素精度设置的丑陋空布局,而是使用了Swing layout(BorderLayout)来定位组件。这允许用户扩展 GUI 以填充屏幕,以及适合具有不同屏幕尺寸的不同计算机的 GUI。
ImagePanel 类是一个完整的一流 Java 类。这意味着您可以拥有类字段和类构造函数。我提供了一种从课外设置颜色的方法。如果您不想要渐变,请将两种颜色设置为相同的颜色。
ImagePanel 类的paintComponent 方法应以超级调用开始,以维护Swing Paint 链。 paintComponent 方法除了绘画什么都不做。时期。句号。没有其他的。与绘画无关的代码我删除了。
查看 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);
【讨论】:
首先感谢吉尔伯特的努力。这个真的很有借鉴意义。我从你的代码中学到了一些机制。但是我使用 NetBeans GUI Builder 来创建 GUI,并且我有很多 JPanel 用于更改颜色取决于一些 if else 语句。我如何将您的解决方案实施到我还不知道的整个真实项目中。但请仔细阅读您的示例,谢谢。 我以非常不同的方式解决了我的问题。很难解释,但这个解决方案足以说明这个问题。我会接受答案。再次感谢您。以上是关于绘制使用自己的 Painter 创建的 JPanel的主要内容,如果未能解决你的问题,请参考以下文章