applemavs
applemavs

Reputation: 503

Repaint() between different classes does not update

I'm trying to make a simple word processor where there is a ControlPanel on the top of the JFrame and a TextPanel in the center with a JTextArea component. A basic overview of my program is that there is one JPanel called MyPanel which takes up the entire JFrame and holds the rest of the panels. Inside MyPanel is ControlPanel and TextPanel (not nested). ControlPanel contains various JButtons and JComboBoxes for font styling while TextPanel simply has a JTextArea.

What I want is that when I press a JButton in the ControlPanel class, for example BOLD, it will go to actionPerformed() and do "text.repaint." But what I'm finding is that text.repaint does not even go to the TextPanel and never enters the paintComponent method. I tried nesting the ControlPanel in the TextPanel and giving it a BorderLayout.NORTH, and that works fine, but then it seems like the paper is connected to the control panel, which is something I don't like.

Can somebody give me an alternative or explain why text.repaint() is not working?

Here's the important portion of my code for reference: (important parts are marked with //)

NOTICE: class ControlPanel and class TextPanel aren't aligned because I was too lazy to fix the alignment on a mediocre text editor. Trust me, they are not nested and are both in the class MyPanel

        class ControlPanel extends JPanel implements ActionListener
        {
            JButton bold, italics;
            JComboBox font;
            JComboBox size;
            String [] fontsizes = {"8", "10", "12", "16", "20", "24", "36", "48", "56", "72"};
            String [] fonttypes = {"Arial", "Serif", "Sans Serif", "Gothic", "Helvetica", "Times New Roman", "Comic Sans"};

            public ControlPanel() // class ControlPanel control
            {
                setBackground(Color.gray);
                this.setLayout(new FlowLayout());

                Font boldfont = new Font("Serif", Font.BOLD, 16);
                bold = new JButton("B");
                bold.setFont(boldfont);
                //bold.getModel().setPressed(true);
                bold.addActionListener(this);
                this.add(bold);

                Font italicsfont = new Font("Serif", Font.ITALIC, 16);
                italics = new JButton("I");
                italics.setFont(italicsfont);
                //italics.getModel().setPressed(true);
                italics.addActionListener(this);
                this.add(italics);

                font = new JComboBox(fonttypes);
                font.setSelectedIndex(0);
                font.addActionListener(this);
                this.add(font);

                size = new JComboBox(fontsizes);
                size.setSelectedIndex(2);
                size.addActionListener(this);
                size.setEditable(true);
                this.add(size);

            }

            public void actionPerformed(ActionEvent e)
            {
                String command = e.getActionCommand();
                if (command.equals("B"))
                {
                    if (boldfont)
                        boldfont = false;
                    else
                        boldfont = true;
                }
                if (command.equals("I"))
                {
                    if (italicsfont)
                        italicsfont = false;
                    else 
                        italicsfont = true;
                }
                fontselection = (String)font.getSelectedItem();
                sizeselection = Integer.parseInt((String)(size.getSelectedItem()));
                text.repaint(); // repaints TextPanel text class
            }
        }

    class TextPanel extends JPanel // class TextPanel text
    {
        JTextArea type;

        public TextPanel()
        {
            this.setLayout(new BorderLayout());
            type = new JTextArea();
            type.setEditable(true);
            type.setLineWrap(true);
            type.setWrapStyleWord(true);
            type.setTabSize(4);
            type.setMargin(new Insets(80, 100, 80, 100));
            this.add(type, BorderLayout.CENTER);
        }


        public void paintComponent(Graphics g) // paintComponent() method for TextPanel
        {
            System.out.println("paintComponent of text"); // does not print out in terminal
            super.paintComponent(g);
            Font regfont;
            int fontstyle = 0;
            regfont = new Font("Arial", Font.PLAIN, 12);
            if (boldfont)
            {
                fontstyle = 1;
            }
            else if (!boldfont)
            {
                fontstyle = 0;
            }
            if (italicsfont)
            {
                if (boldfont)
                    fontstyle = 3;
                else
                    fontstyle = 2;
            }
            else if (!italicsfont)
            {
                if (boldfont)
                    fontstyle = 1;
                else
                    fontstyle = 0;
            }
            regfont = new Font(fontselection, fontstyle, sizeselection);
            type.setFont(regfont);
        }
    }

