java - 不同类之间的Repaint()不更新

标签 java swing actionlistener repaint paintcomponent

我正在尝试制作一个简单的文字处理程序,其中 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方法没有为整个应用程序添加任何功能。实际上,您最好允许控制 Pane 将状态请求传递给 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 Panes , Performing Custom PaintingPainting in AWT and Swing

关于java - 不同类之间的Repaint()不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15848242/

相关文章:

带有 Eclipse 的 Java - 丢失的设计页面

java - 一个事件有两个监听器?

java - 如何使用 Action 监听器从按钮获取背景颜色

java - 图像未显示在 JFrame 中

java - 如何为 JFrame 上的所有 JPanel 设置 Visible

java - 创建一个新框架并使用 SpringUtilities 使用 SpringLayout 对其进行装饰

Java:使用条件创建内部联接

java - 在 json schema 中使用 ref 到 pojo 时出错

java - 在 Java 中从键值对构建映射

java - 当我尝试在另一台计算机上运行 Java 类时出错?