2

我正在尝试制作一个简单的文字处理器,其中 JFrame 顶部有一个 ControlPanel,中间有一个带有 JTextArea 组件的 TextPanel。我的程序的基本概述是有一个名为 MyPanel 的 JPanel,它占据了整个 JFrame 并保存了其余的面板。MyPanel 内部是 ControlPanel 和 TextPanel(未嵌套)。ControlPanel 包含用于字体样式的各种 JButton 和 JComboBoxes,而 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);
        }
    }
4

1 回答 1

2

您的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

于 2013-04-06T08:04:42.057 回答