Может ли graphics.drawString изменить его свойства вне paintComponent?

#java #swing #events #fonts

#java #качать #Мероприятия #шрифты

Вопрос:

Я пытаюсь изменить стиль строки на основе состояния двух флажков. Один есть 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));
            }
        }
    }
}
 

Ответ №1:

Я считаю, что следующий код достигает того, чего вы хотите.

 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() .

Ответ №2:

Я внес несколько изменений в ваш код.

  1. Я запустил приложение с помощью вызова SwingUtilities invokeLater метода. Этот метод гарантирует, что компоненты Swing создаются и выполняются в потоке отправки событий.
  2. Я создал два JPanels , один для кнопок флажков и один для рисования текста. Как правило, не рекомендуется размещать компоненты Swing на чертеже JPanel .
  3. Я сделал поля valBold и valItalic глобальными, поскольку они установлены в классе контроллера и используются в классе панели рисования.
  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();
        }
    }
    
}