【问题标题】:Passing Color object between two views to be used in JButton background在 JButton 背景中使用的两个视图之间传递颜色对象
【发布时间】:2015-10-06 16:41:36
【问题描述】:

我正在尝试制作一个三选项卡桌面应用程序,其中 tab1:添加/删除按钮,用于添加/删除 0-20 JButtons with tab2:用户可选颜色 (JColorChooser) 和 tab3,用于显示统计信息,例如 tab1 中的按钮数和最新的颜色。 我的问题:我在这里收到了很好的提示(感谢充满鳗鱼的气垫船!)我设法添加了一个 PropertyChangeListener,实际上该颜色现在是面板的可显示背景 - 而我想将它用于新的 JButtons。 Tab3 也需要同样的方式......最好同时显示完整的 Main 和 Colors.java:

package com.company;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class Main extends JComponent{

    public Dimension getPreferredSize() {
        return new Dimension(700, 500);
    }
    static int value = 0;

    private static void showGUI() {

        Colors colors = new Colors();  //a new instance of class (JColorchooser)

        JButton[] jbn = new JButton[20];  //Array of 20 buttons (to be added/removed 1 by 1)

        JFrame window = new JFrame("Panels JG");
        window.add(new Main());
        window.pack();
        window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);
        window.setVisible(true);

            /* Creating the needed JPanels and their layouts */
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(4, 4, 10, 10));
        JPanel bottom = new JPanel();
        bottom.setLayout(new FlowLayout());
        JPanel frontPg = new JPanel(new GridLayout(2, 1 , 25, 25));
        JPanel stats = new JPanel();

        /* Need to get two panels in the first view */
        frontPg.add(panel, BorderLayout.NORTH);
        frontPg.add(bottom, BorderLayout.SOUTH);

        /* Adding tabs to JFrame   */
        JTabbedPane tabs = new JTabbedPane();
        window.add(tabs);
        tabs.addTab("Boxes", frontPg);
        tabs.addTab("Color Select", colors);
        tabs.addTab("Details", stats);

        /* Add and del button for adding and removing boxes (JButtons) in the first tab */
        JButton a = new JButton("Add");
        JButton d = new JButton("Del");

        // Alternative for placing the buttons to the right place:
        a.setBounds(300, 650, 80, 25);
        d.setBounds(400, 650, 80, 25);
        bottom.add(a);
        bottom.add(d);

        window.setVisible(true);
        a.setVisible(true);
        d.setVisible(true);

        // add a PropertyChangeListener to our Colors isntance.
        colors.addPropertyChangeListener(Colors.NEW_COLOR,
                new PropertyChangeListener() {

                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        Color col = (Color) evt.getNewValue();
                        panel.setBackground(col);
                        System.out.println("BGcolor = " + col);
                        //this "test" above shows it is the right 'col' needed elsewhere too
                    }
                });
        // eof listener

        JLabel label1 = new JLabel();
        JLabel label2 = new JLabel();
        JLabel label3 = new JLabel();

        a.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Click add");
                Color col = null;  //how should this Color object be initiated really...

                if (value < 20) {

                    jbn[value] = new JButton(String.valueOf(value));
                    col = Color.getColor(Colors.NEW_COLOR);
                    System.out.println("jb1 color = " + col);

                    // CAN IT BE RESIZED? YES IT CAN WHILE GENERALLY NOT RECOMMENDED...
                    Dimension d;
                    d = new Dimension(30, 50);
                    jbn[value].setMinimumSize(d);
                    d = new Dimension(100, 50);
                    jbn[value].setMaximumSize(d);
                    d = new Dimension(40, 50);
                    jbn[value].setPreferredSize(d);
                    jbn[value].setOpaque(true);
                    panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

                    //HERE IS THE PROBLEM - col is always null... It just paints w/ WHITE.
                    if(col!=null){
                        jbn[value].setBackground(col);
                        jbn[value].addActionListener(this);
                        panel.add(jbn[value]);
                        panel.setVisible(true);
                    }
                    else {
                        jbn[value].setBackground(Color.WHITE);
                        panel.add(jbn[value]);
                        panel.setVisible(true);
                    }
                    window.pack();

                    d = new Dimension(700, 500);
                    window.setSize(d);

                    value++;
                    label1.setText("        Count of boxes ");
                    label2.setText("        " + (String.valueOf(value)));
                    label3.setText("        Current Color");

                    label1.setFont(label1.getFont().deriveFont(16.0f));
                    label2.setFont(label2.getFont().deriveFont(20.0f));
                    label3.setFont(label1.getFont().deriveFont(16.0f));

                    stats.setLayout(new GridLayout(4, 1, 10, 100));
                    stats.add(label1);
                    stats.add(label2);
                    stats.add(label3);

                    // ADDING FILLRECT OR SIMILAR TO LAST TAB for showing the latest color
                    label1.repaint();
                    label2.repaint();
                    label3.repaint();
                }

                else {
                    System.out.println("Max box count reached");
                }

            }
        });


        d.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Click del");
                //HOW TO REMOVE THE LATEST ADDED PANEL?
                value = value-1;

            }
        });
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(new Color(35, 45, 55));
        g2d.fillRect(200, 500, 35, 35);
    }

    public static void main(String[] args) {

        showGUI();
    }
}

