我正在尝试制作一个简单的文字处理器,其中在JFrame的顶部有一个ControlPanel,在中央有一个带有JTextArea组件的TextPanel。我的程序的基本概述是,有一个名为MyPanel的JPanel,它占据了整个JFrame,并容纳了其余面板。 MyPanel内部是ControlPanel和TextPanel(未嵌套)。 ControlPanel包含各种JButton和JComboBox,用于字体样式,而TextPanel仅具有JTextArea。

我想要的是,当我按下ControlPanel类中的JButton(例如BOLD)时,它将转到actionPerformed()并执行“ text.repaint”。但是我发现的是,text.repaint甚至都没有进入TextPanel,并且从不输入paintComponent方法。我试着将ControlPanel嵌套在TextPanel中,并给它提供BorderLayout.NORTH,效果很好,但随后看来纸张已连接到控制面板,这是我不喜欢的。

有人可以给我替代方法还是解释一下text.repaint()为什么不起作用?

这是我的代码中供参考的重要部分:(重要部分用//标记)

注意:ControlPanel类和TextPanel类未对齐,因为我太懒了,无法在平庸的文本编辑器上修复对齐方式。相信我,它们不是嵌套的,并且都在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);
        }
    }

最佳答案

您的paint方法没有为整个应用程序添加任何功能。实际上,最好允许控制面板将状态请求传递给TextPane,然后直接影响文本区域。

基本上,您在paintComponent方法中执行的操作是您尝试执行的方法的错误方法,并且实际上可能会产生可能会消耗您的CPU的循环重画调用方案

更新了示例

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

    }

}


我还建议您阅读How to Use Scroll PanesPerforming Custom PaintingPainting in AWT and Swing

07-24 20:44