Java - 更改需要同时出现在多个窗口中的非静态JTextArea的背景颜色

时间:2016-05-23 19:17:37

标签: java swing jtextarea

如果我有一个静态JTextArea对象,我可以使用name.setBackground(Color c);更改其颜色。但是,如果JTextArea对象不是静态的,我就不能使用name.setText(String s)name.setBackground(Color c);等方法。

我需要对象是非静态的,因为我需要在多个窗口中同时运行它们的多个实例。

1 个答案:

答案 0 :(得分:3)

您无法显示Swing组件的多个实例,一次只能显示一个。您可以使用相同的Document具有多个JTextAreas,因此它们将显示相同的文本,但这不会更改背景颜色。

我建议你创建一个ArrayList<JTextArea>字段以及一个允许其他对象更改所有字段背景颜色的公共方法。将颜色传递给方法的参数,并在方法循环内部通过JTextAreas列表,更改循环内的背景颜色。

注意:您声明您需要&#34;对象是非静态的...&#34; - 请注意,对象既不是静态的也不是非静态的。另一方面,变量可以是一个或另一个,我建议你避免使用静态字段和使用公共字段,因为这有助于降低代码的复杂性,从而有助于减少错误的可能性。

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.text.PlainDocument;

@SuppressWarnings("serial")
public class MultTextAreasMain extends JPanel {
    private static final int DIALOG_COUNT = 4; //  how many dialogs?

    // Single Document shared by all JTextAreas -- thus they share text
    private PlainDocument document = new PlainDocument();
    private List<JTextArea> textAreas = new ArrayList<>(); // list of all text areas
    private MultTextAreaPanel panel1 = new MultTextAreaPanel(this);

    public MultTextAreasMain() {
        textAreas.add(panel1.getTextArea());
        setLayout(new BorderLayout());
        add(panel1);
    }

    public PlainDocument getDocument() {
        return document;
    }

    // public method to allow addition of text areas to the array list
    public void addTextArea(JTextArea textArea) {
        textAreas.add(textArea);
    }

    // sets the background color all text areas held by the array list
    public void setTextAreaBackground(Color value) {
        for (JTextArea jTextArea : textAreas) {
            jTextArea.setBackground(value);
        }
    }

    private static void createAndShowGui() {
        MultTextAreasMain main = new MultTextAreasMain();

        JFrame frame = new JFrame("MultTextAreas");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(main);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        for (int i = 0; i < DIALOG_COUNT; i++) {
            MultTextAreaPanel mtaPanel = new MultTextAreaPanel(main);
            main.addTextArea(mtaPanel.getTextArea());
            String title = "Dialog " + (i + 1);
            JDialog dialog = new JDialog(frame, title, ModalityType.MODELESS);
            dialog.add(mtaPanel);
            dialog.pack();
            dialog.setLocationByPlatform(true);
            dialog.setVisible(true);
        }
    }

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

@SuppressWarnings("serial")
class MultTextAreaPanel extends JPanel {
    public static final int GRAY = 150;
    public static final Color[] COLORS = { 
            new Color(255, GRAY, GRAY), 
            new Color(GRAY, 255, GRAY),
            new Color(GRAY, GRAY, 255), 
            new Color(255, 255, GRAY), 
            new Color(255, GRAY, 255),
            new Color(GRAY, 255, 255) };
    private JTextArea textArea = new JTextArea(10, 30);
    private MultTextAreasMain main;
    JComboBox<Color> colorsCombo = new JComboBox<>(COLORS);

    public MultTextAreaPanel(MultTextAreasMain main) {
        this.main = main;
        PlainDocument doc = main.getDocument();
        textArea.setDocument(doc);
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);
        colorsCombo.setRenderer(new ColorListCellRenderer());
        colorsCombo.addActionListener(new ColorsListener());

        JPanel comboPanel = new JPanel();
        comboPanel.add(colorsCombo);

        setLayout(new BorderLayout());
        add(new JScrollPane(textArea));
        add(comboPanel, BorderLayout.PAGE_END);
    }

    public JTextArea getTextArea() {
        return textArea;
    }

    // combo box listener that gets the selected color from the combo box
    // and then calls the main class's method to change the background
    // color of all the JTextAreas held by the ArrayList
    private class ColorsListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            Color value = (Color) colorsCombo.getSelectedItem();
            if (value != null) {
                main.setTextAreaBackground(value);
            }
        }
    }

    // a renderer for the JComboBox. This displays the RGB constants for colors along with 
    // showing each item's background color. A selected item is darker. 
    private class ColorListCellRenderer extends DefaultListCellRenderer {
        private final int darker = 20;

        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            DefaultListCellRenderer renderer = (DefaultListCellRenderer) super.getListCellRendererComponent(list, value,
                    index, isSelected, cellHasFocus);
            renderer.setOpaque(true);
            Color color = (Color) value;
            String text = String.format("Color [%d, %d, %d]", color.getRed(), color.getGreen(), color.getBlue());
            renderer.setText(text);
            if (isSelected) {
                int r = color.getRed() == 255 ? 255 : darker;
                int g = color.getGreen() == 255 ? 255 : darker;
                int b = color.getBlue() == 255 ? 255 : darker;
                color = new Color(r, g, b);
            }
            renderer.setBackground(color);
            return renderer;
        }
    }
}