【问题标题】:paintComponent() and JColorChooserpaintComponent() 和 JColorChooser
【发布时间】:2014-12-05 17:12:24
【问题描述】:

我正在尝试为课堂编写程序,但我被卡住了。我需要创建一个形状(我的初始形状),然后用 JColorChooser 填充它。我已经能够使用绘画和图形创建我的初始。然后我可以使用 g.setColor(new Color(11, 139, 198)); 填充我的形状。我不知道如何为此添加 JColorChooser。这是我的第一篇文章,所以让我知道我可以做些什么来使它更容易阅读。 这是我的代码:

/* Program - Letter 
 * Program Desc - 
 * Programmer - Bradon Fredrickson
 * Class - 
 * Created - Oct 1, 2014
 */
package letter;

import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Letter
{

    public static void PlainLetter()
    {
        /*
         * Creating GUI for letter
         */
        LetterDraw plainLetter = new LetterDraw();
        JFrame logo = new JFrame("My Logos");
        JLabel plain = new JLabel("Plain Letter");
        plain.setLocation(10, 0);
        plain.add(plainLetter);
        Container pane = logo.getContentPane();
        pane.setLayout(new GridLayout(1, 1));
        logo.setLocationRelativeTo(null); // Center the frame
        logo.add(plainLetter);
        logo.setVisible(true);
        logo.setSize(400, 200);
        logo.setLocation(400, 200);
        logo.setVisible(true);
        logo.setDefaultCloseOperation(logo.EXIT_ON_CLOSE);
    }//end plain letter

    public static void main(String[] args)
    {
        PlainLetter();
        new ColorChooser();
    }//end main method
}//end Letter

第二类——这是在画我的对象

/* Program - ThirdLetter 
 * Program Desc - 
 * Programmer - Bradon Fredrickson
 * Class - 
 * Created - Oct 6, 2014
 */

package letter;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.JPanel;

public class LetterDraw extends JPanel
{

    /*
     * Creating my shape/letter
     */
    public void paint(Graphics graphics)
    {

        Path2D.Double path = new Path2D.Double();
        Graphics2D g = (Graphics2D) graphics;
        path.moveTo(17, 63);
        /*
         * Top Horizontal Line
         */
        path.curveTo(21, 60, 21, 43, 17, 37); //left vert
        path.curveTo(30, 43, 100, 43, 120, 37); //top horiz
        path.curveTo(115, 45, 115, 57, 117, 62); //right vert
        path.curveTo(105, 53, 60, 57, 17, 63); //bottom horiz right
        /*
         * Bottom Horizontal Line
         */
        path.moveTo(32, 97);
        path.curveTo(37, 85, 35, 79, 35, 77); //left vert
        path.curveTo(45, 79, 45, 79, 100, 79); //top left horiz
        path.curveTo(96, 85, 98, 92, 98, 98);//right vert
        path.curveTo(89, 93, 79, 94, 32, 97);//bottom right horiz
        /*
         * Vertical Line
         */
        path.moveTo(40, 130);
        path.curveTo(48, 110, 46, 70, 37, 55); //left vert
        path.curveTo(62, 55, 62, 55, 60, 55); //top horiz
        path.curveTo(68, 80, 68, 100, 63, 130); //right vert
        path.curveTo(60, 127, 50, 127, 40, 130);//bottom horiz
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setStroke(new BasicStroke(3));
        //g.setStroke(new BasicStroke(4, BasicStroke.JOIN_BEVEL, 0));
        g.draw(path);
        g.setColor(new Color(11, 139, 198));
        g.fill(path);
    }//end paint
}//end LetterDraw

第三个 - 这是我的颜色选择器

/* Program - ColorChooser 
 * Program Desc - 
 * Programmer - Bradon Fredrickson
 * Class - 
 * Created - Oct 10, 2014
 */
package letter;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ColorChooser
{

    /**
     * Creating the color chooser
     */
    public ColorChooser()
    {
        JFrame frame = new JFrame("JColorChooser Popup");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JLabel label = new JLabel("www.java2s.com", JLabel.CENTER);
        label.setFont(new Font("Serif", Font.BOLD | Font.ITALIC, 48));

        frame.add(label, BorderLayout.NORTH);

        final JColorChooser colorChooser = new JColorChooser(label.
                getBackground());

        ColorSelectionModel model = colorChooser.getSelectionModel();
        ChangeListener changeListener = new ChangeListener()
        {
            public void stateChanged(ChangeEvent changeEvent)
            {
                Color newForegroundColor = colorChooser.getColor();
                label.setForeground(newForegroundColor);
            }
        };
        model.addChangeListener(changeListener);

        frame.add(colorChooser, BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);
    }//end colorChooser
}//end colorChooser class

现在我得到 2 个 JFrame,1 个用于我的形状,1 个用于 JColorChooser。我也想把它们都放在一帧里。

【问题讨论】:

标签: java swing paintcomponent jcolorchooser


【解决方案1】:

在您的 LetterDraw 课程中,而不是这样做

g.setColor(new Color(11, 139, 198));

