【问题标题】:Can graphics.drawString change it properties outside paintComponent?graphics.drawString 可以在paintComponent 之外更改它的属性吗?
【发布时间】:2021-03-20 04:19:48
【问题描述】:

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

【问题讨论】:

    标签: java swing events fonts


    【解决方案1】:

    我对您的代码做了一些更改。

    1. 我通过调用 SwingUtilities invokeLater 方法启动了应用程序。此方法可确保在 Event Dispatch Thread 上创建和执行 Swing 组件。

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

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

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

    5. 我将绘图面板类和项目侦听器类设为公共内部类。

    这是完整的可运行代码。

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

    【讨论】:

      【解决方案2】:

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

      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()中。

      【讨论】:

        猜你喜欢
        • 2013-10-12
        • 1970-01-01
        • 1970-01-01
        • 2023-02-23
        • 2020-07-26
        • 1970-01-01
        • 2021-08-04
        • 1970-01-01
        • 2021-11-14
        相关资源
        最近更新 更多