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