Reputation: 15
I'm trying to change the style of the string based on the status of two check boxes. One is boldCheck
and the other is italicCheck
. However when I run the program it draws the default string in the paintComponent and the two checkboxes are not working? and there is actual problems in the code itself but the problem seems the way I made this code. Any help on fixing this issue will be much appreciated.
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));
}
}
}
}
Upvotes: 0
Views: 112
Reputation: 51559
I made a few changes to your code.
I started the application with a call to the SwingUtilities
invokeLater
method. This method ensures that the Swing comp[onents are created and executed on the Event Dispatch Thread.
I created two JPanels
, one for the checkbox buttons and one to draw the text. Generally, it's not a good idea to put Swing components on a drawing JPanel
.
I made the valBold
and valItalic
fields global since they're set in the controller class and used in the drawing panel class.
The drawing panel draws the text. Period. The controller class will adjust the global Font
fields.
I made the drawing panel class and the item listener class public inner classes.
Here's the complete runnable code.
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();
}
}
}
Upvotes: 1
Reputation: 20913
I believe the following code achieves what you desire.
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());
}
}
You want a repaint to occur whenever you change the selection in one of the check boxes. Hence you add an ItemListener
to each check box. Then, in method paintComponent()
you set the Font
style according to the values of the two check boxes.
You don't change the background color, hence no need to set it in method paintComponent()
. Just set it once. I chose to set it in the class constructor, but that is not mandatory. It can also be set, for example, in method showGui()
.
Upvotes: 2