Upvotes: 2

Views: 143

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347204

Your paint method adds no functionality to the overall application. You'd actually be better off allowing the control pane to pass state request to the TextPane that then effect the text area directly.

Basically, what you're doing in the paintComponent method is the wrong approach for what it is you are trying to and could, in fact, produce a cyclic repaint call scenario that could consume your CPU

Updated with example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestTextPane01 {

    public static void main(String[] args) {
        new TestTextPane01();
    }

    public TestTextPane01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                TextPanel textPanel = new TextPanel();
                ControlPanel controlPanel = new ControlPanel(textPanel);

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(controlPanel, BorderLayout.NORTH);
                frame.add(textPanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }



    class ControlPanel extends JPanel implements ActionListener {

        JButton bold, italics;
        JComboBox font;
        JComboBox size;
        String[] fontsizes = {"8", "10", "12", "16", "20", "24", "36", "48", "56", "72"};
        String[] fonttypes = {"Arial", "Serif", "Sans Serif", "Gothic", "Helvetica", "Times New Roman", "Comic Sans"};
        private boolean boldfont;
        private boolean italicsfont;
        private String fontselection;
        private int sizeselection;
        private TextPanel textPane;

        public ControlPanel(TextPanel txtPanel) // class ControlPanel control
        {
            textPane = txtPanel;
            setBackground(Color.gray);
            this.setLayout(new FlowLayout());

            Font boldfont = new Font("Serif", Font.BOLD, 16);
            bold = new JButton("B");
            bold.setFont(boldfont);
            //bold.getModel().setPressed(true);
            bold.addActionListener(this);
            this.add(bold);

            Font italicsfont = new Font("Serif", Font.ITALIC, 16);
            italics = new JButton("I");
            italics.setFont(italicsfont);
            //italics.getModel().setPressed(true);
            italics.addActionListener(this);
            this.add(italics);

            font = new JComboBox(fonttypes);
            font.setSelectedIndex(0);
            font.addActionListener(this);
            this.add(font);

            size = new JComboBox(fontsizes);
            size.setSelectedIndex(2);
            size.addActionListener(this);
            size.setEditable(true);
            this.add(size);

        }

        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();
            if (command.equals("B")) {
                boldfont = !boldfont;
            } else if (command.equals("I")) {
                italicsfont = !italicsfont;
            }
            fontselection = (String) font.getSelectedItem();
            sizeselection = Integer.parseInt((String) (size.getSelectedItem()));
//            text.repaint(); // repaints TextPanel text class
            textPane.setFont(boldfont, italicsfont);
        }

    }

    class TextPanel extends JPanel // class TextPanel text
    {

        JTextArea type;

        public TextPanel() {
            this.setLayout(new BorderLayout());
            type = new JTextArea();
            type.setEditable(true);
            type.setLineWrap(true);
            type.setWrapStyleWord(true);
            type.setTabSize(4);
            type.setMargin(new Insets(80, 100, 80, 100));
            this.add(type, BorderLayout.CENTER);
        }

        public void setFont(boolean boldFont, boolean italicsFont) {
            Font font = type.getFont();
            int style = Font.PLAIN;
            if (boldFont && italicsFont) {
                style = Font.BOLD | Font.ITALIC;
            } else if (boldFont) {
                style = Font.BOLD;
            } else if (italicsFont) {
                style = Font.ITALIC;
            }
            font = font.deriveFont(style);
            System.out.println("Font");
            type.setFont(font);
        }

    }

}

I'd also suggest you have a read of How to Use Scroll Panes, Performing Custom Painting and Painting in AWT and Swing

Upvotes: 2

Related Questions