最好有一个类成员Color color,并有一个设置器。然后就这样做

public class LetterDraw extends JPanel {
    private Color color = Color.BLUE; // default;

    public void setColor(Color color) {
        this.color = color;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        ...
        g.setColor(color);
    }
}

注意paintComponentsuper.paintComponent。请参阅 cmets 中 @trashgod 的链接。

关于颜色选择,JColorChooser 有一个静态方法,您可以从中调用以显示颜色选择器对话框并从中获取返回的颜色。然后,您可以使用该颜色在LetterDraw 上调用setColor。无需创建自己的框架。例如。

Color color = JColorChooser.showDialog(null, "title", Color.BLUE);
letterDraw.setColor(color);

如果您想保持颜色选择器框架打开并使用您当前的代码,您需要使用某种 MVC/Observer 设计,或者将 LetterDraw 的实例传递给 ColorChooser构造函数,以便它可以在改变颜色后调用LetterDraw's设置颜色方法。

“我也想把它们都放在一帧中”

我刚刚注意到问题的那一部分。

您可能会忘记 ColorChooser 类并在 Letter 类中创建 JColorChooser。所以你可以访问LetterDraw 对象。下面是重构的样子

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Letter {

    LetterDraw letterDraw = new LetterDraw();

    public Letter() {
        JFrame frame = new JFrame();
        JPanel letterDrawWrapper = new JPanel(new GridBagLayout());
        letterDrawWrapper.add(letterDraw);
        frame.add(letterDrawWrapper);
        frame.add(createColorChooser(), BorderLayout.PAGE_END);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JColorChooser createColorChooser() {
        JColorChooser colorChooser = new JColorChooser();
        colorChooser.getSelectionModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                letterDraw.setColor(colorChooser.getColor());
            }
        });
        return colorChooser;
    }

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

class LetterDraw extends JPanel {

    private Color color;

    public void setColor(Color color) {
        this.color = color;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Path2D.Double path = new Path2D.Double();
        Graphics2D g = (Graphics2D) graphics;
        path.moveTo(17, 63);
        /*
         * Top Horizontal Line
         */
        path.curveTo(21, 60, 21, 43, 17, 37); //left vert
        path.curveTo(30, 43, 100, 43, 120, 37); //top horiz
        path.curveTo(115, 45, 115, 57, 117, 62); //right vert
        path.curveTo(105, 53, 60, 57, 17, 63); //bottom horiz right
            /*
         * Bottom Horizontal Line
         */
        path.moveTo(32, 97);
        path.curveTo(37, 85, 35, 79, 35, 77); //left vert
        path.curveTo(45, 79, 45, 79, 100, 79); //top left horiz
        path.curveTo(96, 85, 98, 92, 98, 98);//right vert
        path.curveTo(89, 93, 79, 94, 32, 97);//bottom right horiz
            /*
         * Vertical Line
         */
        path.moveTo(40, 130);
        path.curveTo(48, 110, 46, 70, 37, 55); //left vert
        path.curveTo(62, 55, 62, 55, 60, 55); //top horiz
        path.curveTo(68, 80, 68, 100, 63, 130); //right vert
        path.curveTo(60, 127, 50, 127, 40, 130);//bottom horiz
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setStroke(new BasicStroke(3));
        //g.setStroke(new BasicStroke(4, BasicStroke.JOIN_BEVEL, 0));
        g.draw(path);
        g.setColor(color);
        g.fill(path);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(150, 150);
    }
}

【讨论】:

  • 感谢您的回复。今天晚些时候我会尝试一下,但这看起来就是我需要的!谢谢!
  • 抱歉回复晚了,周末很忙,刚开始更新我的代码。非常感谢,这正是我所需要的。我已经尝试了好几天,而且我越来越接近了,但我不知道我是否会弄明白。我试图理解你所做的一切。 Dimension getPreferedSize() 方法究竟做了什么?这就是你让我的形状在 JFrame 顶部居中的方式吗?
  • getPreferredSize() 给面板一个preferredSize。一些布局管理器将使用此 preferredSize 来调整面板的大小。 JFrame 有一个默认的BorderLayout,它不关心preferredSize。它将拉伸面板以适应。这不是我使用GridBagLayout 将您的绘图面板包装在另一个面板中的内容,它确实尊重preferredSize。如果我没有设置preferredSize并且没有包裹面板,面板会被拉伸到框架的边缘,x,y坐标会导致绘图偏向左上角
  • 您可以通过取出包装面板并更改布局管理器来玩弄它,您会看到不同之处。有关布局管理器的更多信息,请参阅Laying Out Components Withing a Container
  • 至于居中,GridBagLayout 默认情况下将您添加到其中的组件居中。因此,包装面板在将绘图面板添加到其中时,会将绘图面板居中。另外,在玩它的时候,为绘图面板设置一个边框,这样你就可以更好地看到变化。类似setBackground(new LineBorder(Color.BLACK, 3));
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 2018-07-01
  • 2012-02-15
  • 2019-06-27
  • 2012-03-18
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多