最新版本的 Colors.java 如下:

package com.company;
import java.awt.event.*;
import javax.swing.colorchooser.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

@SuppressWarnings("serial")
class Colors extends JPanel implements ChangeListener {
    public static final String NEW_COLOR = "new color";
    private JColorChooser jcc = null;
    protected JLabel title;
    private Color newColor = null;

    public Colors() {
        super(new BorderLayout());

        // Set up the banner at the top of the window
        title = new JLabel("  ", SwingConstants.CENTER);

        // Set up color chooser for setting text color
        jcc = new JColorChooser(title.getForeground());
        jcc.getSelectionModel().addChangeListener(this);
        jcc.setBorder(BorderFactory.createTitledBorder("Choose New Color"));

        AbstractColorChooserPanel[] panels=jcc.getChooserPanels();
        for(AbstractColorChooserPanel p:panels) {
            String displayName = p.getDisplayName();
            switch (displayName) {
                case "HSV":
                    jcc.removeChooserPanel(p);
                    break;
                case "HSL":
                    jcc.removeChooserPanel(p);
                    break;
                case "CMYK":
                    jcc.removeChooserPanel(p);
                    break;
                case "RGB":
                    jcc.removeChooserPanel(p);
                    break;
            }
        }

        add(jcc, BorderLayout.CENTER);
        add(title, BorderLayout.PAGE_START);
    }

    public void stateChanged(ChangeEvent e) {
        // Color newColor = jcc.getColor();
        Color oldValue = newColor;
        newColor = jcc.getColor();

        // fire a notification to the Colors JPanel's property change support
        // object. Any listeners will be notified of the color change
        firePropertyChange(NEW_COLOR, oldValue, newColor);
        title.setForeground(newColor);
    }

    public Color getNewCol() {
        System.out.println("this now =" + newColor);
        return newColor;
    }


    public static Component createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("Color Selector");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new Colors();
        return newContentPane;



    }
}

也有 cmets (open questions) inline...指出有问题的地方(对我来说就是这样!)

【问题讨论】:

  • .......你好??

标签: java swing class colors instance


【解决方案1】:

在我看来,您的问题不是如何获取颜色值,而是 何时 获取它们。既然您希望用户在创建按钮时选择一种新颜色,那么在创建 ActionListener 时,为什么不在 JOptionPane 之类的模态 JDialog 中显示颜色面板并以这种方式获得选择。比如……

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class SelectButtonColor extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = 400;
    private static final int COLUMNS = 4;
    private List<AbstractButton> buttonList = new ArrayList<>();
    private JPanel buttonPanel = new JPanel(new GridLayout(0, COLUMNS, 5, 5));
    private int buttonCount = 0;
    private Colors colors = new Colors();

    public SelectButtonColor() {
        JButton addButton = new JButton(new AddAction("Add"));

        JPanel southPanel = new JPanel();
        southPanel.add(addButton);

        JPanel innerBorderPanel = new JPanel(new BorderLayout());
        innerBorderPanel.add(buttonPanel, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(innerBorderPanel);

        setLayout(new BorderLayout());
        add(scrollPane, BorderLayout.CENTER);
        add(southPanel, BorderLayout.PAGE_END);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class AddAction extends AbstractAction {
        public AddAction(String name) {
            super(name);
            int mnenonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnenonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Component parent = SelectButtonColor.this;
            Object message = colors;
            String title = "Select a Button Color";
            int optionType = JOptionPane.OK_CANCEL_OPTION;
            int response = JOptionPane.showConfirmDialog(parent, message, title, optionType);
            if (response == JOptionPane.OK_OPTION) {
                Color color = colors.getNewCol();
                String text = "" + buttonCount;
                JButton button = new JButton(text);
                button.setBackground(color);
                buttonPanel.add(button);
                buttonList.add(button);
                buttonCount++;
                buttonPanel.revalidate();
                buttonPanel.repaint();
            }
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("SelectButtonColor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SelectButtonColor());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

顺便说一句,请尝试为您在此处发布的示例使用更简洁的代码,因为这将使所有人更容易理解和帮助。此外,您几乎不想重写paint 方法,而是重写paintComponent 方法。

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    相关资源
    最近更新 更多