graphics.drawstring可以在paintcomponent之外更改它的属性吗?

p5cysglq  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(337)

我正在尝试根据两个复选框的状态更改字符串的样式。一个是 boldCheck 另一个是 italicCheck . 但是,当我运行程序时,它会在paintcomponent中绘制默认字符串,并且两个复选框不起作用?代码本身也存在实际问题,但问题似乎与我编写代码的方式相同。任何帮助解决这个问题将不胜感激。

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class JavaTest {
    public static void main(String[] args) {
        JFrame window = new JFrame("HomeWork");
        DrawMessage message = new DrawMessage();
        window.add(message);
        window.setVisible(true);
        window.setSize(600,300);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
    static class DrawMessage extends JPanel{
        private static final JCheckBox boldCheck = new JCheckBox("Bold");
        private static final JCheckBox italicCheck = new JCheckBox("Italic");

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 20));
            g.setColor(Color.blue);
            g.drawString("Welcome to java Programing", 40, 40);
            setBackground(Color.yellow);
            add(boldCheck);
            add(italicCheck);
            CheckBoxHandler handler = new CheckBoxHandler();
            boldCheck.addItemListener(handler);
            italicCheck.addItemListener(handler);
        }
        static private class CheckBoxHandler extends DrawMessage implements ItemListener{
            private int valBold = Font.PLAIN;
            private int valItalic = Font.PLAIN;

            @Override
            public void itemStateChanged(ItemEvent e) {
                if(e.getSource() == boldCheck){
                    valBold = boldCheck.isSelected() ? Font.BOLD: Font.PLAIN;
                }
                if(e.getSource() == italicCheck){
                    valItalic = italicCheck.isSelected() ? Font.ITALIC : Font.PLAIN;
                }
                DrawMessage obj = new DrawMessage();
                obj.setFont(new Font("TimesRoman", valBold + valItalic, 20));
            }
        }
    }
}
smdncfj3

smdncfj31#

我相信下面的代码实现了您的愿望。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class BoldItal extends JPanel implements ItemListener, Runnable {
    private JCheckBox  boldCheckBox;
    private JCheckBox  italicCheckBox;
    private JFrame  frame;

    public BoldItal() {
        setPreferredSize(new Dimension(600, 300));
        setBackground(Color.yellow);
    }

    @Override
    public void run() {
        showGui();
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        repaint();
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int style;
        if (boldCheckBox.isSelected()) {
            style = Font.BOLD;
            if (italicCheckBox.isSelected()) {
                style += Font.ITALIC;
            }
        }
        else {
            if (italicCheckBox.isSelected()) {
                style = Font.ITALIC;
            }
            else {
                style = Font.PLAIN;
            }
        }
        g.setFont(new Font("TimesRoman", style, 20));
        g.setColor(Color.blue);
        g.drawString("Welcome to java Programing", 40, 40);
    }

    private JPanel createCheckBoxes() {
        JPanel checkBoxesPanel = new JPanel();
        boldCheckBox = new JCheckBox("Bold");
        boldCheckBox.addItemListener(this);
        italicCheckBox = new JCheckBox("Italic");
        italicCheckBox.addItemListener(this);
        checkBoxesPanel.add(boldCheckBox);
        checkBoxesPanel.add(italicCheckBox);
        return checkBoxesPanel;
    }

    private void showGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(createCheckBoxes(), BorderLayout.PAGE_START);
        frame.add(this, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new BoldItal());
    }
}

您希望在更改其中一个复选框中的选择时重新绘制。因此您添加了一个 ItemListener 到每个复选框。那么,在方法上 paintComponent() 你设置了 Font 根据两个复选框的值设置样式。
你不改变背景颜色,因此不需要在方法中设置它 paintComponent() . 只需设置一次。我选择在类构造函数中设置它,但这不是必需的。它也可以设置,例如,在方法中 showGui() .

zengzsys

zengzsys2#

我对你的代码做了一些修改。
我在启动应用程序时,给
SwingUtilities invokeLater 方法。此方法确保在事件调度线程上创建和执行swing组件。
我创造了两个 JPanels ,一个用于复选框按钮,另一个用于绘制文本。通常,在图形上放置swing组件不是一个好主意 JPanel .
是我做的 valBold 以及 valItalic 字段是全局的,因为它们在控制器类中设置并在绘图面板类中使用。
绘图面板绘制文本。句号。控制器类将调整全局 Font 领域。
我使drawing panel类和item listener类成为公共内部类。
下面是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DrawStringGUI implements Runnable {

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

    private DrawMessage message;

    private JCheckBox boldCheck;
    private JCheckBox italicCheck;

    private int valBold = Font.PLAIN;
    private int valItalic = Font.PLAIN;

    @Override
    public void run() {
        JFrame window = new JFrame("HomeWork");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        window.add(createCheckBoxPanel(), BorderLayout.BEFORE_FIRST_LINE);
        message = new DrawMessage();
        window.add(message, BorderLayout.CENTER);

        window.pack();
        window.setVisible(true);
    }

    private JPanel createCheckBoxPanel() {
        JPanel panel = new JPanel();

        CheckBoxHandler handler = new CheckBoxHandler();

        boldCheck = new JCheckBox("Bold");
        boldCheck.addItemListener(handler);
        panel.add(boldCheck);

        italicCheck = new JCheckBox("Italic");
        italicCheck.addItemListener(handler);
        panel.add(italicCheck);

        return panel;
    }

    private void repaint() {
        message.repaint();
    }

    public class DrawMessage extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawMessage() {
            this.setBackground(Color.YELLOW);
            this.setPreferredSize(new Dimension(350, 100));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            int style = valBold | valItalic;

            g.setFont(new Font("TimesRoman", style, 20));
            g.setColor(Color.BLUE);
            g.drawString("Welcome to Java Programing", 40, 40);
        }

    }

    public class CheckBoxHandler implements ItemListener {

        @Override
        public void itemStateChanged(ItemEvent event) {
            if (event.getSource() == boldCheck) {
                valBold = boldCheck.isSelected() ? Font.BOLD : Font.PLAIN;
            }
            if (event.getSource() == italicCheck) {
                valItalic = italicCheck.isSelected() ? Font.ITALIC : Font.PLAIN;
            }

            DrawStringGUI.this.repaint();
        }
    }

}

相关问题