使用另一个jFrame

时间:2017-07-06 20:22:57

标签: java swing jpanel background-color

所以我正在开发一个软件,我已经达到了一个特殊的地方,在设置窗口(与主要的jFrame分开),我应该能够使用ComboBox(称为Color_cb1)更改两个不同面板的颜色。 我使用了一个switch语句来获取所选索引并改变另一种形式的颜色,如下所示:[整个代码的屏幕截图在这里给出 - >截图:

enter image description here

但它似乎没有改变任何东西!有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

我看到你的问题,就在这里:

Chatroom c = new Chatroom(); 

然后调用方法尝试更改此对象的状态c.xxx.someMethod();并且您的方法实际上工作,它们确实会更改c的状态,但请理解您更改错误的对象。您的聊天室对象c与实际显示的聊天室不同,更改c的状态对显示的对象没有神奇的影响。想象一下,想象一下你的妻子有车,它需要汽油。您的上述解决方案类似于您购买完全相同的品牌,型号和年份的新车,然后填充气体,并期望现在您的妻子的汽车有汽油。不行。相反,你需要抓住你妻子的车,用气体填充,现在情况很好。

一种可能的解决方案是创建状态字段static,这是一个糟糕的解决方案,因为它会导致类失去OOP优势,使调试变得更加困难,增加潜在的复杂性并增加风险错误。

更好的解决方案是将引用传递给可视化的Chatroom对象到此类中,并在其上调用您的方法。通过构造函数或setter参数传递引用,您就可以使用它了。

对于显示使用JDialog以及通过构造函数参数将一个对象的引用传递给另一个对象的MCVE的示例,请注意下面的程序。在这个程序中,我有两个JPanels,一个MainPanel和一个DialogPanel,一个是应用程序的主要JPanel,另一个是JDialog持有的JPanel,当我创建JDialog时,我将主面板传递到如下:

class MainPanel extends JPanel {
    // ....

    // create the dialog, passing the main panel into it:
    private DialogPanel dialogPanel = new DialogPanel(this);

然后在DialogPanel的构造函数中,我设置了一个带参数的字段:

@SuppressWarnings("serial")
class DialogPanel extends JPanel {
    private MainPanel mainPanel;
    // ....

    public DialogPanel(MainPanel mainPanel) {
        this.mainPanel = mainPanel;

然后在对话框面板所持有的ActionListener中使用此mainPanel字段:

public void actionPerformed(ActionEvent e) {
    ColorPair colorPair = (ColorPair) colorCombo.getSelectedItem();
    mainPanel.setCenterBackground(colorPair.getColor());
    mainPanel.setSideBackground(colorPair.getDarkColor());
}

此外,由于您正在使用Color对,我创建了一个名为ColorPair的枚举,它将两种颜色与一个字符串绑定在一起:

public enum ColorPair {
    BLUE("Blue", new Color(52, 73, 94), new Color(44, 62, 80)), 
    GREEN("Green", new Color(46, 204, 113), new Color(39, 174, 96)), 
    TURQ("Turquoise", new Color(26, 188, 156), new Color(22, 160, 133)), 
    GREY("Grey", new Color(149, 165, 166), new Color(127, 140, 141));

    private ColorPair(String text, Color color1, Color color2) {
        this.text = text;
        this.color = color1;
        this.darkColor = color2;
    }

    private String text;
    private Color color;
    private Color darkColor;

    public String getText() {
        return text;
    }
    public Color getColor() {
        return color;
    }
    public Color getDarkColor() {
        return darkColor;
    }
}

为什么这样?好吧,它有助于我们创建一个漂亮的效果,我们渲染两种颜色加上JComboBox中的文本,让我们通过使用自定义ListCellRenderer类选择颜色:

public class ColorPairRenderer implements ListCellRenderer<ColorPair> {
    private static final int IMG_W = 100;
    private static final int IMG_H = 20;
    private JLabel label = new JLabel();
    private Map<ColorPair, Icon> iconMap = new EnumMap<>(ColorPair.class);

    public ColorPairRenderer() {
        label.setOpaque(true);
        label.setHorizontalTextPosition(SwingConstants.TRAILING);
        label.setVerticalTextPosition(SwingConstants.CENTER);
        for (ColorPair colorPair : ColorPair.values()) {
            BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
            Graphics g = img.getGraphics();
            int x = 0;
            int y = 0;
            int width = IMG_W / 2;
            int height = IMG_H;
            g.setColor(colorPair.getColor());
            g.fillRect(x, y, width, height);

            x = width;
            g.setColor(colorPair.getDarkColor());
            g.fillRect(x, y, width, height);

            x = 0;
            width = IMG_W;
            g.setColor(Color.BLACK);
            g.drawRect(x, y, width, height);
            g.dispose();
            Icon icon = new ImageIcon(img);
            iconMap.put(colorPair, icon);
        }
    }

    @Override
    public Component getListCellRendererComponent(JList<? extends ColorPair> list, ColorPair value, int index,
            boolean isSelected, boolean cellHasFocus) {
        if (value != null) {
            label.setText(value.getText());
            label.setIcon(iconMap.get(value));
        } else {
            label.setText("");
            label.setIcon(null);
        }
        return label;
    }
}

要查看整个操作,请将下面的代码复制并粘贴到IDE中的名为ChangeColor.java的类文件中,然后运行它(更新后显示添加新颜色是多么容易 - 一行代码) :

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;

public class ChangeColor {
    private static void createAndShowGui() {
        MainPanel mainPanel = new MainPanel();

        JFrame frame = new JFrame("Change Color");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class MainPanel extends JPanel {
    private JPanel centerPanel = new JPanel();
    private JPanel sidePanel = new JPanel();

    // create the dialog, passing the main panel into it:
    private DialogPanel dialogPanel = new DialogPanel(this);
    private JDialog dialog;

    public MainPanel() {
        centerPanel.setPreferredSize(new Dimension(400, 400));
        sidePanel.setPreferredSize(new Dimension(100, 400));
        setLayout(new BorderLayout());
        add(centerPanel, BorderLayout.CENTER);
        add(sidePanel, BorderLayout.LINE_END);

        centerPanel.add(new JButton(new ShowColorDialogAction("Change Colors")));
    }

    public void setCenterBackground(Color c) {
        centerPanel.setBackground(c);
    }

    public void setSideBackground(Color c) {
        sidePanel.setBackground(c);
    }

    private class ShowColorDialogAction extends AbstractAction {
        public ShowColorDialogAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (dialog == null) {                
                Window frame = SwingUtilities.getWindowAncestor(MainPanel.this);
                dialog = new JDialog(frame, "Color Setter", ModalityType.MODELESS);
                dialog.getContentPane().add(dialogPanel);
                dialog.pack();
                dialog.setLocationByPlatform(true);
            }
            dialog.setVisible(true);
        }
    }
}

@SuppressWarnings("serial")
class DialogPanel extends JPanel {
    private MainPanel mainPanel;
    private JComboBox<ColorPair> colorCombo = new JComboBox<>(ColorPair.values());

    public DialogPanel(MainPanel mainPanel) {
        this.mainPanel = mainPanel;
        colorCombo.setSelectedIndex(-1);
        colorCombo.setRenderer(new ColorPairRenderer());
        colorCombo.addActionListener(new ColorComboListener());
        add(colorCombo);
    }

    private class ColorComboListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            ColorPair colorPair = (ColorPair) colorCombo.getSelectedItem();
            mainPanel.setCenterBackground(colorPair.getColor());
            mainPanel.setSideBackground(colorPair.getDarkColor());
        }
    }
}

class ColorPairRenderer implements ListCellRenderer<ColorPair> {
    private static final int IMG_W = 100;
    private static final int IMG_H = 20;
    private JLabel label = new JLabel();
    private Map<ColorPair, Icon> iconMap = new EnumMap<>(ColorPair.class);

    public ColorPairRenderer() {
        label.setOpaque(true);
        label.setHorizontalTextPosition(SwingConstants.TRAILING);
        label.setVerticalTextPosition(SwingConstants.CENTER);
        for (ColorPair colorPair : ColorPair.values()) {
            BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
            Graphics g = img.getGraphics();
            int x = 0;
            int y = 0;
            int width = IMG_W / 2;
            int height = IMG_H;
            g.setColor(colorPair.getColor());
            g.fillRect(x, y, width, height);

            x = width;
            g.setColor(colorPair.getDarkColor());
            g.fillRect(x, y, width, height);

            x = 0;
            width = IMG_W;
            g.setColor(Color.BLACK);
            g.drawRect(x, y, width, height);
            g.dispose();
            Icon icon = new ImageIcon(img);
            iconMap.put(colorPair, icon);
        }
    }

    @Override
    public Component getListCellRendererComponent(JList<? extends ColorPair> list, ColorPair value, int index,
            boolean isSelected, boolean cellHasFocus) {
        if (value != null) {
            label.setText(value.getText());
            label.setIcon(iconMap.get(value));
        } else {
            label.setText("");
            label.setIcon(null);
        }

        if (isSelected) {
            label.setBackground(Color.LIGHT_GRAY);
        } else {
            label.setBackground(null);
        }
        return label;
    }
}

enum ColorPair {
    BLUE("Blue", new Color(52, 73, 94), new Color(44, 62, 80)), 
    GREEN("Green", new Color(46, 204, 113), new Color(39, 174, 96)),
    TURQ("Turquoise", new Color(26, 188, 156), new Color(22, 160, 133)), 
    RED("Red", new Color(204, 46, 113), new Color(174, 39, 96)),
    YELLOW("Yellow", new Color(204, 204, 46), new Color(174, 174, 39)),
    Violet("Violet", new Color(204, 46, 204), new Color(174, 39, 174)),
    GREY("Grey", new Color(149, 165, 166), new Color(127, 140, 141));

    private ColorPair(String text, Color color1, Color color2) {
        this.text = text;
        this.color = color1;
        this.darkColor = color2;
    }

    private String text;
    private Color color;
    private Color darkColor;

    public String getText() {
        return text;
    }
    public Color getColor() {
        return color;
    }
    public Color getDarkColor() {
        return darkColor;
    }
}