graphics.drawString 可以在 paintComponent 之外更改它的属性吗?

Can graphics.drawString change it properties outside paintComponent?

我正在尝试根据两个复选框的状态更改字符串的样式。一个是 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));
            }
        }
    }
}

我相信下面的代码可以实现你想要的。

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() 中进行设置。只需设置一次。我选择在 class 构造函数中设置它,但这不是强制性的。也可以设置,例如在方法 showGui().

我对你的代码做了一些修改。

  1. 我通过调用 SwingUtilities invokeLater 方法启动了应用程序。此方法确保在 Event Dispatch Thread.

    上创建和执行 Swing comp[onents]
  2. 我创建了两个 JPanels,一个用于复选框按钮,一个用于绘制文本。一般来说,把 Swing 组件放在绘图上并不是一个好主意 JPanel.

  3. 我将 valBoldvalItalic 字段设置为全局字段,因为它们在控制器 class 中设置并在绘图面板中使用 class .

  4. 绘图面板绘制文本。时期。控制器 class 将调整全局 Font 字段。

  5. 我在 classes.class 内制作了绘图面板 class 和项目监听器 class public

这是完整的可运行代码。

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