本文介绍了在两个视图之间传递Color对象以在JButton背景中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个三个选项卡桌面应用程序,其中tab1:添加/删除按钮添加/删除0-20 JButtons与tab2:用户可选择的颜色(JColorChooser)和tab3显示统计信息,如在tab1中的按钮计数和最新的颜色。
我的问题:有好的提示我在这里收到(感谢Hovercraft充分的Eels!)我设法添加一个PropertyChangeListener,实际上,该颜色是面板的可显示的背景 - 而我想要使用它新的JButton。也同样需要Tab3 ...更好地显示完整的Main和Colors.java:

  package com 。公司; 

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 = new Colors(); //一个新的类实例(JColorchooser)

JButton [] jbn = new JButton [20]; // 20个按钮的数组(要添加/删除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);

/ *创建所需的JPanels及其布局* /
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();

/ *需要在第一个视图中获取两个面板* /
frontPg.add(panel,BorderLayout.NORTH);
frontPg.add(bottom,BorderLayout.SOUTH);

/ *添加标签到JFrame * /
JTabbedPane tabs = new JTabbedPane();
window.add(tabs);
tabs.addTab(Boxes,frontPg);
tabs.addTab(Color Select,colors);
tabs.addTab(Details,stats);

/ *添加和删除第一个选项卡中添加和删除框(JButtons)的按钮* /
JButton a = new JButton(Add);
JButton d = new JButton(Del);

//将按钮放置到正确位置的替代方法:
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);

//向我们的颜色isntance添加PropertyChangeListener。
colors.addPropertyChangeListener(Colors.NEW_COLOR,
new PropertyChangeListener(){

@Override
public void propertyChange(PropertyChangeEvent evt){
Color col = (颜色)evt.getNewValue();
panel.setBackground(col);
System.out.println(BGcolor =+ col);
//它是正确的'col'在其他地方需要
}
});
// 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单击添加);
颜色col = null; //应该如何启动这个Color对象真的...

if(value< 20){

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

//可以调整大小吗?是的,一般不推荐...
尺寸d;
d =新尺寸(30,50);
jbn [value] .setMinimumSize(d);
d = new Dimension(100,50);
jbn [value] .setMaximumSize(d);
d = new Dimension
jbn [value] .setPreferredSize(d);
jbn [value] .setOpaque(true);
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

//这里是问题 - col总是null ...它只是涂抹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()。derivFont(16.0f));
label2.setFont(label2.getFont()。derivFont(20.0f));
label3.setFont(label1.getFont()。derivFont(16.0f));

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

//添加填充或类似于最后一个TAB以显示最新颜色
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单击del);
//如何删除最新添加的面板?
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的最新版本如下: / p>

  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)
类颜色extends JPanel实现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());

//设置窗口顶部的横幅
title = new JLabel(,SwingConstants.CENTER);

//设置颜色选择器以设置文本颜色
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){
caseHSV:
jcc.removeChooserPanel(p);
break;
caseHSL:
jcc.removeChooserPanel(p);
break;
caseCMYK:
jcc.removeChooserPanel(p);
break;
caseRGB:
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();

//通知颜色JPanel的属性更改支持
//对象。任何监听器都会通知颜色变化
firePropertyChange(NEW_COLOR,oldValue,newColor);
title.setForeground(newColor);
}

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


public static Component createAndShowGUI(){
//创建并设置窗口。
JFrame frame = new JFrame(Color Selector);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

//创建并设置内容窗格。
JComponent newContentPane = new Colors();
return newContentPane;



}
}
解决方案
还有注释(开放问题)inline ...指出有问题的区域>我的视图中的问题不是如何获取颜色值,而是获取它们。由于希望用户在创建按钮时选择新颜色,因此在创建ActionListener时,为什么不在模式JDialog(如JOptionPane)中显示颜色面板,并以此方式获取选择。例如...

  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 = 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;
对象消息=颜色;
String title =选择按钮颜色;
int optionType = JOptionPane.OK_CANCEL_OPTION;
int response = JOptionPane.showConfirmDialog(parent,message,title,optionType);
if(response == JOptionPane.OK_OPTION){
颜色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方法。


I am trying to make a three tab desktop app where tab1: add/del button for adding/deleting 0-20 JButtons with tab2: user selectable color (JColorChooser) and tab3 for showing the statistics such as count of buttons in tab1 and the latest color.My problem: with good hint I received here (thanks to Hovercraft Full of Eels!) I managed to add a PropertyChangeListener, and actually that color is now showable background for the panel - whereas I'd want to use it for new JButtons. Also same way it would be needed for Tab3... Better to show both the full Main and 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();
    }
}

And the latest version of Colors.java follows:

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;



    }
}

There are also comments (open questions) inline... to point out the problematic areas (for me that is!)

解决方案

Your problem in my view is less how to get color values but when to get them. Since you want the user to select a new color when a button is created, then in the creation ActionListener, why not display the color panel in a modal JDialog such as a JOptionPane and get the selection that way. For example...

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();
            }
        });
    }
}

As an aside, try to use more concise code for your examples posted here as that will make it easier for all to understand and help. Also, you almost never want to override the paint method but rather the paintComponent method.

这篇关于在两个视图之间传递Color对象以在JButton背景中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 22:43